From 2f512e32a72190cdeb59105ae563fd7570d324cb Mon Sep 17 00:00:00 2001 From: cjihrig Date: Tue, 7 May 2019 11:31:29 -0400 Subject: [PATCH] module: handle relative paths in resolve paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for relative paths in require.resolve()'s paths option. PR-URL: https://github.com/nodejs/node/pull/27598 Fixes: https://github.com/nodejs/node/issues/27583 Reviewed-By: Rich Trott Reviewed-By: Daniel Bevenius Reviewed-By: Michaƫl Zasso --- lib/internal/modules/cjs/loader.js | 25 ++++++++++++++--------- test/fixtures/require-resolve.js | 32 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 91b89860e7b66d..d02c632bcee5a7 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -575,18 +575,25 @@ Module._resolveFilename = function(request, parent, isMain, options) { if (typeof options === 'object' && options !== null && Array.isArray(options.paths)) { - const fakeParent = new Module('', null); + const isRelative = request.startsWith('./') || request.startsWith('../') || + (isWindows && request.startsWith('.\\') || request.startsWith('..\\')); - paths = []; + if (isRelative) { + paths = options.paths; + } else { + const fakeParent = new Module('', null); - for (var i = 0; i < options.paths.length; i++) { - const path = options.paths[i]; - fakeParent.paths = Module._nodeModulePaths(path); - const lookupPaths = Module._resolveLookupPaths(request, fakeParent); + paths = []; - for (var j = 0; j < lookupPaths.length; j++) { - if (!paths.includes(lookupPaths[j])) - paths.push(lookupPaths[j]); + for (var i = 0; i < options.paths.length; i++) { + const path = options.paths[i]; + fakeParent.paths = Module._nodeModulePaths(path); + const lookupPaths = Module._resolveLookupPaths(request, fakeParent); + + for (var j = 0; j < lookupPaths.length; j++) { + if (!paths.includes(lookupPaths[j])) + paths.push(lookupPaths[j]); + } } } } else { diff --git a/test/fixtures/require-resolve.js b/test/fixtures/require-resolve.js index aa496e5eb66f70..a398e59cfa496f 100644 --- a/test/fixtures/require-resolve.js +++ b/test/fixtures/require-resolve.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const path = require('path'); const nodeModules = path.join(__dirname, 'node_modules'); @@ -54,3 +54,33 @@ assert.throws(() => { path.join(nodeModules, 'bar.js') ); } + +// Verify that relative request paths work properly. +{ + const searchIn = './' + path.relative(process.cwd(), nestedIndex); + + // Search in relative paths. + assert.strictEqual( + require.resolve('./three.js', { paths: [searchIn] }), + path.join(nestedIndex, 'three.js') + ); + + // Search in absolute paths. + assert.strictEqual( + require.resolve('./three.js', { paths: [nestedIndex] }), + path.join(nestedIndex, 'three.js') + ); + + // Repeat the same tests with Windows slashes in the request path. + if (common.isWindows) { + assert.strictEqual( + require.resolve('.\\three.js', { paths: [searchIn] }), + path.join(nestedIndex, 'three.js') + ); + + assert.strictEqual( + require.resolve('.\\three.js', { paths: [nestedIndex] }), + path.join(nestedIndex, 'three.js') + ); + } +}