diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 2cac6f2d450fab..619b9531e9037b 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -307,8 +307,10 @@ function finalizeResolution(resolved, base, preserveSymlinks) { resolved.pathname, fileURLToPath(base), 'module'); } } - - path = file; + // If `preserveSymlinks` is false, `resolved` is returned and `path` + // is used only to check that the resolved path exists. + resolved = file; + path = fileURLToPath(resolved); } const stats = tryStatSync(StringPrototypeEndsWith(path, '/') ? diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs index 692db968141997..a9419e90ced097 100644 --- a/test/es-module/test-esm-specifiers.mjs +++ b/test/es-module/test-esm-specifiers.mjs @@ -36,6 +36,37 @@ describe('ESM: specifier-resolution=node', { concurrency: true }, () => { strictEqual(stdout, ''); strictEqual(code, 0); }); + it('should work with --preserve-symlinks', async () => { + const { code, stderr, stdout } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-specifier-resolution=node', + '--preserve-symlinks', + '--input-type=module', + '--eval', + [ + 'import { strictEqual } from "node:assert";', + // CommonJS index.js + `import commonjs from ${JSON.stringify(fixtures.fileURL('es-module-specifiers/package-type-commonjs'))};`, + // ESM index.js + `import module from ${JSON.stringify(fixtures.fileURL('es-module-specifiers/package-type-module'))};`, + // Directory entry with main.js + `import main from ${JSON.stringify(fixtures.fileURL('es-module-specifiers/dir-with-main'))};`, + // Notice the trailing slash + `import success, { explicit, implicit, implicitModule } from ${JSON.stringify(fixtures.fileURL('es-module-specifiers/'))};`, + 'strictEqual(commonjs, "commonjs");', + 'strictEqual(module, "module");', + 'strictEqual(main, "main");', + 'strictEqual(success, "success");', + 'strictEqual(explicit, "esm");', + 'strictEqual(implicit, "cjs");', + 'strictEqual(implicitModule, "cjs");', + ].join('\n'), + ]); + + strictEqual(stderr, ''); + strictEqual(stdout, ''); + strictEqual(code, 0); + }); it('should throw when the file doesn\'t exist', async () => { const { code, stderr, stdout } = await spawnPromisified(execPath, [