Modify readme, implement cross-plat --python <loc> closes #94
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
## This repository is not actively maintained.
|
||||
|
||||
### Nexe
|
||||
|
||||
Nexe is a command-line utility that compiles your Node.js application into a single executable file.
|
||||
@@ -9,7 +7,7 @@ Nexe is a command-line utility that compiles your Node.js application into a sin
|
||||
|
||||
### Motivation
|
||||
|
||||
- Ability to run multiple applications with *different* node.js runtimes.
|
||||
- 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.
|
||||
@@ -20,69 +18,73 @@ Nexe is a command-line utility that compiles your Node.js application into a sin
|
||||
- Linux / Mac / BSD / Windows
|
||||
- Windows: Python 2.6 or 2.7 (in PATH), Visual Studio 2010 or 2012
|
||||
|
||||
##Caveats
|
||||
## Caveats
|
||||
|
||||
### Doesn't support native modules
|
||||
|
||||
- Use the techniques below for working around dynamic require statments 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.
|
||||
|
||||
###Doesn't support dynamic require statments
|
||||
- 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.
|
||||
|
||||
### Doesn't support dynamic require statements
|
||||
|
||||
Such As:
|
||||
```
|
||||
|
||||
```javascript
|
||||
var x = require(someVar);
|
||||
```
|
||||
|
||||
In this case nexe won't bundle the file
|
||||
|
||||
```
|
||||
```javascript
|
||||
var x;
|
||||
if (someCheck) {
|
||||
x = require("./ver1.js");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
x = require("./var2.js");
|
||||
}
|
||||
```
|
||||
|
||||
In this case nexe will bundle both files.
|
||||
|
||||
|
||||
Workarounds:
|
||||
1) for dyanmic requires that you want bundled add the following into your project
|
||||
```
|
||||
1) for dynamic requires that you want bundled add the following into your project
|
||||
|
||||
```javascript
|
||||
var dummyToForceIncludeForBundle = false;
|
||||
if (dummyToForceIncludeForBundle) {
|
||||
require("./loadedDynamicallyLater.js");
|
||||
...
|
||||
// ...
|
||||
}
|
||||
```
|
||||
this will trick the bundler into including them.
|
||||
|
||||
|
||||
2) for dynamic files getting included that you don't want to be
|
||||
```
|
||||
|
||||
```javascript
|
||||
var moduleName = "./ver2.js";
|
||||
if (someCheck) {
|
||||
moduleName = "./ver1.js";
|
||||
}
|
||||
var x = require(moduleName)
|
||||
var x = require(moduleName);
|
||||
```
|
||||
Note: neither file will be bundled.
|
||||
|
||||
Using these two techniques you can change your application code so mdoules 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.
|
||||
|
||||
### __dirname
|
||||
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 budnled it is part of the executable. __dirname is therefore the executable dir (process.execPath). Thus if you put resources on a realtive path from the the executable your app will be able to access them.
|
||||
### __dirname
|
||||
|
||||
If you had a data file at /dev/myNodeApp/stateManager/handler/data/some.csv
|
||||
and a file at /dev/myNodeApp/stateManager/handler/loader.js
|
||||
```
|
||||
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`
|
||||
|
||||
```javascript
|
||||
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
|
||||
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 dependciey that you are unaware of).
|
||||
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'
|
||||
Note: __filename will be 'undefined'
|
||||
|
||||
### child_process.fork
|
||||
|
||||
@@ -99,13 +101,13 @@ Via NPM:
|
||||
Or git:
|
||||
|
||||
```bash
|
||||
git clone
|
||||
git clone
|
||||
```
|
||||
|
||||
### CLI Usage
|
||||
|
||||
````text
|
||||
|
||||
```text
|
||||
|
||||
Usage: nexe -i [sources] -o [binary]
|
||||
|
||||
Options:
|
||||
@@ -115,12 +117,12 @@ Options:
|
||||
-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]
|
||||
|
||||
````
|
||||
```
|
||||
|
||||
|
||||
### Code Usage
|
||||
|
||||
````javascript
|
||||
```javascript
|
||||
|
||||
var nexe = require('nexe');
|
||||
|
||||
@@ -131,7 +133,12 @@ nexe.compile({
|
||||
nodeTempDir: __dirname,
|
||||
flags: true
|
||||
}, function(err) {
|
||||
|
||||
|
||||
});
|
||||
|
||||
````
|
||||
|
||||
```
|
||||
|
||||
## Maintainers
|
||||
|
||||
* __Jared Allard__ ([@rainbowdashdc](https://github.com/RainbowDashDC)) <[rainbowdashdc@mezgrman.de](mailto:rainbowdashdc@mezgrman.de)> (Active)
|
||||
* __Craig Jefferds__ ([@crcn](https://github.com/crcn)) <[craig.j.condon@gmail.com](mailto:craig.j.condon@gmail.com)> (Not Active)
|
||||
|
||||
@@ -34,6 +34,11 @@ options('f', {
|
||||
options('v', {
|
||||
alias: 'version',
|
||||
description: 'Display version number'
|
||||
}).
|
||||
options('p', {
|
||||
alias: 'python',
|
||||
description: 'Set path of python to use.',
|
||||
default: 'python'
|
||||
});
|
||||
|
||||
var argv = cli.argv;
|
||||
@@ -54,12 +59,12 @@ function toRelative(pt) {
|
||||
return path.join(process.cwd(), pt);
|
||||
}
|
||||
|
||||
|
||||
require('../lib').compile({
|
||||
require('../lib').compile({
|
||||
input : require.resolve(toRelative(argv.i)),
|
||||
output : toRelative(argv.o),
|
||||
output : toRelative(argv.o),
|
||||
flags : argv.f,
|
||||
nodeVersion : argv.r,
|
||||
nodeVersion : argv.r,
|
||||
python : argv.python,
|
||||
nodeTempDir : toRelative(argv.t) }, function(error) {
|
||||
|
||||
if(error) console.log(error.message);
|
||||
|
||||
@@ -3,9 +3,10 @@ var nexe = require('nexe');
|
||||
nexe.compile(
|
||||
{
|
||||
input: "./index.js",
|
||||
output: "./helloWorld.exe",
|
||||
output: "",
|
||||
nodeVersion: "0.10.33",
|
||||
nodeTempDir: "",
|
||||
python: "C:\\Python27\\python.exe",
|
||||
flags: true,
|
||||
resourceFiles: ["./message.txt"]
|
||||
},
|
||||
@@ -14,4 +15,4 @@ nexe.compile(
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
+73
-12
@@ -19,8 +19,10 @@ var _log = require("./log"),
|
||||
_monkeypatch = require("./monkeypatch");
|
||||
|
||||
var isWin = /^win/.test(process.platform);
|
||||
var isPy;
|
||||
|
||||
/**
|
||||
* Compiliation process.
|
||||
*/
|
||||
|
||||
exports.compile = function (options, complete) {
|
||||
@@ -28,11 +30,31 @@ exports.compile = function (options, complete) {
|
||||
var nodeCompiler, nexeEntryPath;
|
||||
|
||||
async.waterfall([
|
||||
/** check relevant options
|
||||
*
|
||||
*/
|
||||
function checkOpts (next) {
|
||||
/*
|
||||
* Have we been given a custom flag for python executable?
|
||||
*/
|
||||
if(options.python!=='python' && options.python!=="") {
|
||||
if(isWin) {
|
||||
isPy=options.python.replace(/\//gm, "\\"); // use windows file paths, batch is sensitive.
|
||||
} else {
|
||||
isPy=options.python;
|
||||
}
|
||||
|
||||
_log("set python as "+isPy);
|
||||
} else {
|
||||
isPy="python";
|
||||
}
|
||||
|
||||
next();
|
||||
},
|
||||
|
||||
/**
|
||||
* first download node
|
||||
*/
|
||||
|
||||
function downloadNode (next) {
|
||||
_downloadNode(options.nodeVersion, options.nodeTempDir, next);
|
||||
},
|
||||
@@ -104,11 +126,16 @@ exports.compile = function (options, complete) {
|
||||
*/
|
||||
|
||||
function makeExe (next) {
|
||||
_log("make");
|
||||
if(isWin) {
|
||||
_log("vcbuild [make stage]");
|
||||
} else {
|
||||
_log("make");
|
||||
}
|
||||
nodeCompiler.make(next);
|
||||
},
|
||||
|
||||
/**
|
||||
* we create the output directory if needed
|
||||
*/
|
||||
|
||||
function makeOutputDirectory (next) {
|
||||
@@ -116,11 +143,20 @@ exports.compile = function (options, complete) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy the compilied binary to the output specified.
|
||||
*/
|
||||
|
||||
function copyBinaryToOutput (next) {
|
||||
_log("cp %s %s", nodeCompiler.releasePath, options.output);
|
||||
ncp(nodeCompiler.releasePath, options.output, next);
|
||||
ncp(nodeCompiler.releasePath, options.output, function (err) {
|
||||
if (err) {
|
||||
console.log("* NOTICE * Failed to copy binary. Did the build fail?");
|
||||
throw err; // dump raw error object
|
||||
}
|
||||
_log('copied');
|
||||
|
||||
next();
|
||||
});
|
||||
}
|
||||
], complete);
|
||||
}
|
||||
@@ -228,7 +264,27 @@ function _getNodeCompiler (nodeFileDir, complete) {
|
||||
version: path.basename(nodeFileDir),
|
||||
releasePath: path.join(dir, "Release", "node.exe"),
|
||||
make: function(next) {
|
||||
var vcbuild = spawn("vcbuild.bat", ["nosign", "release"], { cwd: dir });
|
||||
// create a new env with minimal impact on old one
|
||||
var newEnv = process.env
|
||||
|
||||
if(isPy!=="python") {
|
||||
_log("vcbuild: python => "+isPy);
|
||||
|
||||
// replace vcbuild contents
|
||||
var data = fs.readFileSync(dir+"\\vcbuild.bat", 'utf8');
|
||||
var result = data.replace(/[\s]python/gm, isPy); // I can't regex
|
||||
var err = fs.writeFileSync(dir+"\\vcbuild.bat", result, 'utf8');
|
||||
if(err) throw err;
|
||||
|
||||
// temporary fix, should edit whatever is gening the project files at somepoint.
|
||||
newEnv.path = process.env.PATH+";"+path.dirname(isPy)
|
||||
}
|
||||
|
||||
// spawn a vcbuild process with our custom enviroment.
|
||||
var vcbuild = spawn("vcbuild.bat", ["nosign", "release"], {
|
||||
cwd: dir,
|
||||
env: newEnv
|
||||
});
|
||||
vcbuild.stdout.pipe(process.stdout);
|
||||
vcbuild.stderr.pipe(process.stderr);
|
||||
vcbuild.on("close", function() {
|
||||
@@ -242,7 +298,13 @@ function _getNodeCompiler (nodeFileDir, complete) {
|
||||
version: path.basename(nodeFileDir),
|
||||
releasePath: path.join(dir, "out", "Release", "node"),
|
||||
make: function (next) {
|
||||
var configure = spawn("./configure", [], { cwd: dir });
|
||||
var cfg = "./configure", configure;
|
||||
if(isPy !== "python") {
|
||||
configure = spawn(isPy, [cfg], { cwd: dir });
|
||||
} else {
|
||||
configure = spawn(cfg, [], { cwd: dir });
|
||||
}
|
||||
|
||||
configure.stdout.pipe(process.stdout);
|
||||
configure.stderr.pipe(process.stderr);
|
||||
configure.on("close", function () {
|
||||
@@ -281,7 +343,7 @@ function _monkeyPatchNodeConfig (compiler, complete) {
|
||||
},
|
||||
|
||||
/**
|
||||
* monkeypatch main entry point
|
||||
* monkeypatch main entry point
|
||||
*/
|
||||
|
||||
function (next) {
|
||||
@@ -299,7 +361,7 @@ function _monkeyPatchGyp (compiler, complete) {
|
||||
var gypPath = path.join(compiler.dir, "node.gyp");
|
||||
|
||||
_monkeypatch(
|
||||
gypPath,
|
||||
gypPath,
|
||||
function (content) {
|
||||
return ~content.indexOf("nexe.js");
|
||||
},
|
||||
@@ -317,7 +379,7 @@ function _monkeyPatchMainJs (compiler, complete) {
|
||||
var mainPath = path.join(compiler.dir, "src", "node.js");
|
||||
|
||||
_monkeypatch(
|
||||
mainPath,
|
||||
mainPath,
|
||||
function (content) {
|
||||
return ~content.indexOf("nexe");
|
||||
},
|
||||
@@ -395,9 +457,9 @@ function _logProgress (req) {
|
||||
req.on("response", function (resp) {
|
||||
|
||||
var len = parseInt(resp.headers["content-length"], 10),
|
||||
bar = new ProgressBar("[:bar]", {
|
||||
complete: "=",
|
||||
incomplete: " ",
|
||||
bar = new ProgressBar("[:bar]", {
|
||||
complete: "=",
|
||||
incomplete: " ",
|
||||
total: len,
|
||||
width: process.stdout.columns - 2
|
||||
});
|
||||
@@ -409,4 +471,3 @@ function _logProgress (req) {
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
module.exports = require("./exe");
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user