From 2811e40becdefe1f736818a002de7a1415a40458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Sun, 14 Jun 2026 23:26:32 +0200 Subject: [PATCH 1/2] loader: enforce path normalization before lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maƫl Nison --- lib/internal/modules/package_map.js | 2 ++ test/parallel/test-require-package-map.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/internal/modules/package_map.js b/lib/internal/modules/package_map.js index 0bee02a20789a1..38e7e12206c9ce 100644 --- a/lib/internal/modules/package_map.js +++ b/lib/internal/modules/package_map.js @@ -140,6 +140,8 @@ class PackageMap { * @returns {string|null} */ #getKeyForPath(filePath) { + filePath = pathResolve(filePath); + const cached = this.#pathToKeyCache.get(filePath); if (cached !== undefined) { return cached; } diff --git a/test/parallel/test-require-package-map.js b/test/parallel/test-require-package-map.js index b65a8f4db5a7da..94d83a4c790599 100644 --- a/test/parallel/test-require-package-map.js +++ b/test/parallel/test-require-package-map.js @@ -79,6 +79,7 @@ describe('CJS: --experimental-package-map', { concurrency: !process.env.TEST_PAR assert.match(stdout, /dep-b using dep-a-value/); assert.strictEqual(status, 0, stderr); }); + }); describe('resolution boundaries', () => { @@ -300,6 +301,22 @@ describe('CJS: --experimental-package-map', { concurrency: !process.env.TEST_PAR describe('longest path wins', () => { const longestPathMap = fixtures.path('package-map/package-map-longest-path.json'); + it('resolves from createRequire() paths with mixed separators', () => { + const { status, stdout, stderr } = spawnSync(process.execPath, [ + '--no-warnings', + '--experimental-package-map', longestPathMap, + '-e', + `const { createRequire } = require('node:module'); const req = createRequire(process.cwd() + '/node_modules/inner/index.js'); const dep = req('dep-a'); console.log(dep.default);`, + ], { + cwd: fixtures.path('package-map/root'), + encoding: 'utf8', + }); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /dep-a-value/); + assert.strictEqual(status, 0, stderr); + }); + it('resolves nested package using its own dependencies, not the parent', () => { // Inner lives at ./root/node_modules/inner which is inside root's // path (./root). The longest matching path should win, so code in From 77b378e8b4836f103ac963dee7564d76bda52d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Sun, 14 Jun 2026 23:34:55 +0200 Subject: [PATCH 2/2] Update test-require-package-map.js --- test/parallel/test-require-package-map.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/parallel/test-require-package-map.js b/test/parallel/test-require-package-map.js index 94d83a4c790599..87786d62738a41 100644 --- a/test/parallel/test-require-package-map.js +++ b/test/parallel/test-require-package-map.js @@ -79,7 +79,6 @@ describe('CJS: --experimental-package-map', { concurrency: !process.env.TEST_PAR assert.match(stdout, /dep-b using dep-a-value/); assert.strictEqual(status, 0, stderr); }); - }); describe('resolution boundaries', () => {