Skip to content

Commit e8c9c43

Browse files
authored
module: allow subpath imports that start with #/
It's a common ecosystem pattern to map a source root directory to `@/` but it requires special tooling support. This turns `#/*` into a more realistic alternative for that pattern. PR-URL: #60864 Reviewed-By: Guy Bedford <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Claudio Wunder <[email protected]> Reviewed-By: Zeyu "Alex" Yang <[email protected]>
1 parent cb0eb58 commit e8c9c43

File tree

6 files changed

+12
-5
lines changed

6 files changed

+12
-5
lines changed

doc/api/esm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ Note: This function is directly invoked by the CommonJS resolution algorithm.
11021102
Note: This function is directly invoked by the CommonJS resolution algorithm.
11031103
11041104
> 1. Assert: _specifier_ begins with _"#"_.
1105-
> 2. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then
1105+
> 2. If _specifier_ is exactly equal to _"#"_, then
11061106
> 1. Throw an _Invalid Module Specifier_ error.
11071107
> 3. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_parentURL_).
11081108
> 4. If _packageURL_ is not **null**, then

doc/api/packages.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ can be written:
527527
added:
528528
- v14.6.0
529529
- v12.19.0
530+
changes:
531+
- version: REPLACEME
532+
pr-url: https://github.com/nodejs/node/pull/60864
533+
description: Allow subpath imports that start with `#/`.
530534
-->
531535

532536
In addition to the [`"exports"`][] field, there is a package `"imports"` field

lib/internal/modules/esm/resolve.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,7 @@ function patternKeyCompare(a, b) {
692692
* @returns {URL} The resolved import URL.
693693
*/
694694
function packageImportsResolve(name, base, conditions) {
695-
if (name === '#' || StringPrototypeStartsWith(name, '#/') ||
696-
StringPrototypeEndsWith(name, '/')) {
695+
if (name === '#' || StringPrototypeEndsWith(name, '/')) {
697696
const reason = 'is not a valid internal imports specifier name';
698697
throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base));
699698
}

test/es-module/test-esm-imports.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const { requireImport, importImport } = importer;
1515
const internalImports = new Map([
1616
// Base case
1717
['#test', maybeWrapped({ default: 'test' })],
18+
// Root wildcard import
19+
['#/foo', maybeWrapped({ default: 'foo' })],
20+
// Explicit #/ mapping
21+
['#/initialslash', maybeWrapped({ default: 'test' })],
1822
// import / require conditions
1923
['#branch', maybeWrapped({ default: isRequire ? 'requirebranch' : 'importbranch' })],
2024
// Subpath imports
@@ -64,8 +68,6 @@ const { requireImport, importImport } = importer;
6468
['#external/subpath/x%5Cy', 'must not include encoded "/" or "\\"'],
6569
// Target must have a name
6670
['#', '#'],
67-
// Initial slash target must have a leading name
68-
['#/initialslash', '#/initialslash'],
6971
// Percent-encoded target paths
7072
['#encodedslash', 'must not include encoded "/" or "\\"'],
7173
['#encodedbackslash', 'must not include encoded "/" or "\\"'],

test/fixtures/es-modules/pkgimports/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"imports": {
3+
"#/*": "./src/*.js",
34
"#branch": {
45
"import": "./importbranch.js",
56
"require": "./requirebranch.js"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'foo';

0 commit comments

Comments
 (0)