requisite
Version:
A cosmic javascript bundler.
379 lines (354 loc) • 11.1 kB
JavaScript
// Generated by CoffeeScript 1.7.1
var Module, compilers, fs, path, resolver, utils, wrapper;
fs = require('fs');
path = require('path');
compilers = require('./compilers');
resolver = require('./resolver');
utils = require('./utils');
wrapper = require('./wrapper');
Module = (function() {
function Module(requiredAs, opts) {
var ext, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6;
if (opts == null) {
opts = {};
}
this.moduleCache = (_ref = opts.moduleCache) != null ? _ref : {};
this.requiredAs = requiredAs;
this.requiredBy = opts.requiredBy;
this.resolver = (_ref1 = opts.resolver) != null ? _ref1 : resolver();
this.compilers = (_ref2 = opts.compilers) != null ? _ref2 : compilers;
this.extensions = (function() {
var _results;
_results = [];
for (ext in compilers) {
_results.push('.' + ext);
}
return _results;
})();
this.async = (_ref3 = opts.async) != null ? _ref3 : false;
this.exclude = opts.exclude;
this.include = opts.include;
this.paths = opts.paths;
this.bare = opts.bare;
this.strict = opts.strict;
this["export"] = (_ref4 = opts["export"]) != null ? _ref4 : false;
this.require = (_ref5 = opts.require) != null ? _ref5 : true;
this.urlRoot = (_ref6 = opts.urlRoot) != null ? _ref6 : '';
this.ast = null;
this.source = null;
this.absolutePath = opts.absolutePath;
this.basePath = opts.basePath;
this.normalizedPath = opts.normalizedPath;
this.requireAs = opts.requireAs;
if (!((this.absolutePath != null) && (this.normalizedPath != null))) {
this.resolve();
}
this.dependencies = {};
this.dependents = {};
}
Module.prototype.resolve = function() {
var k, v, _ref, _results;
_ref = this.resolver(this.requiredAs, {
paths: this.paths,
requireAs: this.requireAs,
requiredBy: this.requiredBy,
basePath: this.basePath
});
_results = [];
for (k in _ref) {
v = _ref[k];
_results.push(this[k] = v);
}
return _results;
};
Module.prototype.compile = function(callback) {
return fs.stat(this.absolutePath, (function(_this) {
return function(err, stat) {
var extension;
if (err != null) {
return callback(err);
}
if ((_this.mtime != null) && stat.mtime < _this.mtime) {
return callback();
}
_this.mtime = stat.mtime;
extension = (path.extname(_this.absolutePath)).substr(1);
return fs.readFile(_this.absolutePath, 'utf8', function(err, source) {
var compiler;
if ((compiler = _this.compilers[extension]) == null) {
throw new Error("No suitable compiler found for " + _this.absolutePath);
}
return compiler.call(_this, {
source: source,
filename: _this.normalizedPath
}, function(err, source, sourceMap) {
if (err != null) {
return callback(err);
}
_this.source = source;
_this.sourceMap = sourceMap;
return callback();
});
});
};
})(this));
};
Module.prototype.parse = function(opts, callback) {
var k, v, _ref, _ref1;
if (typeof opts === 'function') {
_ref = [opts, {}], callback = _ref[0], opts = _ref[1];
}
if (opts.deep) {
_ref1 = this.moduleCache;
for (k in _ref1) {
v = _ref1[k];
delete this.moduleCache[k];
}
}
return this.compile((function(_this) {
return function(err) {
var dependencies, mod, _ref2;
if (err != null) {
return callback(err);
}
_this.ast = utils.parse(_this.source, {
filename: _this.normalizedPath
});
try {
dependencies = _this.transform();
} catch (_error) {
err = _error;
return callback(err);
}
_this.moduleCache[_this.requireAs] = _this;
_this.dependencies = {};
if (_this.include != null) {
_ref2 = _this.include;
for (k in _ref2) {
v = _ref2[k];
mod = _this.resolver(v, {
paths: _this.paths,
basePath: _this.basePath,
extensions: _this.extensions,
requiredAs: k
});
mod.requireAs = k;
mod.basePath = _this.basePath;
mod.requiredBy = _this.absolutePath;
dependencies.unshift(mod);
}
}
return _this.traverse(dependencies, opts, callback);
};
})(this));
};
Module.prototype.transform = function() {
var dependencies;
dependencies = [];
this.walkAst((function(_this) {
return function(node) {
var callback, mod, required, _ref;
if (node.type === 'CallExpression' && node.callee.name === 'require') {
_ref = node["arguments"], required = _ref[0], callback = _ref[1];
if (required.type === 'Literal' && typeof required.value === 'string') {
mod = _this.resolver(required.value, {
basePath: _this.basePath,
extensions: _this.extensions,
requiredAs: required.value,
requiredBy: _this.absolutePath
});
if (mod.async = callback != null) {
required.value = path.join(_this.urlRoot, mod.requireAs);
} else {
required.value = mod.requireAs;
}
dependencies.push(mod);
}
return true;
}
};
})(this));
return dependencies;
};
Module.prototype.traverse = function(dependencies, opts, callback) {
var cached, dep, mod, _ref;
if (typeof opts === 'function') {
_ref = [opts, {}], callback = _ref[0], opts = _ref[1];
}
if (dependencies == null) {
dependencies = this.dependencies.slice(0);
}
if (opts == null) {
opts = {};
}
if (callback == null) {
callback = function() {};
}
if (dependencies.length === 0) {
return callback();
}
dep = dependencies.shift();
if ((this.exclude != null) && this.exclude.test(dep.requireAs)) {
return this.traverse(dependencies, opts, callback);
}
if (this.dependencies[dep.requireAs] != null) {
return this.traverse(dependencies, opts, callback);
}
if ((cached = this.find(dep.requireAs)) != null) {
this.dependencies[cached.requireAs] = cached;
cached.dependents[this.requireAs] = this;
return this.traverse(dependencies, opts, callback);
}
dep.moduleCache = this.moduleCache;
dep.resolver = this.resolver;
dep.urlRoot = this.urlRoot;
dep.strict = this.strict;
mod = new Module(dep.requiredAs, dep);
mod.exclude = this.exclude;
mod.dependents[this.requireAs] = this;
this.dependencies[mod.requireAs] = mod;
return mod.parse((function(_this) {
return function(err) {
if (err != null) {
return callback(err);
}
return _this.traverse(dependencies, opts, callback);
};
})(this));
};
Module.prototype.append = function(mod) {
var node, _i, _len, _ref, _ref1, _ref2;
_ref2 = (_ref = (_ref1 = mod.ast) != null ? _ref1.body : void 0) != null ? _ref : [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
node = _ref2[_i];
this.ast.body.push(node);
}
};
Module.prototype.find = function(query) {
var k, requireAs, v, _ref;
switch (typeof query) {
case 'function':
_ref = this.moduleCache;
for (k in _ref) {
v = _ref[k];
if (query(v)) {
return v;
}
}
break;
case 'string':
requireAs = query.replace(/^\.?\/+/, '');
if (requireAs === '') {
requireAs = this.requireAs;
}
return this.moduleCache[requireAs];
default:
throw new Error('Invalid query for find');
}
};
Module.prototype.wrapped = function() {
var define, node, _i, _len, _ref;
if (this.bare) {
return this.ast;
}
define = new wrapper.Define({
strict: this.strict,
absolutePath: this.absolutePath,
async: this.async,
urlRoot: this.urlRoot,
requireAs: this.requireAs,
mtime: this.mtime
});
_ref = this.ast.body;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
define.body.push(node);
}
return define.ast;
};
Module.prototype.walkAst = function(fn) {
return utils.walk(this.ast, fn);
};
Module.prototype.walkCache = function(fn) {
var mod, _i, _len, _ref, _results;
_ref = this.moduleCache;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
mod = _ref[_i];
_results.push(fn(mod));
}
return _results;
};
Module.prototype.walkDependencies = function(mod, fn) {
var seen, walk, _ref;
if (typeof mod === 'function') {
_ref = [mod, this], fn = _ref[0], mod = _ref[1];
}
seen = {};
walk = function(mod, fn) {
var k, v, _ref1, _results;
if (seen[mod.requireAs]) {
return;
}
seen[mod.requireAs] = true;
_ref1 = mod.dependencies;
_results = [];
for (k in _ref1) {
v = _ref1[k];
if (seen[k]) {
continue;
}
if ((fn(v)) !== false) {
_results.push(walk(v, fn));
} else {
_results.push(void 0);
}
}
return _results;
};
return walk(mod, fn);
};
Module.prototype.bundle = function() {
var node, toplevel, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
toplevel = ((_ref = this.toplevel) != null ? _ref : new wrapper.Wrapper()).clone();
this.walkDependencies(function(mod) {
var node, _i, _len, _ref1, _results;
if ((mod.ast != null) && !mod.async) {
_ref1 = mod.wrapped().body;
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
node = _ref1[_i];
_results.push(toplevel.body.push(node));
}
return _results;
}
});
_ref1 = this.wrapped().body;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
node = _ref1[_i];
toplevel.body.push(node);
}
if (!(this.async || this.bare)) {
if (this["export"]) {
_ref2 = (utils.parse("global." + this["export"] + " = require('" + this.requireAs + "');")).body;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
node = _ref2[_j];
toplevel.body.push(node);
}
} else if (this.require) {
_ref3 = (utils.parse("require('" + this.requireAs + "');")).body;
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
node = _ref3[_k];
toplevel.body.push(node);
}
}
}
return toplevel.ast;
};
Module.prototype.toString = function(opts) {
return utils.codegen(this.bundle(), opts);
};
return Module;
})();
module.exports = Module;
//# sourceMappingURL=module.map