module-bundler
Version:
ModuleBundler combines javascript files and provides a minimal CommonJS-like loader to access them
355 lines (324 loc) • 12.2 kB
JavaScript
// Generated by CoffeeScript 1.7.1
(function() {
var Queue, RESERVED, coffeescript, existsSync, fs, installThenWriteBundle, jsp, mb, path, pro, runInExecDir, spawn, wrench, _, _base,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
spawn = require('child_process').spawn;
fs = require('fs');
path = require('path');
_ = require('underscore');
existsSync = fs.existsSync || path.existsSync;
wrench = require('wrench');
coffeescript = require('coffee-script');
jsp = require('uglify-js').parser;
pro = require('uglify-js').uglify;
Queue = require('queue-async');
mb = this.mb = typeof exports !== 'undefined' ? exports : {};
RESERVED = ['_publish', '_load', '_alias'];
if ((_base = require.extensions)['.coffee'] == null) {
_base['.coffee'] = function(module, filename) {
var content;
content = coffeescript.compile(fs.readFileSync(filename, 'utf8', {
filename: filename
}));
return module._compile(content, filename);
};
}
installThenWriteBundle = function(filename, bundle, options, callback) {
var dir, spawned;
dir = path.dirname(filename);
spawned = spawn('npm', ['install'], {
cwd: dir
});
spawned.on('error', function(err) {
console.log("Failed to run command: npm, args: " + (['install'].join(', ')) + ". Error: " + err.message);
return callback(err);
});
spawned.stderr.on('data', function(data) {
process.stderr.write(data.toString());
return callback(new Error("Errors encountered: " + (data.toString())));
});
return spawned.on('exit', (function(_this) {
return function(code) {
if (code) {
return callback(new Error("Unexpected code " + code));
}
options = _.clone(options);
options.skip_install = true;
return mb.writeBundle(filename, bundle, options, callback);
};
})(this));
};
mb.writeBundle = function(filename, bundle, options, callback) {
var ast, bundle_code, compressed_bundle, dir, directory, e, resolved_filename;
if (!filename) {
throw 'module-bundler: missing output filename or object';
}
if (!bundle) {
throw 'module-bundler: missing bundle object';
}
if (!(options && options.cwd)) {
throw 'module-bundler: missing options.cwd';
}
if (!callback) {
throw 'module-bundler: missing callback';
}
dir = path.dirname(filename);
if (!options.skip_install && (dir !== options.cwd) && existsSync(path.join(dir, 'package.json'))) {
return installThenWriteBundle(filename, bundle, options, callback);
}
if (!(bundle_code = mb.generateBundleCode(bundle, options))) {
return callback(new Error("Failed to generate bundle"));
}
resolved_filename = mb.resolveSafe(filename, options);
try {
directory = path.dirname(resolved_filename);
if (!existsSync(directory)) {
wrench.mkdirSyncRecursive(directory, 0x1ff);
}
} catch (_error) {
e = _error;
if (e.code !== 'EEXIST') {
return callback(e);
}
}
bundle = "(function() {\n" + bundle_code + "})(this);\n";
if (options.compress || resolved_filename.endsWith('.min.js') || resolved_filename.endsWith('-min.js')) {
ast = jsp.parse(bundle);
ast = pro.ast_mangle(ast);
ast = pro.ast_squeeze(ast);
compressed_bundle = pro.gen_code(ast);
return fs.writeFile(resolved_filename, compressed_bundle, 'utf8', function() {
return callback();
});
} else {
return fs.writeFile(resolved_filename, bundle, 'utf8', function() {
return callback();
});
}
};
mb.writeBundles = function(config, options, callback) {
var bundle, err, filename, installed_packages, queue, _fn;
if (!config) {
throw 'module-bundler: missing config filename or object';
}
if (!(options && options.cwd)) {
throw 'module-bundler: missing options.cwd';
}
if (!callback) {
throw 'module-bundler: missing callback';
}
if (_.isString(config)) {
try {
config = require(mb.resolveSafe(config, options));
} catch (_error) {
err = _error;
return callback(err);
}
if (_.isString(config)) {
return callbacK(new Error("mbundle: failed to load " + config + " configuration file. Does it exist?"));
}
}
queue = new Queue(1);
installed_packages = [];
_fn = function(filename, bundle) {
return queue.defer(function(callback) {
var dir;
if (!_.isObject(bundle)) {
return callback(new Error("mbundle: unexpected information for " + filename));
}
dir = path.dirname(filename);
if (!options.skip_install && (dir !== options.cwd) && existsSync(path.join(dir, 'package.json')) && !(__indexOf.call(installed_packages, path) >= 0)) {
installed_packages.push(path);
return installThenWriteBundle(filename, bundle, options, callback);
} else {
return mb.writeBundle(filename, bundle, options, callback);
}
});
};
for (filename in config) {
bundle = config[filename];
_fn(filename, bundle);
}
return queue.await(callback);
};
runInExecDir = function(fn, cwd) {
var original_dirname, result;
if (cwd) {
original_dirname = fs.realpathSync('.');
process.chdir(cwd);
result = fn();
return process.chdir(original_dirname);
} else {
return fn();
}
};
mb.pathNormalizeSafe = function(target, options) {
var cwd;
if (options == null) {
options = {};
}
if (options.cwd) {
cwd = path.normalize(options.cwd);
}
if (target.substr(0, process.env.HOME.length) === process.env.HOME) {
return target;
}
if (cwd && (target.substr(0, cwd.length) === cwd)) {
return target;
}
runInExecDir((function() {
var e;
try {
return target = path.normalize(target);
} catch (_error) {
e = _error;
}
}), cwd);
return target;
};
mb.requireResolveSafe = function(target, options) {
var e;
if (options == null) {
options = {};
}
if (target.substr(0, process.env.HOME.length) === process.env.HOME) {
return target;
}
target = target;
try {
target = require.resolve(target);
} catch (_error) {
e = _error;
}
return target;
};
mb.resolveSafe = function(target, options) {
var char, cwd, is_file, next_char, path_to_target, raw_target, _i, _len;
if (options == null) {
options = {};
}
if (options.cwd) {
cwd = path.normalize(options.cwd);
}
is_file = target.search(/^file:\/\//) >= 0;
if (is_file) {
target = target.replace(/^file:\/\//, '');
}
if (!(options.skip_require || is_file)) {
target = mb.requireResolveSafe(target, options);
}
if (target.substr(0, process.env.HOME.length) === process.env.HOME) {
return target;
}
if (cwd && (target.substr(0, cwd.length) === cwd)) {
return target;
}
if (target[0] === '.') {
for (_i = 0, _len = target.length; _i < _len; _i++) {
char = target[_i];
next_char = char;
if (char !== '.' && char !== '/') {
break;
}
}
if (next_char === '.' || '/') {
raw_target = path.join((cwd ? cwd : cwd), target);
} else {
raw_target = path.join(cwd, target);
}
} else if (target[0] === '~') {
raw_target = target.replace(/^~/, process.env.HOME);
} else if (cwd) {
raw_target = path.join(cwd, target);
} else {
raw_target = target;
}
path_to_target = path.normalize(raw_target);
if (options.must_exist && !existsSync(path_to_target)) {
return '';
}
return path_to_target;
};
_ = require('underscore');
mb.generateLibraryCode = function() {
return "var root = this;\nvar root_require = root.require;\nvar root_require_define = root_require ? root.require.define : null;\nvar root_require_resolve = root_require ? root.require.resolve : null;\n\n/*\nDefine module-bundler require functions\n*/\nvar mb = (typeof(exports) !== 'undefined') ? exports : {};\nmb.modules = {};\nmb.require = function(module_name) {\n if (!mb.modules.hasOwnProperty(module_name)) {\n if (root_require) {\n return root_require.apply(this, arguments);\n }\n throw \"Cannot find module '\" + module_name + \"'\";\n }\n if (!mb.modules[module_name].exports) {\n mb.modules[module_name].exports = {};\n mb.modules[module_name].loader.call(root, mb.modules[module_name].exports, mb.require, mb.modules[module_name]);\n }\n return mb.modules[module_name].exports;\n};\nmb.require_define = function(obj) {\n for (var module_name in obj) {\n mb.modules[module_name] = {loader: obj[module_name]};\n }\n};\nmb.require_alias = function(alias_name, module_name) {\n mb.modules[alias_name] = {exports: root.require(module_name)};\n};\nmb.require_resolve = function(module_name) {\n if (!mb.modules[module_name]) {\n if (root_require_resolve) {\n return root_require_resolve.apply(this, arguments);\n }\n throw \"Cannot find module '\" + module_name + \"'\"\n }\n return module_name;\n};\n\n// overwrite the root implementation\nroot.require = mb.require;\nif (root_require) {\n // copy all additional properties\n for (var key in root_require)\n root.require[key] = root_require[key];\n}\nroot.require.resolve = mb.require_resolve;\n";
};
mb.generateAliasCode = function(entries) {
var alias_name, code, module_name;
code = "\n";
for (alias_name in entries) {
module_name = entries[alias_name];
code += "mb.require_alias('" + alias_name + "', '" + module_name + "');\n";
}
return code;
};
mb.generatePublishCode = function(entries) {
var code, module_name, symbol;
code = "\n";
for (symbol in entries) {
module_name = entries[symbol];
code += "root['" + symbol + "'] = root.require('" + module_name + "');\n";
}
return code;
};
mb.generateLoadCode = function(entries) {
var code, module_name, _i, _len;
code = "\n";
if (_.isString(entries)) {
entries = [entries];
}
for (_i = 0, _len = entries.length; _i < _len; _i++) {
module_name = entries[_i];
code += "root.require('" + module_name + "');\n";
}
return code;
};
mb.generateModuleCode = function(module_name, filename, options) {
var e, file_contents, pathed_file;
if (__indexOf.call(RESERVED, module_name) >= 0) {
throw "module name cannot be a reservered word: " + module_name;
}
pathed_file = mb.resolveSafe(filename, options);
try {
file_contents = fs.readFileSync(pathed_file, 'utf8');
} catch (_error) {
e = _error;
console.log("Couldn't bundle '" + filename + "'. Does it exist?");
return;
}
return "\nmb.require_define({'" + module_name + "': function(exports, require, module) {\n\n" + file_contents + "\n}});\n";
};
mb.generateBundleCode = function(bundle, options) {
var code, key, module_code, success, value;
code = mb.generateLibraryCode();
success = true;
for (key in bundle) {
value = bundle[key];
if (__indexOf.call(RESERVED, key) >= 0) {
continue;
}
module_code = mb.generateModuleCode(key, value, options);
if (module_code) {
code += module_code;
} else {
success = false;
}
}
if (bundle.hasOwnProperty('_alias')) {
code += mb.generateAliasCode(bundle._alias);
}
if (bundle.hasOwnProperty('_publish')) {
code += mb.generatePublishCode(bundle._publish);
}
if (bundle.hasOwnProperty('_load')) {
code += mb.generateLoadCode(bundle._load);
}
if (success) {
return code;
} else {
}
};
}).call(this);