From a73469663de0c7360b0ba0e01126e899c82376aa Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Mon, 22 Oct 2018 20:42:53 +0200 Subject: [PATCH 1/6] module: allow passing a directory to createRequireFromPath Fixes: https://github.com/nodejs/node/issues/23710 --- lib/internal/modules/cjs/loader.js | 12 +++++++++--- .../test-module-create-require-from-directory.js | 12 ++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-module-create-require-from-directory.js diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 96b5e8b7b881b6..2e81e575da307c 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -825,9 +825,15 @@ Module.runMain = function() { }; Module.createRequireFromPath = (filename) => { - const m = new Module(filename); - m.filename = filename; - m.paths = Module._nodeModulePaths(path.dirname(filename)); + // Allow a directory to be passed as the filename + const proxyPath = filename.endsWith('/') ? + path.join(filename, 'noop.js') : + filename; + + const m = new Module(proxyPath); + m.filename = proxyPath; + + m.paths = Module._nodeModulePaths(path.dirname(proxyPath)); return makeRequireFunction(m); }; diff --git a/test/parallel/test-module-create-require-from-directory.js b/test/parallel/test-module-create-require-from-directory.js new file mode 100644 index 00000000000000..8cee533819486d --- /dev/null +++ b/test/parallel/test-module-create-require-from-directory.js @@ -0,0 +1,12 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const { createRequireFromPath } = require('module'); + +const p = path.join(path.resolve(__dirname, '..', 'fixtures'), '/'); + +const req = createRequireFromPath(p); +assert.strictEqual(req('./baz'), 'perhaps I work'); From 676cc00ee0337ece577173eb5e2eb61e01396f2d Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Mon, 22 Oct 2018 23:03:32 +0200 Subject: [PATCH 2/6] module: fix windows path separators --- lib/internal/modules/cjs/loader.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 2e81e575da307c..3fe092cc8d9994 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -826,7 +826,11 @@ Module.runMain = function() { Module.createRequireFromPath = (filename) => { // Allow a directory to be passed as the filename - const proxyPath = filename.endsWith('/') ? + const normalized = path.win32.normalize(filename); + const trailingSlash = normalized.charCodeAt(normalized.length - 1) === + CHAR_BACKWARD_SLASH; + + const proxyPath = trailingSlash ? path.join(filename, 'noop.js') : filename; From c2eff1160a5361cf5ebe0ac3176c5d8c1e182a2f Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Mon, 22 Oct 2018 23:10:12 +0200 Subject: [PATCH 3/6] test: make test-module-create-require-from-directory pass on Windows --- test/parallel/test-module-create-require-from-directory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-module-create-require-from-directory.js b/test/parallel/test-module-create-require-from-directory.js index 8cee533819486d..04b6255395e846 100644 --- a/test/parallel/test-module-create-require-from-directory.js +++ b/test/parallel/test-module-create-require-from-directory.js @@ -6,7 +6,7 @@ const path = require('path'); const { createRequireFromPath } = require('module'); -const p = path.join(path.resolve(__dirname, '..', 'fixtures'), '/'); +const p = path.join(path.resolve(__dirname, '..', 'fixtures'), path.sep); const req = createRequireFromPath(p); assert.strictEqual(req('./baz'), 'perhaps I work'); From 2b1f48e01f26b67877748aa7481299e868cf7460 Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Wed, 28 Nov 2018 16:30:58 +0100 Subject: [PATCH 4/6] test: add a negative test to test-module-create-require-from-directory --- .../parallel/test-module-create-require-from-directory.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-module-create-require-from-directory.js b/test/parallel/test-module-create-require-from-directory.js index 04b6255395e846..f043adacf994d8 100644 --- a/test/parallel/test-module-create-require-from-directory.js +++ b/test/parallel/test-module-create-require-from-directory.js @@ -6,7 +6,13 @@ const path = require('path'); const { createRequireFromPath } = require('module'); -const p = path.join(path.resolve(__dirname, '..', 'fixtures'), path.sep); +const fixPath = path.resolve(__dirname, '..', 'fixtures'); +const p = path.join(fixPath, path.sep); const req = createRequireFromPath(p); +const reqFromNotDir = createRequireFromPath(fixPath); + assert.strictEqual(req('./baz'), 'perhaps I work'); +assert.throws(() => { + reqFromNotDir('./baz'); +}, { code: 'MODULE_NOT_FOUND' }); From 59427473434d007911ba3d3152a5a202b2a260a3 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Thu, 25 Apr 2019 02:50:13 -0400 Subject: [PATCH 5/6] fixup: doc change --- doc/api/modules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/modules.md b/doc/api/modules.md index d52d4ddac5f32e..8638b137ade732 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -916,7 +916,7 @@ added: v10.12.0 ```js const { createRequireFromPath } = require('module'); -const requireUtil = createRequireFromPath('../src/utils'); +const requireUtil = createRequireFromPath('../src/utils/'); // Require `../src/utils/some-tool` requireUtil('./some-tool'); From 9ec4cb8d607945be44ddf7647382b0d40cbf3db4 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Tue, 30 Apr 2019 10:48:22 -0700 Subject: [PATCH 6/6] fixup: notes from review --- lib/internal/modules/cjs/loader.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 3fe092cc8d9994..5df34cb3f022b4 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -826,9 +826,8 @@ Module.runMain = function() { Module.createRequireFromPath = (filename) => { // Allow a directory to be passed as the filename - const normalized = path.win32.normalize(filename); - const trailingSlash = normalized.charCodeAt(normalized.length - 1) === - CHAR_BACKWARD_SLASH; + const trailingSlash = + filename.endsWith(path.sep) || path.sep !== '/' && filename.endsWith('\\'); const proxyPath = trailingSlash ? path.join(filename, 'noop.js') : @@ -837,7 +836,7 @@ Module.createRequireFromPath = (filename) => { const m = new Module(proxyPath); m.filename = proxyPath; - m.paths = Module._nodeModulePaths(path.dirname(proxyPath)); + m.paths = Module._nodeModulePaths(m.path); return makeRequireFunction(m); };