Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 53 additions & 52 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var fs = require('fs');
var path = require('path');
var relativePath = require('cached-path-relative');

var browserResolve = require('browser-resolve');
var nodeResolve = require('resolve');
Expand All @@ -22,9 +23,9 @@ function Deps (opts) {
var self = this;
if (!(this instanceof Deps)) return new Deps(opts);
Transform.call(this, { objectMode: true });

if (!opts) opts = {};

this.basedir = opts.basedir || process.cwd();
this.cache = opts.cache;
this.fileCache = opts.fileCache;
Expand All @@ -36,7 +37,7 @@ function Deps (opts) {
this.walking = {};
this.entries = [];
this._input = [];

this.paths = opts.paths || process.env.NODE_PATH || '';
if (typeof this.paths === 'string') {
var delimiter = path.delimiter || (process.platform === 'win32' ? ';' : ':');
Expand All @@ -47,7 +48,7 @@ function Deps (opts) {
.map(function (p) {
return path.resolve(self.basedir, p);
});

this.transforms = [].concat(opts.transform).filter(Boolean);
this.globalTransforms = [].concat(opts.globalTransform).filter(Boolean);
this.resolver = opts.resolve || browserResolve;
Expand All @@ -59,7 +60,7 @@ function Deps (opts) {
if (!this.options.expose) this.options.expose = {};
this.pending = 0;
this.inputPending = 0;

var topfile = path.join(this.basedir, '__fake.js');
this.top = {
id: topfile,
Expand All @@ -71,11 +72,11 @@ function Deps (opts) {

Deps.prototype._isTopLevel = function (file) {
var isTopLevel = this.entries.some(function (main) {
var m = path.relative(path.dirname(main), file);
var m = relativePath(path.dirname(main), file);
return m.split(/[\\\/]/).indexOf('node_modules') < 0;
});
if (!isTopLevel) {
var m = path.relative(this.basedir, file);
var m = relativePath(this.basedir, file);
isTopLevel = m.split(/[\\\/]/).indexOf('node_modules') < 0;
}
return isTopLevel;
Expand All @@ -94,14 +95,14 @@ Deps.prototype._transform = function (row, enc, next) {
this.transforms.push([ row.transform, row.options ]);
return next();
}

self.pending ++;
var basedir = defined(row.basedir, self.basedir);

if (row.entry !== false) {
self.entries.push(path.resolve(basedir, row.file || row.id));
}

self.lookupPackage(row.file, function (err, pkg) {
if (err && self.options.ignoreMissing) {
self.emit('missing', row.file, self.top);
Expand Down Expand Up @@ -130,7 +131,7 @@ Deps.prototype._flush = function () {
}
else files[w.file || w.id] = r;
});

Object.keys(files).forEach(function (key) {
var r = files[key];
var pkg = r.pkg || {};
Expand All @@ -147,7 +148,7 @@ Deps.prototype._flush = function () {
Deps.prototype.resolve = function (id, parent, cb) {
var self = this;
var opts = self.options;

if (xhas(self.cache, parent.id, 'deps', id)
&& self.cache[parent.id].deps[id]) {
var file = self.cache[parent.id].deps[id];
Expand All @@ -157,25 +158,25 @@ Deps.prototype.resolve = function (id, parent, cb) {
cb(null, file, pkg);
});
}

parent.packageFilter = function (p, x) {
var pkgdir = path.dirname(x);
if (opts.packageFilter) p = opts.packageFilter(p, x);
p.__dirname = pkgdir;

return p;
};

if (opts.extensions) parent.extensions = opts.extensions;
if (opts.modules) parent.modules = opts.modules;

self.resolver(id, parent, function onresolve (err, file, pkg, fakePath) {
if (err) return cb(err);
if (!file) return cb(new Error(
'module not found: "' + id + '" from file '
+ parent.filename
));

if (!pkg || !pkg.__dirname) {
self.lookupPackage(file, function (err, p) {
if (err) return cb(err);
Expand Down Expand Up @@ -211,25 +212,25 @@ Deps.prototype.readFile = function (file, id, pkg) {
Deps.prototype.getTransforms = function (file, pkg, opts) {
if (!opts) opts = {};
var self = this;

var isTopLevel;
if (opts.builtin || opts.inNodeModules) isTopLevel = false;
else isTopLevel = this._isTopLevel(file);

var transforms = [].concat(isTopLevel ? this.transforms : [])
.concat(getTransforms(pkg, {
globalTransform: this.globalTransforms,
transformKey: this.options.transformKey
}))
;
if (transforms.length === 0) return through();

var pending = transforms.length;
var streams = [];
var input = through();
var output = through();
var dup = duplexer(input, output);

for (var i = 0; i < transforms.length; i++) (function (i) {
makeTransform(transforms[i], function (err, trs) {
if (err) return self.emit('error', err)
Expand All @@ -238,7 +239,7 @@ Deps.prototype.getTransforms = function (file, pkg, opts) {
});
})(i);
return dup;

function done () {
var middle = combine.apply(null, streams);
middle.on('error', function (err) {
Expand All @@ -248,7 +249,7 @@ Deps.prototype.getTransforms = function (file, pkg, opts) {
});
input.pipe(middle).pipe(output);
}

function makeTransform (tr, cb) {
var trOpts = {};
if (Array.isArray(tr)) {
Expand All @@ -267,24 +268,24 @@ Deps.prototype.getTransforms = function (file, pkg, opts) {
});
}
}

function loadTransform (id, trOpts, cb) {
var params = { basedir: path.dirname(file) };
nodeResolve(id, params, function nr (err, res, again) {
if (err && again) return cb && cb(err);

if (err) {
params.basedir = pkg.__dirname;
return nodeResolve(id, params, function (e, r) {
nr(e, r, true)
});
}

if (!res) return cb(new Error(
'cannot find transform module ' + tr
+ ' while transforming ' + file
));

var r = require(res);
if (typeof r !== 'function') {
return cb(new Error(
Expand All @@ -293,7 +294,7 @@ Deps.prototype.getTransforms = function (file, pkg, opts) {
+ 'Expected a transform function.'
));
}

var trs = r(file, trOpts);
self.emit('transform', trs, file);
cb(null, trs);
Expand All @@ -305,7 +306,7 @@ Deps.prototype.walk = function (id, parent, cb) {
var self = this;
var opts = self.options;
this.pending ++;

var rec = {};
var input;
if (typeof id === 'object') {
Expand All @@ -315,7 +316,7 @@ Deps.prototype.walk = function (id, parent, cb) {
input = true;
this.inputPending ++;
}

self.resolve(id, parent, function (err, file, pkg, fakePath) {
// this is checked early because parent.modules is also modified
// by this function.
Expand All @@ -332,15 +333,15 @@ Deps.prototype.walk = function (id, parent, cb) {
self._emittedPkg[pkg.__dirname] = true;
self.emit('package', pkg);
}

if (opts.postFilter && !opts.postFilter(id, file, pkg)) {
if (--self.pending === 0) self.push(null);
if (input) --self.inputPending;
return cb && cb(null, undefined);
}
if (err && rec.source) {
file = rec.file;

var ts = self.getTransforms(file, pkg);
ts.pipe(concat(function (body) {
rec.source = body.toString('utf8');
Expand All @@ -361,7 +362,7 @@ Deps.prototype.walk = function (id, parent, cb) {
return cb && cb(null, file);
}
self.visited[file] = true;

if (rec.source) {
var ts = self.getTransforms(file, pkg);
ts.pipe(concat(function (body) {
Expand All @@ -370,10 +371,10 @@ Deps.prototype.walk = function (id, parent, cb) {
}));
return ts.end(rec.source);
}

var c = self.cache && self.cache[file];
if (c) return fromDeps(file, c.source, c.package, fakePath, Object.keys(c.deps));

self.readFile(file, id, pkg)
.pipe(self.getTransforms(fakePath || file, pkg, {
builtin: builtin,
Expand All @@ -389,13 +390,13 @@ Deps.prototype.walk = function (id, parent, cb) {
var deps = rec.noparse ? [] : self.parseDeps(file, src);
if (deps) fromDeps(file, src, pkg, fakePath, deps);
}

function fromDeps (file, src, pkg, fakePath, deps) {
var p = deps.length;
var resolved = {};

if (input) --self.inputPending;

(function resolve () {
if (self.inputPending > 0) return setTimeout(resolve);
deps.forEach(function (id) {
Expand All @@ -419,18 +420,18 @@ Deps.prototype.walk = function (id, parent, cb) {
});
if (deps.length === 0) done();
})();

function done () {
if (!rec.id) rec.id = file;
if (!rec.source) rec.source = src;
if (!rec.deps) rec.deps = resolved;
if (!rec.file) rec.file = file;

if (self.entries.indexOf(file) >= 0) {
rec.entry = true;
}
self.push(rec);

if (cb) cb(null, file);
if (-- self.pending === 0) self.push(null);
}
Expand All @@ -440,12 +441,12 @@ Deps.prototype.walk = function (id, parent, cb) {
Deps.prototype.parseDeps = function (file, src, cb) {
if (this.options.noParse === true) return [];
if (/\.json$/.test(file)) return [];

if (Array.isArray(this.options.noParse)
&& this.options.noParse.indexOf(file) >= 0) {
return [];
}

try { var deps = detective(src) }
catch (ex) {
var message = ex && ex.message ? ex.message : ex;
Expand All @@ -459,13 +460,13 @@ Deps.prototype.parseDeps = function (file, src, cb) {

Deps.prototype.lookupPackage = function (file, cb) {
var self = this;

var cached = this.pkgCache[file];
if (cached) return nextTick(cb, null, cached);
if (cached === false) return nextTick(cb, null, undefined);

var dirs = parents(path.dirname(file));

(function next () {
if (dirs.length === 0) {
self.pkgCache[file] = false;
Expand All @@ -475,17 +476,17 @@ Deps.prototype.lookupPackage = function (file, cb) {
if (dir.split(/[\\\/]/).slice(-1)[0] === 'node_modules') {
return cb(null, undefined);
}

var pkgfile = path.join(dir, 'package.json');

var cached = self.pkgCache[pkgfile];
if (cached) return nextTick(cb, null, cached);
else if (cached === false) return next();

var pcached = self.pkgFileCachePending[pkgfile];
if (pcached) return pcached.push(onpkg);
pcached = self.pkgFileCachePending[pkgfile] = [];

fs.readFile(pkgfile, function (err, src) {
if (err) return onpkg();
try { var pkg = JSON.parse(src) }
Expand All @@ -495,12 +496,12 @@ Deps.prototype.lookupPackage = function (file, cb) {
].join('')))
}
pkg.__dirname = dir;

self.pkgCache[pkgfile] = pkg;
self.pkgCache[file] = pkg;
onpkg(null, pkg);
});

function onpkg (err, pkg) {
if (self.pkgFileCachePending[pkgfile]) {
var fns = self.pkgFileCachePending[pkgfile];
Expand All @@ -516,7 +517,7 @@ Deps.prototype.lookupPackage = function (file, cb) {
}
})();
};

function getTransforms (pkg, opts) {
var trx = [];
if (opts.transformKey) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"JSONStream": "^1.0.3",
"browser-resolve": "^1.7.0",
"cached-path-relative": "^1.0.0",
"concat-stream": "~1.5.0",
"defined": "^1.0.0",
"detective": "^4.0.0",
Expand Down