exe: support --jsFlag, use browserify API, try to get work started on source maps

This commit is contained in:
Jared Allard
2016-02-07 00:45:16 -08:00
parent ce2db38b92
commit 6a07ea62ea
15 changed files with 894 additions and 633 deletions
+1
View File
@@ -5,5 +5,6 @@ test/**/out.nex
test/**/test.nex
test/**/tmp
test/**/node_modules
test/**/*.map
src
+76 -63
View File
@@ -1,96 +1,109 @@
#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
nexe = require('../lib'),
_log = require("../lib/log"),
cli = require('yargs').
fs = require('fs'),
nexe = require('../lib'),
_log = require("../lib/log"),
cli = require('yargs').
usage('Usage: $0 -i [sources] -o [binary]').
options('i', {
demand: true,
alias: 'input',
desc: 'The entry javascript files',
default: process.cwd()
demand: true,
alias: 'input',
desc: 'The entry javascript files',
default: process.cwd()
}).
options('o', {
demand: true,
alias: 'output',
desc: 'The output binary',
default: "out.nex"
demand: true,
alias: 'output',
desc: 'The output binary',
default: "out.nex"
}).
options('r', {
alias: 'runtime',
default: 'latest',
description: 'The node.js runtime to use'
alias: 'runtime',
default: 'latest',
description: 'The node.js runtime to use'
}).
options('t', {
alias: 'temp',
default: './tmp/nexe',
description: 'The path to store node.js sources'
alias: 'temp',
default: './tmp/nexe',
description: 'The path to store node.js sources'
}).
options('f', {
alias: 'flags',
description: 'Don\'t parse node and v8 flags, pass through app flags',
default: false
alias: 'flags',
description: 'Don\'t parse node and v8 flags, pass through app flags',
default: false
}).
options('d', {
alias: 'debug',
default: false,
description: 'generate and use source maps, large file size'
}).
options('j', {
alias: 'jsFlags',
default: false,
description: 'v8 flags for runtime'
})
options('v', {
alias: 'version',
description: 'Display version number'
alias: 'version',
description: 'Display version number'
}).
options('p', {
alias: 'python',
description: 'Set path of python to use.',
default: 'python'
alias: 'python',
description: 'Set path of python to use.',
default: 'python'
}).
options('F', {
alias: 'framework',
description: 'Set the framework to use',
default: 'nodejs'
alias: 'framework',
description: 'Set the framework to use',
default: 'nodejs'
});
var argv = cli.argv;
if(argv.h || argv.help) {
cli.showHelp();
process.exit();
if (argv.h || argv.help) {
cli.showHelp();
process.exit();
} else if (argv.v || argv.version) {
var pkginfo = require('../package.json');
console.log(pkginfo.version);
process.exit();
var pkginfo = require('../package.json');
console.log(pkginfo.version);
process.exit();
}
/**
* TODO: Support network shares?
**/
function toAbsolute(pt) {
if(pt.substr(0, 1) == "/") return pt;
if(pt.substr(1, 3) == ":/") return pt; // for windows "c:/"
return path.join(process.cwd(), pt);
if (pt.substr(0, 1) == "/") return pt; // for *nix "/"
if (pt.substr(0, 2) == "\\\\") return pt; // for windows "\\"
if (pt.substr(1, 3) == ":/") return pt; // for windows "c:/"
// otheerwise...
return path.join(process.cwd(), pt);
}
if(fs.lstatSync(argv.i).isDirectory()) {
opts = nexe.package(path.join(argv.i, "package.json"), argv);
nexe.compile(opts, function(error) {
if(error) {
return console.log(error.message);
}
});
if (fs.lstatSync(argv.i).isDirectory()) {
opts = nexe.package(path.join(argv.i, "package.json"), argv);
nexe.compile(opts, function(error) {
if (error) {
return console.log(error.message);
}
});
} else {
/**
* Call the core
**/
nexe.compile({
input : require.resolve(toAbsolute(argv.i)),
output : toAbsolute(argv.o),
flags : argv.f,
nodeVersion : argv.r,
python : argv.python,
nodeTempDir : toAbsolute(argv.t),
framework : argv.F
},
function(error) {
if(error) {
return console.log(error.message);
}
}
);
/**
* Call the core
**/
nexe.compile({
input: require.resolve(toAbsolute(argv.i)),
output: toAbsolute(argv.o),
flags: argv.f,
nodeVersion: argv.r,
python: argv.python,
nodeTempDir: toAbsolute(argv.t),
framework: argv.F
},
function(error) {
if (error) {
return console.log(error.message);
}
}
);
}
+46 -50
View File
@@ -23,65 +23,61 @@
*
**/
var mdeps = require("module-deps"),
path = require("path"),
spawn = require('child_process').spawn,
fs = require("fs"),
async = require("async"),
browserify = require('browserify'),
builtins = require("builtins"),
_log = require("./log");
'use strict';
let exorcist = require('exorcist'),
browserify = require('browserify'),
path = require("path"),
spawn = require('child_process').spawn,
insertGlobals = require('insert-module-globals'),
fs = require("fs"),
async = require("async"),
builtins = require("builtins"),
_log = require("./log");
/**
* User browserify to create a "packed" file.
*
* @param {String} input - input file
* @param {String} nc - node compiler dir
* @param {Function} complete - next function to call (async)
* @param {string} input - input file
* @param {string} nc - node compiler dir
* @param {array} options - nexe options
* @param {function} complete - next function to call (async)
**/
function bundle (input, nc, complete) {
var bundlePath = path.join(nc, "lib", "nexe.js");
var ws = fs.createWriteStream(bundlePath);
var browserifyExec;
function bundle(input, nc, options, complete) {
const bundlePath = path.join(nc, "lib", "nexe.js");
const mapfile = options.output+'.map';
let ws = fs.createWriteStream(bundlePath);
var browserifyLocations = [ // TODO: Do this programattically.
'This is to ignore the 0 location.',
path.join(__dirname, '../', 'node_modules/browserify/bin/cmd.js'),
path.join(__dirname, '../../', 'node_modules/browserify/bin/cmd.js'),
path.join(__dirname, '../../../', 'node_modules/browserify/bin/cmd.js'),
path.join(__dirname, '../../../../', 'node_modules/browserify/bin/cmd.js')
]
for(var i = 0; i !== (browserifyLocations.length-1); i++) {
if(fs.existsSync(browserifyLocations[i])) {
browserifyExec = browserifyLocations[i];
_log('found browserify in', browserifyExec);
break;
const igv = '__filename,__dirname';
let insertGlobalVars = {},
wantedGlobalVars = igv.split(',');
// parse insertGlobalVars.
Object.keys(insertGlobals.vars).forEach(function (x) {
if (wantedGlobalVars.indexOf(x) === -1) {
insertGlobalVars[x] = undefined;
}
}
var proc = spawn('node', [browserifyExec, '--node', input ]);
proc.stdout.pipe(ws);
proc.on('error', function(err) {
console.error(err.toString('ascii'));
_log('error', 'Failed to invoke browserify');
process.exit(1);
})
proc.stderr.on('data', function(data) {
console.error(data.toString('ascii'));
if(!fs.existsSync(input)) {
_log('error', 'Your input file doesn\'t exist!');
}
_log('error', 'Browserify failed to launch');
process.exit(1);
});
proc.on('close', function(code) {
_log("Browserify finished");
})
_log('executing browserify via API');
let bproc = browserify([], {
debug: options.debug,
commondir: false,
builtins: false,
insertGlobalVars: insertGlobalVars,
detectGlobals: true,
browserField: false
}).add(input)
if(options.debug) {
bproc.require(require.resolve('source-map-support'))
}
let bprocbun = bproc.bundle() // bundle
.pipe(exorcist(mapfile, mapfile, './')) // generate source maps.
.pipe(ws) // pipe to file
ws.on('error', function(err) {
console.log(err);
@@ -95,7 +91,7 @@ function bundle (input, nc, complete) {
// write the source modified to nexe.js
fs.writeFile(bundlePath, source, 'utf8', function(err) {
if(err) {
if (err) {
_log('error', 'failed to save source');
process.exit(1);
}
+10 -5
View File
@@ -23,11 +23,17 @@
*
**/
'use strict';
var path = require("path"),
fs = require("fs");
fs = require("fs");
/**
* TODO: Optimize this code. (more like document it so I understand it better.)
* Embed files.
*
* @param {array} resourceFiles - array of files to embed.
* @param {string} resourceRoot - root of resources.
* @param {function} compelte - callback
**/
function embed(resourceFiles, resourceRoot, complete) {
function encode(filePath) {
@@ -52,11 +58,10 @@ function embed(resourceFiles, resourceRoot, complete) {
complete(null, buffer);
}
var accessor = function (key) {
var accessor = function(key) {
if (embeddedFiles.hasOwnProperty(key)) {
return new Buffer(embeddedFiles[key], 'base64');
}
else {
} else {
//file was not embedded, throw err.
throw new Error('Embedded file not found');
}
+532 -515
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -21,6 +21,7 @@
"browserify": "^13.0.0",
"builtins": "1.0.3",
"colors": "^1.1.2",
"exorcist": "^0.4.0",
"glob": "^6.0.4",
"gunzip-maybe": "^1.3.1",
"insert-module-globals": "^7.0.1",
@@ -30,6 +31,7 @@
"outcome": "0.0.18",
"progress": "^1.1.8",
"request": "^2.67.0",
"source-map-support": "^0.4.0",
"sprintf": "~0.1.5",
"step": "0.0.x",
"tar-stream": "^1.3.1",
+61
View File
@@ -0,0 +1,61 @@
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var jade = require('jade');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env node
require('source-map-support').install();
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('express-test:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
throw new Error('test');
//# sourceMappingURL=./test.nex.map
+28
View File
@@ -0,0 +1,28 @@
{
"name": "express-test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"jade": "~1.11.0",
"morgan": "~1.6.1",
"serve-favicon": "~2.3.0"
},
"nexe": {
"input": "bin/www",
"output": "test.nex",
"temp": "src",
"debug": true,
"runtime": {
"framework": "node",
"version": "5.5.0",
"ignoreFlags": true
}
}
}
@@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
+9
View File
@@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
+9
View File
@@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
+6
View File
@@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}
+5
View File
@@ -0,0 +1,5 @@
extends layout
block content
h1= title
p Welcome to #{title}
+7
View File
@@ -0,0 +1,7 @@
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content