Nexe is a command-line utility that compiles your Node.js application into a single executable file.
- Ability to run multiple applications with different node.js runtimes.
- Distributable binaries without needing node / npm.
- Starts faster.
- Lockdown specific application versions, and easily rollback.
- Faster deployments.
- Linux / Mac / BSD / Windows
- Python 2.6 or 2.7 (use --python if not in PATH)
- Windows: Visual Studio 2010+
- Use the techniques below for working around dynamic require statements to exclude the module from the bundling, and deploy along side the executable in a node_module folder so your app can find it. Note: On windows you may need to have your app be named node.exe if .node file depends on node.
Such As:
var x = require(someVar);
In this case nexe won't bundle the file
var x;
if (someCheck) {
x = require("./ver1.js");
} else {
x = require("./ver2.js");
}
In this case nexe will bundle both files.
Workarounds:
- for dynamic requires that you want bundled add the following into your project
var dummyToForceIncludeForBundle = false;
if (dummyToForceIncludeForBundle) {
require("./loadedDynamicallyLater.js");
// ...
}
this will trick the bundler into including them.
- for dynamic files getting included that you don't want to be
var moduleName = "./ver2.js";
if (someCheck) {
moduleName = "./ver1.js";
}
var x = require(moduleName);
Note: neither file will be bundled.
Using these two techniques you can change your application code so modules are not bundles, and generate a includes.js file as part of your build process so that the right files get bundled for your build configuration.
Once the module is bundled it is part of the executable. __dirname is therefore the executable dir (process.execPath). Thus if you put resources on a relative path from the the executable your app will be able to access them.
If you had a data file at /dev/myNodeApp/stateManager/handler/data/some.csv
and a file at /dev/myNodeApp/stateManager/handler/loader.js
module.exports = fw.readFileSync(path.join(__dirname, "./data/some.csv"));
You would need to deploy some.csv in a sub dir data/
along side your executable
There are potential use cases for __dirname where the executable path is not the correct substitution, and could result in a silent error (possibly even in a dependency that you are unaware of).
Note: __filename will be 'undefined'
child_process.spawn works is unmodified, but child_process.fork will make an attempt to launch a new instance of your executable and run the bundled module.
Via NPM:
npm install nexe [-g]
Or git:
git clone https://github.com/jaredallard/nexe.git
Usage: nexe -i [sources] -o [binary] [options]
Options:
-i, --input The entry javascript files [default: cwd]
-o, --output The output binary [default: out.nex]
-r, --runtime The node.js runtime to use [default: "latest"]
-t, --temp The path to store node.js sources [default: ./tmp/nexe]
-f, --flags Don't parse node and v8 flags, pass through app flags [default: false]
-v, --version Display version number
-p, --python Set path of python to use. [default: "python"]
-F, --framework Set the framework to use. [default: "nodejs"]
var nexe = require('nexe');
nexe.compile({
input: 'input.js', // where the input file is
output: 'path/to/bin', // where to output the compiled binary
nodeVersion: '5.5.0', // node version
nodeTempDir: 'src', // where to store node source.
nodeConfigureArgs: ['opt', 'val'], // for all your configure arg needs.
nodeMakeArgs: ["-j", "4"], // when you want to control the make process.
nodeVCBuildArgs: ["nosign", "x64"], // when you want to control the make process for windows.
// By default "nosign" option will be specified
// You can check all available options and its default values here:
// https://github.com/nodejs/node/blob/master/vcbuild.bat
python: 'path/to/python', // for non-standard python setups. Or python 3.x forced ones.
resourceFiles: [ 'path/to/a/file' ], // array of files to embed.
resourceRoot: [ 'path/' ], // where to embed the resourceFiles.
flags: true, // use this for applications that need command line flags.
jsFlags: "--use_strict", // v8 flags
startupSnapshot: 'path/to/snapshot.js', // when you want to specify a script to be
// added to V8's startup snapshot. This V8
// feature deserializes a heap to save startup time.
// More information in this blog post:
// http://v8project.blogspot.de/2015/09/custom-startup-snapshots.html
framework: "node" // node, nodejs, or iojs
}, function(err) {
if(err) {
return console.log(err);
}
// do whatever
});
As of 0.4.0 you can now embed nexe options into package.json. Note that this Format is still in works, so it is likely to change.
"nexe": {
"input": "./bin/nexe",
"output": "nexe^$",
"temp": "src",
"browserify": {
"requires": [],
"excludes": [],
"paths": []
},
"runtime": {
"framework": "node",
"version": "5.6.0",
"js-flags": "--use_strict",
"ignoreFlags": true
}
}
Notes:
- output: can use ^$ for platform specific file extension
- js-flags: this is also known as v8 flags, and supports all v8 flags.
If you have requires that aren't resolving well, you can do two things.
Try adding it to nexe.browserify.requires
in your package.json
"nexe": {
.......
"browserify": {
"requires": [
{
"file": "myfile.js",
"expose": "mymodule"
},
"mymodule.js"
],
"excludes": [],
"paths": []
},
.......
}
Or, if that doesn't work (it tends to not work sometimes), you can try altering browserify.paths like so:
"nexe": {
.......
"browserify": {
"requires": []
"excludes": [],
"paths": ["/path/to/my/loc"]
},
.......
}
If it still doesn't work, file a bug with what you tried! (also try using nexe@0.4.2
)
- Jared Allard (@jaredallard) <jaredallard@outlook.com> (Active)
- Christopher Karper (@ckarper) <Christopher.Karper@gmail.com> (Active)
- Craig Condon (@crcn) <craig.j.condon@gmail.com> (Old Project Owner)