npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bytenode

v1.5.6

Published

A minimalist bytecode compiler for Node.js

Downloads

26,231

Readme

Bytenode

A minimalist bytecode compiler for Node.js.

This tool truly compiles your JavaScript code into V8 bytecode, so that you can protect your source code. It can be used with Node.js, as well as Electron and NW.js (check examples/ directory).


Install

npm install --save bytenode

Or globally:

sudo npm install -g bytenode

Known Issues and Limitations

  • In Node 10.x, Bytenode does not work in debug mode. See #29.

  • Any code depends on Function.prototype.toString function will break, because Bytenode removes the source code from .jsc files and puts a dummy code instead. See #34. For a workaround, see #163

  • Async Arrow Functions (and Arrow Functions in general) cause crashes in Puppeteer and in Electron apps. See #106, #47. They also cause issues with the ndb debugger. See #135. It seems that whenever there is a context change (or even when called from another file or module), arrow functions break because V8 inspects them internally using Function.prototype.toString in these cases. See #157.


Resources


Bytenode CLI

  Usage: bytenode [option] [ FILE... | - ] [arguments]

  Options:
    -h, --help                        show help information.
    -v, --version                     show bytenode version.

    -c, --compile [ FILE... | - ]     compile stdin, a file, or a list of files
    --compress                        compress bytecode
    -n, --no-module                   compile without producing commonjs module
    -e, --electron                    compile for Electron
    -ep, --electron-path              path to Electron executable

    -l, --loader [ FILE | PATTERN ]   create a loader file and optionally define
                                      loader filename or pattern using % as
                                      filename replacer
                                      defaults to %.loader.js
    --no-loader                       do not create a loader file, conflicts
                                      with -l
    -t, --loader-type type            create a loader file of type commonjs or
                                      module. Defaults to CommonJS

  Examples:

  $ bytenode -c script.js             compile `script.js` to `script.jsc`.
  $ bytenode -c server.js app.js
  $ bytenode -c src/*.js              compile all `.js` files in `src/` directory.

  $ bytenode -c *.js -l %.load.js     create `filename.load.js` loader files along side `.jsc` files

  $ bytenode script.jsc [arguments]   run `script.jsc` with arguments.
  $ bytenode                          open Node REPL with bytenode pre-loaded.

Examples:

  • Compile express-server.js to express-server.jsc.
user@machine:~$ bytenode --compile express-server.js
  • Run your compiled file express-server.jsc.
user@machine:~$ bytenode express-server.jsc
Server listening on port 3000
  • Compile all .js files in ./app directory.
user@machine:~$ bytenode --compile ./app/*.js
  • Compile all .js files in your project.
user@machine:~$ bytenode --compile ./**/*.js

Note: you may need to enable globstar option in bash (you should add it to ~/.bashrc): shopt -s globstar

  • Starting from v1.0.0, bytenode can compile from stdin.
echo 'console.log("Hello");' | bytenode --compile - > hello.jsc

Bytenode API

const bytenode = require('bytenode');

bytenode.compileCode(javascriptCode) → {Buffer}

Generates v8 bytecode buffer.

  • Parameters:

| Name | Type | Description | | ---- | ---- | ----------- | | javascriptCode | string | JavaScript source that will be compiled to bytecode. |

  • Returns:

{Buffer} The generated bytecode.

  • Example:
let helloWorldBytecode = bytenode.compileCode(
  `console.log('Hello World!');
  43;  // this will be returned`
);

This helloWorldBytecode bytecode can be saved to a file. However, if you want to use your code as a module (i.e. if your file has some exports), you have to compile it using bytenode.compileFile({compileAsModule: true}), or wrap your code manually, using Module.wrap() function.


bytenode.compileElectronCode(javascriptCode, options) → {Promise<Buffer>}

Asynchronous function which generates v8 bytecode buffer for Electron.

Same as bytenode.compileCode(), but generates bytecode for the version of Electron currently installed in node_modules.

  • Parameters:

| Name | Type | Description | | ---- | ---- | ----------- | | javascriptCode | string | JavaScript source that will be compiled to bytecode. | | options | object | Options object. | | options.electronPath | string | Path to Electron executable. |

  • Returns:

{Promise<Buffer>} A Promise which resolves with the generated bytecode.

  • Example:
let helloWorldBytecode = await bytenode.compileElectronCode(
  `console.log('Hello World!');
  43;  // this will be returned`
);

This helloWorldBytecode bytecode can be saved to a file. However, if you want to use your code as a module (i.e. if your file has some exports), you have to compile it using bytenode.compileFile({compileAsModule: true}), or wrap your code manually, using Module.wrap() function.


bytenode.runBytecode(bytecodeBuffer) → {any}

Runs v8 bytecode buffer and returns the result.

  • Parameters:

| Name | Type | Description | | ---- | ---- | ----------- | | bytecodeBuffer | Buffer | The buffer object that was created using compileCode function. |

  • Returns:

{any} The result of the very last statement executed in the script.

  • Example:
const result = bytenode.runBytecode(helloWorldBytecode);
// prints: Hello World!
console.log(result)
// prints: 43

bytenode.compileFile(args, output) → {Promise<string>}

Asynchronous function which compiles JavaScript file to .jsc file.

  • Parameters:

Name | Type | Description ---- | ---- | ----------- args | object | string args.filename | string | The JavaScript source file that will be compiled. args.compileAsModule | boolean | If true, the output will be a commonjs module. Default: true. args.electron | boolean | If true, the output will be a compiled through Electron. Default: false. args.electronPath | string | Path to Electron executable. Default: Electron binary from node_modules. args.output | string | The output filename. Defaults to the same path and name of the original file, but with .jsc extension. args.createLoader | boolean | string | If true, create a CommonJS loader file. As a string, select between module or commonjs loader. Default: false args.loaderFilename | string | Filename or pattern for generated loader files. Defaults to originalFilename.loader.js. Use % as a substitute for originalFilename. output | string | The output filename. (Deprecated: use args.output instead)

  • Returns:

{Promise<string>}: A Promise that resolves as the compiled filename.

  • Examples:
let compiledFilename = bytenode.compileFile({
  filename: '/path/to/your/file.js',
  output: '/path/to/compiled/file.jsc' // if omitted, it defaults to '/path/to/your/file.jsc'
});

Previous code will produce a commonjs module that can be required using require function.

let compiledFilename = await bytenode.compileFile({
  filename: '/path/to/your/file.js',
  output: '/path/to/compiled/file.jsc',
  compileAsModule: false
});

Previous code will produce a direct .jsc file, that can be run using bytenode.runBytecodeFile() function. It can NOT be required as a module. Please note that compileAsModule MUST be false in order to turn it off. Any other values (including: null, "", etc) will be treated as true. (It had to be done this way in order to keep the old code valid.)


bytenode.runBytecodeFile(filename) → {any}

Runs .jsc file and returns the result.

  • Parameters:

| Name | Type | | ---- | ---- | | filename | string |

  • Returns:

{any} The result of the very last statement executed in the script.

  • Example:
// test.js
console.log('Hello World!');
43;  // this will be returned
const result = bytenode.runBytecodeFile('/path/to/test.jsc');
// prints: Hello World!
console.log(result)
// prints: 43

require(filename) → {any}

  • Parameters:

| Name | Type | | ---- | ---- | | filename | string |

  • Returns:

{any} exported module content

  • Example:
let myModule = require('/path/to/your/file.jsc');

Just like regular .js modules. You can also omit the extension .jsc.

.jsc file must have been compiled using bytenode.compileFile(), or have been wrapped inside Module.wrap() function. Otherwise it won't work as a module and it can NOT be required.

Please note .jsc files must run with the same Node.js version that was used to compile it (using same architecture of course). Also, .jsc files are CPU-agnostic. However, you should run your tests before and after deployment, because V8 sanity checks include some checks related to CPU supported features, so this may cause errors in some rare cases.


Acknowledgements

I had the idea of this tool many years ago. However, I finally decided to implement it after seeing this issue by @hashseed. Also, some parts were inspired by v8-compile-cache by @zertosh.