pkg-plugin

Webpack Plugin For the Newer NodeJS v22.9.0 Single Executable Bundling Process Provided By Johnathan Edward Brown! Now includes a Simple Runtime Script Integrity Check! Using SEA assets! With a Binary Tamper Proof Included!


Keywords
Webpack, Plugin, Executable, Tamper Proof, Bundler, SEA, Assets
License
X11
Install
npm install pkg-plugin@2.0.2

Documentation

NodePkgPlugin

NodePkgPlugin is a Webpack and Rollup plugin that generates single executable applications for multiple platforms (Linux, macOS, Windows) by leveraging Node.js SEA (Single Executable Applications) feature.

  • Warning all versions below 2.0.0 are broken btw please update to 2.0.1 for the proper fully working dual npm module pkg plugin
  • Warning: The Final output binaries will include -hash.txt files if you plan to rename them you must rename the -hash.txt files if not the binaries won't work!
  • Which the final output binary name is configurable see further below for more information on this!
  • Fully working Bundling of tamperproof for Rollup and Webpack as of version 2.0.1 and Fully working dual NPM module plugin for Webpack and Rollup
  • Please properly follow tutorials and instructions for tamper bundling due to the nature of bundling automatically poses issues when combined into a single npm module like we have here for public release usage

Installation

To install the plugin, you need to add it to your project dependencies:

npm install --save-dev pkg-plugin

Usage

Webpack

To use the NodePkgPlugin in your Webpack configuration, follow these steps:

  1. Create a Webpack Configuration File

Create a webpack.config.js file in the root of your project if you don't already have one.

const path = require('path');
const { WebpackPkgPlugin } = require('pkg-plugin');

module.exports = {
   entry: [
    //Include the following entries in your webpack config!
    './node_modules/pkg-plugin/tamperTs/tamper.js', //Don't need to include both but if you choose so you can they do both work perfectly fine with each other if you have a binary that is SEA the tamper.ts properly and tamper.js correleate with the tamperBinary.ts and tamperBinary.js 
    //Only use tamperBinary for Binarys not for NPM modules all though it can work but not recommended!! 
    './node_modules/pkg-plugin/tamperTs/tamperBinary.js',
    './src/index.js' //Your file here include above before it!
    ],
   output: {
      filename: 'app.js',
      path: path.resolve(__dirname, 'dist')
   },
   plugins: [
      new WebpackPkgPlugin('app.js', 'app-', false)//true if using typescript else don't add last parameter defaults to false for CommonJS javascript!
   ]
};
  1. Set Up Your Project Structure

Ensure your project has the following structure:

your-project/
├── src/
│   └── index.js
├── dist/
├── webpack.config.js
└── package.json
  1. Build Your Project

Run the Webpack build command to generate the single executable applications:

npx webpack --config webpack.config.js

This will create the executables for Linux, macOS, and Windows in the dist directory.

Rollup

To use the NodePkgPlugin in your Rollup configuration, follow these steps:

  1. Create a Rollup Configuration File

Create a rollup.config.js file in the root of your project if you don't already have one.

import RollupPkgPlugin from 'pkg-plugin';

const rollupPkgPlugin = new RollupPkgPlugin('pheonix-box-cli.js', 'pheonix-box-cli-', false, 'production');
// Define the entry files
const entryFiles = [
  './node_modules/pkg-plugin/tamperScripts/tamper.js',
  './node_modules/pkg-plugin/tamperScripts/tamperBinary.js',
  './src/index.js'
];

// Generate the entry file
const entryFilePath = './entry.js';
rollupPkgPlugin.generateEntryFile(entryFilePath, entryFiles);
//The final option parameter allows specifying the binarys to output to a different directory then your npm javascript file thats being bundled!
//Also tamper proofs your javascript file as well! Enjoy! :D

export default {
  input: [ entryFilePath, ],
  output: {
    dir: 'dist',
    format: 'cjs',
    entryFileName: 'app.js'
  },
  plugins: [
    {
      name: 'rollup-pkg-plugin',
      buildStart: rollupPkgPlugin.buildStart.bind(rollupPkgPlugin),
      generateBundle: rollupPkgPlugin.generateBundle.bind(rollupPkgPlugin),
    }
  ]
};
  1. Set Up Your Project Structure

Ensure your project has the following structure:

your-project/
├── src/
│   └── index.js
├── dist/
├── rollup.config.js
└── package.json
  1. Build Your Project

Run the Rollup build command to generate the single executable applications:

npx rollup -c rollup.config.js

This will create the executables for Linux, macOS, and Windows in the dist directory.

Configuration

The plugin allows you to specify the input filename and the output filename prefix through its constructor. By default, it uses app.js as the input filename and app- as the output filename prefix. You can customize these values as shown in the example above.

External Node Modules

If your project uses external Node modules, ensure your Webpack or Rollup configuration properly caches all modules. Failing to do so may result in a non-functional binary. For more details, refer to the Node.js Single Executable Applications documentation, also you can refer to the Webpack documentation on caching.

For Rollup, you can refer to the following documentation and guides for caching:

For caching node modules in Webpack, you can use the cache option in your Webpack configuration file like this:

module.exports = {
  // other configurations...
  cache: {
    type: 'filesystem', // Enables filesystem caching
    buildDependencies: {
      config: [__filename], // Add your config as a build dependency
    },
  },
};

This will cache the node modules and other build dependencies to speed up subsequent builds. For more detailed information, refer to the Webpack caching guide linked above.

Here are a few ways to cache node modules with Rollup:

1. Using the rollup-plugin-cache plugin:

This plugin is specifically designed to cache node modules. It can be installed using npm or yarn:

npm install rollup-plugin-cache
yarn add rollup-plugin-cache

Then, add it to your Rollup configuration:

import rollupPluginCache from 'rollup-plugin-cache';

export default {
  plugins: [
    rollupPluginCache({
      // Cache directory
      cacheDir: '.rollupCache',
      // Cache key generator
      cacheKey: (id) => id,
    }),
    // Other plugins
  ],
};

2. Using the rollup-plugin-commonjs plugin:

If you're using the rollup-plugin-commonjs plugin to transpile CommonJS modules, you can enable caching by setting the cache option to true:

import commonjs from '@rollup/plugin-commonjs';

export default {
  plugins: [
    commonjs({
      cache: true,
    }),
    // Other plugins
  ],
};

3. Using the rollup-plugin-node-resolve plugin:

If you're using the rollup-plugin-node-resolve plugin to resolve node modules, you can enable caching by setting the cache option to true:

import resolve from '@rollup/plugin-node-resolve';

export default {
  plugins: [
    resolve({
      cache: true,
    }),
    // Other plugins
  ],
};

New Features

TypeScript Support

The plugin now supports TypeScript projects. You can enable TypeScript support by passing true as the third parameter to the NodePkgPlugin constructor.

Integrity Checks

The plugin includes built-in integrity checks for both the source code and the binary. This ensures that the generated executables have not been tampered with.

  • Source Integrity Check: Verifies the integrity of the JavaScript source code.
  • Binary Integrity Check: Verifies the integrity of the binary executable.

Example

Here is an example of a simple Webpack project setup:

  1. Initialize a New Node.js Project
mkdir my-webpack-project
cd my-webpack-project
npm init -y
  1. Install Webpack and the Plugin
npm install --save-dev webpack webpack-cli pkg-plugin
  1. Create the Project Files

Create the following files and directories:

  • src/index.js:

    console.log('Hello, World!');
  • webpack.config.js:

    const path = require('path');
    const WebpackPkgPlugin = require('pkg-plugin');
    
    module.exports = {
      entry: './src/index.js',
      output: {
         filename: 'app.js',
         path: path.resolve(__dirname, 'dist')
      },
      plugins: [
         new WebpackPkgPlugin('app.js', 'app-', true)//true if using typescript else don't add last parameter defaults to false for CommonJS javascript!
      ]
    };
  1. Build the Project
npx webpack --config webpack.config.js

The dist directory will contain the executables for Linux, macOS, and Windows.

License

This project is licensed under the X11 License. See the LICENSE file for details.

Contributing

Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.

Contact

For any questions or inquiries, please contact Johnathan Edward Brown at sierrajohn1234brown@gmail.com.

References

Credits

  • Githubs Copilot for generated code snippets for webpack examples and project setup included in this README.md
  • Author: Johnathan Edward Brown