module: support custom paths to require.resolve()
This commit allows custom lookup paths to be passed to require.resolve(). It also adds require.resolve.paths() which retrieves the default resolution paths. Fixes: https://github.com/nodejs/node/issues/5963 Fixes: https://github.com/nodejs/node/issues/16389 PR-URL: https://github.com/nodejs/node/pull/16397 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Wyatt Preul <wpreul@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
This commit is contained in:
parent
4997894390
commit
9c6f6b0633
@ -598,14 +598,36 @@ filename scales linearly with the number of registered extensions.
|
|||||||
In other words, adding extensions slows down the module loader and
|
In other words, adding extensions slows down the module loader and
|
||||||
should be discouraged.
|
should be discouraged.
|
||||||
|
|
||||||
#### require.resolve()
|
#### require.resolve(request[, options])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.3.0
|
added: v0.3.0
|
||||||
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/16397
|
||||||
|
description: The `paths` option is now supported.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
* `request` {string} The module path to resolve.
|
||||||
|
* `options` {Object}
|
||||||
|
* `paths` {Array} Paths to resolve module location from. If present, these
|
||||||
|
paths are used instead of the default resolution paths. Note that each of
|
||||||
|
these paths is used as a starting point for the module resolution algorithm,
|
||||||
|
meaning that the `node_modules` hierarchy is checked from this location.
|
||||||
|
* Returns: {string}
|
||||||
|
|
||||||
Use the internal `require()` machinery to look up the location of a module,
|
Use the internal `require()` machinery to look up the location of a module,
|
||||||
but rather than loading the module, just return the resolved filename.
|
but rather than loading the module, just return the resolved filename.
|
||||||
|
|
||||||
|
#### require.resolve.paths(request)
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* `request` {string} The module path whose lookup paths are being retrieved.
|
||||||
|
* Returns: {Array}
|
||||||
|
|
||||||
|
Returns an array containing the paths searched during resolution of `request`.
|
||||||
|
|
||||||
## The `module` Object
|
## The `module` Object
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.1.16
|
added: v0.1.16
|
||||||
|
@ -1899,7 +1899,7 @@ cases:
|
|||||||
[`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
|
[`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
|
||||||
[`require()`]: globals.html#globals_require
|
[`require()`]: globals.html#globals_require
|
||||||
[`require.main`]: modules.html#modules_accessing_the_main_module
|
[`require.main`]: modules.html#modules_accessing_the_main_module
|
||||||
[`require.resolve()`]: modules.html#modules_require_resolve
|
[`require.resolve()`]: modules.html#modules_require_resolve_request_options
|
||||||
[`setTimeout(fn, 0)`]: timers.html#timers_settimeout_callback_delay_args
|
[`setTimeout(fn, 0)`]: timers.html#timers_settimeout_callback_delay_args
|
||||||
[Child Process]: child_process.html
|
[Child Process]: child_process.html
|
||||||
[Cluster]: cluster.html
|
[Cluster]: cluster.html
|
||||||
|
@ -14,12 +14,18 @@ function makeRequireFunction(mod) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolve(request) {
|
function resolve(request, options) {
|
||||||
return Module._resolveFilename(request, mod);
|
return Module._resolveFilename(request, mod, false, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
require.resolve = resolve;
|
require.resolve = resolve;
|
||||||
|
|
||||||
|
function paths(request) {
|
||||||
|
return Module._resolveLookupPaths(request, mod, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve.paths = paths;
|
||||||
|
|
||||||
require.main = process.mainModule;
|
require.main = process.mainModule;
|
||||||
|
|
||||||
// Enable support to add extra extension types.
|
// Enable support to add extra extension types.
|
||||||
|
@ -484,12 +484,32 @@ function tryModuleLoad(module, filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Module._resolveFilename = function(request, parent, isMain) {
|
Module._resolveFilename = function(request, parent, isMain, options) {
|
||||||
if (NativeModule.nonInternalExists(request)) {
|
if (NativeModule.nonInternalExists(request)) {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
var paths = Module._resolveLookupPaths(request, parent, true);
|
var paths;
|
||||||
|
|
||||||
|
if (typeof options === 'object' && options !== null &&
|
||||||
|
Array.isArray(options.paths)) {
|
||||||
|
paths = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < options.paths.length; i++) {
|
||||||
|
const path = options.paths[i];
|
||||||
|
const lookupPaths = Module._resolveLookupPaths(path, parent, true);
|
||||||
|
|
||||||
|
if (!paths.includes(path))
|
||||||
|
paths.push(path);
|
||||||
|
|
||||||
|
for (var j = 0; j < lookupPaths.length; j++) {
|
||||||
|
if (!paths.includes(lookupPaths[j]))
|
||||||
|
paths.push(lookupPaths[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paths = Module._resolveLookupPaths(request, parent, true);
|
||||||
|
}
|
||||||
|
|
||||||
// look up the filename first, since that's the cache key.
|
// look up the filename first, since that's the cache key.
|
||||||
var filename = Module._findPath(request, paths, isMain);
|
var filename = Module._findPath(request, paths, isMain);
|
||||||
|
55
test/fixtures/require-resolve.js
vendored
Normal file
55
test/fixtures/require-resolve.js
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
const path = require('path');
|
||||||
|
const nodeModules = path.join(__dirname, 'node_modules');
|
||||||
|
const nestedNodeModules = path.join(__dirname, 'node_modules', 'node_modules');
|
||||||
|
const nestedIndex = path.join(__dirname, 'nested-index');
|
||||||
|
|
||||||
|
// Test the default behavior.
|
||||||
|
assert.strictEqual(
|
||||||
|
require.resolve('bar'),
|
||||||
|
path.join(nodeModules, 'bar.js')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Verify that existing paths are removed.
|
||||||
|
assert.throws(() => {
|
||||||
|
require.resolve('bar', { paths: [] })
|
||||||
|
}, /^Error: Cannot find module 'bar'$/);
|
||||||
|
|
||||||
|
// Verify that resolution path can be overwritten.
|
||||||
|
{
|
||||||
|
// three.js cannot be loaded from this file by default.
|
||||||
|
assert.throws(() => {
|
||||||
|
require.resolve('three')
|
||||||
|
}, /^Error: Cannot find module 'three'$/);
|
||||||
|
|
||||||
|
// However, it can be found if resolution contains the nested index directory.
|
||||||
|
assert.strictEqual(
|
||||||
|
require.resolve('three', { paths: [nestedIndex] }),
|
||||||
|
path.join(nestedIndex, 'three.js')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Resolution from nested index directory also checks node_modules.
|
||||||
|
assert.strictEqual(
|
||||||
|
require.resolve('bar', { paths: [nestedIndex] }),
|
||||||
|
path.join(nodeModules, 'bar.js')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the default paths can be used and modified.
|
||||||
|
{
|
||||||
|
const paths = require.resolve.paths('bar');
|
||||||
|
|
||||||
|
assert.strictEqual(paths[0], nodeModules);
|
||||||
|
assert.strictEqual(
|
||||||
|
require.resolve('bar', { paths }),
|
||||||
|
path.join(nodeModules, 'bar.js')
|
||||||
|
);
|
||||||
|
|
||||||
|
paths.unshift(nestedNodeModules);
|
||||||
|
assert.strictEqual(
|
||||||
|
require.resolve('bar', { paths }),
|
||||||
|
path.join(nestedNodeModules, 'bar.js')
|
||||||
|
);
|
||||||
|
}
|
@ -35,4 +35,5 @@ assert.strictEqual(
|
|||||||
require.resolve(fixtures.path('nested-index', 'one').toLowerCase()));
|
require.resolve(fixtures.path('nested-index', 'one').toLowerCase()));
|
||||||
assert.strictEqual('path', require.resolve('path'));
|
assert.strictEqual('path', require.resolve('path'));
|
||||||
|
|
||||||
console.log('ok');
|
// Test configurable resolve() paths.
|
||||||
|
require(fixtures.path('require-resolve.js'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user