From 22292f3ba4d2b23a65de9527a88b0442f1c689f2 Mon Sep 17 00:00:00 2001 From: Ling Samuel Date: Wed, 1 Apr 2020 22:19:51 +0800 Subject: [PATCH 1/3] esm: resolve main from package.json when importing from directory --- lib/internal/modules/esm/resolve.js | 25 ++++++++++++++++++- test/es-module/test-esm-specifiers.mjs | 6 +++++ .../package-with-exports/exports_main.js | 3 +++ .../package-with-exports/package.json | 6 +++++ .../package-with-main/main.js | 3 +++ .../package-with-main/package.json | 3 +++ 6 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/es-module-specifiers/package-with-exports/exports_main.js create mode 100644 test/fixtures/es-module-specifiers/package-with-exports/package.json create mode 100644 test/fixtures/es-module-specifiers/package-with-main/main.js create mode 100644 test/fixtures/es-module-specifiers/package-with-main/package.json diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 730c815b8435f0..6440156c33a0b6 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -587,12 +587,35 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { return false; } +function resolveRelativePackage(specifier /* string */, base /* URL */) { + const resolved = new URL(specifier, base); + const stat = tryStatSync(resolved); + if (stat.isDirectory()) { + let packageJSONPath; + if (!StringPrototypeEndsWith(resolved.pathname, '/')) { + packageJSONPath = `${resolved.pathname}/package.json`; + } else { + packageJSONPath = `${resolved.pathname}package.json`; + } + const packageJSONUrl = new URL(packageJSONPath, base); + packageJSONPath = fileURLToPath(packageJSONUrl); + const packageConfig = getPackageConfig(packageJSONPath, base); + return packageMainResolve(packageJSONUrl, packageConfig, base); + } + return new URL(specifier, base); +} + function moduleResolve(specifier /* string */, base /* URL */) { /* -> URL */ // Order swapped from spec for minor perf gain. // Ok since relative URLs cannot parse as URLs. let resolved; if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { - resolved = new URL(specifier, base); + if (getOptionValue('--experimental-specifier-resolution') === 'node') { + // experimental-specifier-resolution also allows importing from directory + resolved = resolveRelativePackage(specifier, base); + } else { + resolved = new URL(specifier, base); + } } else { try { resolved = new URL(specifier); diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs index 5e436f21b74cc6..da3b3a2432488c 100644 --- a/test/es-module/test-esm-specifiers.mjs +++ b/test/es-module/test-esm-specifiers.mjs @@ -9,12 +9,18 @@ import { fileURLToPath } from 'url'; import commonjs from '../fixtures/es-module-specifiers/package-type-commonjs'; // esm index.js import module from '../fixtures/es-module-specifiers/package-type-module'; +// esm main.js +import pkg_main from '../fixtures/es-module-specifiers/package-with-main'; +// esm exports_main.js +import pkg_export from '../fixtures/es-module-specifiers/package-with-exports'; // Notice the trailing slash import success, { explicit, implicit, implicitModule, getImplicitCommonjs } from '../fixtures/es-module-specifiers/'; assert.strictEqual(commonjs, 'commonjs'); assert.strictEqual(module, 'module'); +assert.strictEqual(pkg_main, 'package-with-main'); +assert.strictEqual(pkg_export, 'package-with-exports'); assert.strictEqual(success, 'success'); assert.strictEqual(explicit, 'esm'); assert.strictEqual(implicit, 'cjs'); diff --git a/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js b/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js new file mode 100644 index 00000000000000..042f23d7dc03fc --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js @@ -0,0 +1,3 @@ +const identifier = 'package-with-exports'; +console.log(identifier); +module.exports = identifier; diff --git a/test/fixtures/es-module-specifiers/package-with-exports/package.json b/test/fixtures/es-module-specifiers/package-with-exports/package.json new file mode 100644 index 00000000000000..41b46dbac95c48 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-with-exports/package.json @@ -0,0 +1,6 @@ +{ + "main": "main.js", + "exports": { + ".": "./exports_main.js" + } +} diff --git a/test/fixtures/es-module-specifiers/package-with-main/main.js b/test/fixtures/es-module-specifiers/package-with-main/main.js new file mode 100644 index 00000000000000..e3cbdbe728c053 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-with-main/main.js @@ -0,0 +1,3 @@ +const identifier = 'package-with-main'; +console.log(identifier); +module.exports = identifier; diff --git a/test/fixtures/es-module-specifiers/package-with-main/package.json b/test/fixtures/es-module-specifiers/package-with-main/package.json new file mode 100644 index 00000000000000..c13b8cf6acfd33 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-with-main/package.json @@ -0,0 +1,3 @@ +{ + "main": "main.js" +} From fc5a30d8612d98c81bfc1b92bbc9ce96a374f92a Mon Sep 17 00:00:00 2001 From: Ling Samuel Date: Thu, 2 Apr 2020 14:52:05 +0800 Subject: [PATCH 2/3] test: remove console.log --- .../es-module-specifiers/package-with-exports/exports_main.js | 1 - test/fixtures/es-module-specifiers/package-with-main/main.js | 1 - 2 files changed, 2 deletions(-) diff --git a/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js b/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js index 042f23d7dc03fc..196c5b4c7f1ef9 100644 --- a/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js +++ b/test/fixtures/es-module-specifiers/package-with-exports/exports_main.js @@ -1,3 +1,2 @@ const identifier = 'package-with-exports'; -console.log(identifier); module.exports = identifier; diff --git a/test/fixtures/es-module-specifiers/package-with-main/main.js b/test/fixtures/es-module-specifiers/package-with-main/main.js index e3cbdbe728c053..c335f303944136 100644 --- a/test/fixtures/es-module-specifiers/package-with-main/main.js +++ b/test/fixtures/es-module-specifiers/package-with-main/main.js @@ -1,3 +1,2 @@ const identifier = 'package-with-main'; -console.log(identifier); module.exports = identifier; From 7f8fcbbbe4a12a82cb1488c82b2346faa70a37f0 Mon Sep 17 00:00:00 2001 From: Ling Samuel Date: Thu, 2 Apr 2020 14:53:16 +0800 Subject: [PATCH 3/3] esm: fix a redundant new call --- lib/internal/modules/esm/resolve.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 6440156c33a0b6..9a2e081b201065 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -602,7 +602,7 @@ function resolveRelativePackage(specifier /* string */, base /* URL */) { const packageConfig = getPackageConfig(packageJSONPath, base); return packageMainResolve(packageJSONUrl, packageConfig, base); } - return new URL(specifier, base); + return resolved; } function moduleResolve(specifier /* string */, base /* URL */) { /* -> URL */