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
|
||||
should be discouraged.
|
||||
|
||||
#### require.resolve()
|
||||
#### require.resolve(request[, options])
|
||||
<!-- YAML
|
||||
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,
|
||||
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
|
||||
<!-- YAML
|
||||
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
|
||||
[`require()`]: globals.html#globals_require
|
||||
[`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
|
||||
[Child Process]: child_process.html
|
||||
[Cluster]: cluster.html
|
||||
|
@ -14,12 +14,18 @@ function makeRequireFunction(mod) {
|
||||
}
|
||||
}
|
||||
|
||||
function resolve(request) {
|
||||
return Module._resolveFilename(request, mod);
|
||||
function resolve(request, options) {
|
||||
return Module._resolveFilename(request, mod, false, options);
|
||||
}
|
||||
|
||||
require.resolve = resolve;
|
||||
|
||||
function paths(request) {
|
||||
return Module._resolveLookupPaths(request, mod, true);
|
||||
}
|
||||
|
||||
resolve.paths = paths;
|
||||
|
||||
require.main = process.mainModule;
|
||||
|
||||
// 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)) {
|
||||
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.
|
||||
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()));
|
||||
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