Skip to content

Commit 9ea8b16

Browse files
committed
[Refactor] node-modules-paths: Change paths function option to receive a thunk for node modules resolution paths
- this would be a breaking change, but the “paths as function” option has not yet been released.
1 parent d5dc919 commit 9ea8b16

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

lib/node-modules-paths.js

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,7 @@ var path = require('path');
22
var fs = require('fs');
33
var parse = path.parse || require('path-parse');
44

5-
module.exports = function nodeModulesPaths(start, opts, request) {
6-
var modules = opts && opts.moduleDirectory
7-
? [].concat(opts.moduleDirectory)
8-
: ['node_modules'];
9-
10-
// ensure that `start` is an absolute path at this point, resolving against the process' current working directory
11-
var absoluteStart = path.resolve(start);
12-
13-
if (!opts || !opts.preserveSymlinks) {
14-
try {
15-
absoluteStart = fs.realpathSync(absoluteStart);
16-
} catch (err) {
17-
if (err.code !== 'ENOENT') {
18-
throw err;
19-
}
20-
}
21-
}
22-
5+
var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) {
236
var prefix = '/';
247
if ((/^([A-Za-z]:)/).test(absoluteStart)) {
258
prefix = '';
@@ -34,17 +17,40 @@ module.exports = function nodeModulesPaths(start, opts, request) {
3417
parsed = parse(parsed.dir);
3518
}
3619

37-
var dirs = paths.reduce(function (dirs, aPath) {
20+
return paths.reduce(function (dirs, aPath) {
3821
return dirs.concat(modules.map(function (moduleDir) {
3922
return path.join(prefix, aPath, moduleDir);
4023
}));
4124
}, []);
25+
};
4226

43-
if (!opts || !opts.paths) {
44-
return dirs;
27+
module.exports = function nodeModulesPaths(start, opts, request) {
28+
var modules = opts && opts.moduleDirectory
29+
? [].concat(opts.moduleDirectory)
30+
: ['node_modules'];
31+
32+
// ensure that `start` is an absolute path at this point, resolving against the process' current working directory
33+
var absoluteStart = path.resolve(start);
34+
35+
if (!opts || !opts.preserveSymlinks) {
36+
try {
37+
absoluteStart = fs.realpathSync(absoluteStart);
38+
} catch (err) {
39+
if (err.code !== 'ENOENT') {
40+
throw err;
41+
}
42+
}
4543
}
46-
if (typeof opts.paths === 'function') {
47-
return dirs.concat(opts.paths(request, absoluteStart, opts));
44+
45+
if (opts && typeof opts.paths === 'function') {
46+
return opts.paths(
47+
request,
48+
absoluteStart,
49+
function () { return getNodeModulesDirs(absoluteStart, modules); },
50+
opts
51+
);
4852
}
49-
return dirs.concat(opts.paths);
53+
54+
var dirs = getNodeModulesDirs(absoluteStart, modules);
55+
return opts && opts.paths ? dirs.concat(opts.paths) : dirs;
5056
};

readme.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ options are:
7777
For advanced users, `paths` can also be a `opts.paths(request, start, opts)` function
7878
* request - the import specifier being resolved
7979
* start - lookup path
80+
* getNodeModulesDirs - a thunk (no-argument function) that returns the paths using standard `node_modules` resolution
8081
* opts - the resolution options
8182

8283
* opts.moduleDirectory - directory (or directories) in which to recursively look for modules. default: `"node_modules"`

test/node-modules-paths.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ test('node-modules-paths', function (t) {
6565
});
6666

6767
t.test('with paths=function option', function (t) {
68-
var paths = function paths(request, absoluteStart, opts) {
69-
return [path.join(absoluteStart, 'not node modules', request)];
68+
var paths = function paths(request, absoluteStart, getNodeModulesDirs, opts) {
69+
return getNodeModulesDirs().concat(path.join(absoluteStart, 'not node modules', request));
7070
};
7171

7272
var start = path.join(__dirname, 'resolver');
@@ -77,6 +77,16 @@ test('node-modules-paths', function (t) {
7777
t.end();
7878
});
7979

80+
t.test('with paths=function skipping node modules resolution', function (t) {
81+
var paths = function paths(request, absoluteStart, getNodeModulesDirs, opts) {
82+
return [];
83+
};
84+
var start = path.join(__dirname, 'resolver');
85+
var dirs = nodeModulesPaths(start, { paths: paths });
86+
t.deepEqual(dirs, [], 'no node_modules was computed');
87+
t.end();
88+
});
89+
8090
t.test('with moduleDirectory option', function (t) {
8191
var start = path.join(__dirname, 'resolver');
8292
var moduleDirectory = 'not node modules';

0 commit comments

Comments
 (0)