GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — loader: implement package maps · nodejs/node@fbb108b

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • doc
    • api
      • cli.md
      • errors.md
      • esm.md
      • modules.md
      • packages.md
    • node.1
  • lib/internal
    • errors.js
    • modules
      • cjs
        • loader.js
      • esm
        • resolve.js
      • package_map.js
  • src
    • node_options.cc
    • node_options.h
  • test
    • es-module
      • test-esm-package-map-basic.mjs
      • test-esm-package-map-boundaries.mjs
      • test-esm-package-map-errors.mjs
      • test-esm-package-map-exports.mjs
      • test-esm-package-map-flag.mjs
      • test-esm-package-map-paths.mjs
      • test-esm-package-map-symlink.mjs
      • test-esm-package-map-version-fork.mjs
    • fixtures/package-map
      • app-18
        • index.js
        • package.json
      • app-19
        • index.js
        • package.json
      • component-lib
        • index.js
        • package.json
      • dep with spaces
        • index.js
        • package.json
      • dep-a
        • index.cjs
        • index.js
        • lib
          • util.js
        • package.json
      • dep-b
        • index.js
        • package.json
      • nameless-pkg
        • index.js
      • nested-project
        • package-map-external-deps.json
        • src
          • .gitkeep
      • not-a-dep
        • index.js
        • package.json
      • package-map-duplicate-path.json
      • package-map-https-path.json
      • package-map-invalid-schema.json
      • package-map-invalid-syntax.json
      • package-map-longest-path.json
      • package-map-missing-dep.json
      • package-map-path-prefix.json
      • package-map-url-encoded-spaces.json
      • package-map-version-fork.json
      • package-map.json
      • pkg-other
        • index.js
        • package.json
      • pkg
        • index.cjs
        • index.js
        • package.json
      • react-18
        • index.js
        • package.json
      • react-19
        • index.js
        • package.json
      • root
        • index.js
        • node_modules/inner
          • index.cjs
          • index.js
          • package.json
        • package.json
    • parallel
      • test-bootstrap-modules.js
      • test-package-map-cli.js
      • test-require-package-map.js

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/cli.md‎

Copy file name to clipboardExpand all lines: doc/api/cli.md
+23Lines changed: 23 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,27 @@ added:
13061306
13071307
Enable experimental support for the network inspection with Chrome DevTools.
13081308

1309+
### `--experimental-package-map=<path>`
1310+
1311+
<!-- YAML
1312+
added: REPLACEME
1313+
-->
1314+
1315+
> Stability: 1 - Experimental
1316+
1317+
Enable experimental package map resolution. The `path` argument specifies the
1318+
location of a JSON configuration file that defines package resolution mappings.
1319+
1320+
```bash
1321+
node --experimental-package-map=./package-map.json app.js
1322+
```
1323+
1324+
When enabled, bare specifier resolution consults the package map for resolution.
1325+
This allows explicit control over which packages can import which dependencies.
1326+
1327+
See [Package maps][] for details on the configuration file format and
1328+
resolution algorithm.
1329+
13091330
### `--experimental-print-required-tla`
13101331

13111332
<!-- YAML
@@ -3753,6 +3774,7 @@ one is included in the list below.
37533774
* `--experimental-json-modules`
37543775
* `--experimental-loader`
37553776
* `--experimental-modules`
3777+
* `--experimental-package-map`
37563778
* `--experimental-print-required-tla`
37573779
* `--experimental-quic`
37583780
* `--experimental-require-module`
@@ -4349,6 +4371,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
43494371
[Navigator API]: globals.md#navigator
43504372
[Node.js issue tracker]: https://github.com/nodejs/node/issues
43514373
[OSSL_PROVIDER-legacy]: https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
4374+
[Package maps]: packages.md#package-maps
43524375
[Permission Model]: permissions.md#permission-model
43534376
[REPL]: repl.md
43544377
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
Collapse file

‎doc/api/errors.md‎

Copy file name to clipboardExpand all lines: doc/api/errors.md
+72Lines changed: 72 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -2537,6 +2537,77 @@ A given value is out of the accepted range.
25372537
The `package.json` [`"imports"`][] field does not define the given internal
25382538
package specifier mapping.
25392539

2540+
<a id="ERR_PACKAGE_MAP_EXTERNAL_FILE"></a>
2541+
2542+
### `ERR_PACKAGE_MAP_EXTERNAL_FILE`
2543+
2544+
<!-- YAML
2545+
added: REPLACEME
2546+
-->
2547+
2548+
A module attempted to resolve a bare specifier using the [package map][], but
2549+
the importing file is not located within any package defined in the map.
2550+
2551+
```console
2552+
$ node --experimental-package-map=./package-map.json /tmp/script.js
2553+
Error [ERR_PACKAGE_MAP_EXTERNAL_FILE]: Cannot resolve "dep-a" from "/tmp/script.js": file is not within any package defined in /path/to/package-map.json
2554+
```
2555+
2556+
To fix this error, ensure the importing file is inside one of the package
2557+
directories listed in the package map, or add a new package entry whose `url`
2558+
covers the importing file.
2559+
2560+
<a id="ERR_PACKAGE_MAP_INVALID"></a>
2561+
2562+
### `ERR_PACKAGE_MAP_INVALID`
2563+
2564+
<!-- YAML
2565+
added: REPLACEME
2566+
-->
2567+
2568+
The [package map][] configuration file is invalid. This can occur when:
2569+
2570+
* The file does not exist at the specified path.
2571+
* The file contains invalid JSON.
2572+
* The file is missing the required `packages` object.
2573+
* A package entry is missing the required `url` field.
2574+
* Two package entries have the same `url` value.
2575+
2576+
```console
2577+
$ node --experimental-package-map=./missing.json app.js
2578+
Error [ERR_PACKAGE_MAP_INVALID]: Invalid package map at "./missing.json": file not found
2579+
```
2580+
2581+
<a id="ERR_PACKAGE_MAP_KEY_NOT_FOUND"></a>
2582+
2583+
### `ERR_PACKAGE_MAP_KEY_NOT_FOUND`
2584+
2585+
<!-- YAML
2586+
added: REPLACEME
2587+
-->
2588+
2589+
A package's `dependencies` object in the [package map][] references a package
2590+
key that is not defined in the `packages` object.
2591+
2592+
```json
2593+
{
2594+
"packages": {
2595+
"app": {
2596+
"url": "./app",
2597+
"dependencies": {
2598+
"foo": "nonexistent"
2599+
}
2600+
}
2601+
}
2602+
}
2603+
```
2604+
2605+
In this example, `"nonexistent"` is referenced as a dependency target but not
2606+
defined in `packages`, which will throw this error.
2607+
2608+
To fix this error, ensure all package keys referenced in `dependencies` values
2609+
are defined in the `packages` object.
2610+
25402611
<a id="ERR_PACKAGE_PATH_NOT_EXPORTED"></a>
25412612

25422613
### `ERR_PACKAGE_PATH_NOT_EXPORTED`
@@ -4559,6 +4630,7 @@ An error occurred trying to allocate memory. This should never happen.
45594630
[domains]: domain.md
45604631
[event emitter-based]: events.md#class-eventemitter
45614632
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
4633+
[package map]: packages.md#package-maps
45624634
[relative URL]: https://url.spec.whatwg.org/#relative-url-string
45634635
[self-reference a package using its name]: packages.md#self-referencing-a-package-using-its-name
45644636
[special scheme]: https://url.spec.whatwg.org/#special-scheme
Collapse file

‎doc/api/esm.md‎

Copy file name to clipboardExpand all lines: doc/api/esm.md
+8Lines changed: 8 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,12 @@ The default loader has the following properties
941941
* Fails on unknown extensions for `file:` loading
942942
(supports only `.cjs`, `.js`, and `.mjs`)
943943
944+
When the [`--experimental-package-map`][] flag is enabled, bare specifier
945+
resolution first consults the package map configuration. If the importing
946+
module is within a mapped package and the specifier matches a declared
947+
dependency, the package map resolution takes precedence. See [Package maps][]
948+
for details.
949+
944950
### Resolution algorithm
945951
946952
The algorithm to load an ES module specifier is given through the
@@ -1304,12 +1310,14 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
13041310
[Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require
13051311
[Module customization hooks]: module.md#customization-hooks
13061312
[Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification
1313+
[Package maps]: packages.md#package-maps
13071314
[Source Phase Imports]: https://github.com/tc39/proposal-source-phase-imports
13081315
[Terminology]: #terminology
13091316
[URL]: https://url.spec.whatwg.org/
13101317
[WebAssembly JS String Builtins Proposal]: https://github.com/WebAssembly/js-string-builtins
13111318
[`"exports"`]: packages.md#exports
13121319
[`"type"`]: packages.md#type
1320+
[`--experimental-package-map`]: cli.md#--experimental-package-mappath
13131321
[`--input-type`]: cli.md#--input-typetype
13141322
[`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data
13151323
[`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
Collapse file

‎doc/api/modules.md‎

Copy file name to clipboardExpand all lines: doc/api/modules.md
+36-15Lines changed: 36 additions & 15 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,12 @@ require(X) from module at path Y
352352
4. If X begins with '#'
353353
a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
354354
5. LOAD_PACKAGE_SELF(X, dirname(Y))
355-
6. LOAD_NODE_MODULES(X, dirname(Y))
356-
7. THROW "not found"
355+
6. If a package map PACKAGE_MAP exists,
356+
a. Find the package ID for the package owning Y
357+
1. Let PARENT_PACKAGE_ID be FIND_PACKAGE_ID(dirname(Y), PACKAGE_MAP)
358+
b. LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
359+
7. LOAD_NODE_MODULES(X, dirname(Y))
360+
8. THROW "not found"
357361
358362
MAYBE_DETECT_AND_LOAD(X)
359363
1. If X parses as a CommonJS module, load X as a CommonJS module. STOP.
@@ -397,9 +401,11 @@ LOAD_AS_DIRECTORY(X)
397401
2. LOAD_INDEX(X)
398402
399403
LOAD_NODE_MODULES(X, START)
400-
1. let DIRS = NODE_MODULES_PATHS(START)
401-
2. for each DIR in DIRS:
402-
a. LOAD_PACKAGE_EXPORTS(X, DIR)
404+
1. Try to interpret X as a combination of NAME and SUBPATH where the name
405+
may have a @scope/ prefix and the subpath begins with a slash (`/`).
406+
2. let DIRS = NODE_MODULES_PATHS(START)
407+
3. for each DIR in DIRS:
408+
a. LOAD_PACKAGE_EXPORTS(SUBPATH, DIR/NAME)
403409
b. LOAD_AS_FILE(DIR/X)
404410
c. LOAD_AS_DIRECTORY(DIR/X)
405411
@@ -414,6 +420,25 @@ NODE_MODULES_PATHS(START)
414420
d. let I = I - 1
415421
5. return DIRS + GLOBAL_FOLDERS
416422
423+
FIND_PACKAGE_ID(PATH, PACKAGE_MAP)
424+
1. Find the PACKAGE_ID for the entry whose "path" is a parent directory of PATH
425+
2. If multiple entries are found, THROW "ambiguous resolution"
426+
3. If no entry was found, THROW "external file".
427+
4. return PACKAGE_ID
428+
429+
LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
430+
1. Try to interpret X as a combination of NAME and SUBPATH where the name
431+
may have a @scope/ prefix and the subpath begins with a slash (`/`).
432+
2. Find the package map entry for key PARENT_PACKAGE_ID
433+
3. Look up NAME in the entry's "dependencies" map.
434+
4. If NAME is not found, THROW "not found".
435+
5. Let TARGET be PACKAGE_MAP.packages[dependencies[name]]
436+
6. Let PACKAGE_PATH be the resolved path of TARGET.
437+
7. LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_PATH)
438+
8. LOAD_AS_FILE(PACKAGE_PATH/SUBPATH)
439+
9. LOAD_AS_DIRECTORY(PACKAGE_PATH/SUBPATH)
440+
10. THROW "not found"
441+
417442
LOAD_PACKAGE_IMPORTS(X, DIR)
418443
1. Find the closest package scope SCOPE to DIR.
419444
2. If no scope was found, return.
@@ -425,19 +450,15 @@ LOAD_PACKAGE_IMPORTS(X, DIR)
425450
CONDITIONS) defined in the ESM resolver.
426451
6. RESOLVE_ESM_MATCH(MATCH).
427452
428-
LOAD_PACKAGE_EXPORTS(X, DIR)
429-
1. Try to interpret X as a combination of NAME and SUBPATH where the name
430-
may have a @scope/ prefix and the subpath begins with a slash (`/`).
431-
2. If X does not match this pattern or DIR/NAME/package.json is not a file,
432-
return.
433-
3. Parse DIR/NAME/package.json, and look for "exports" field.
434-
4. If "exports" is null or undefined, return.
435-
5. If `--no-require-module` is not enabled
453+
LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_DIR)
454+
1. Parse PACKAGE_DIR/package.json, and look for "exports" field.
455+
2. If "exports" is null or undefined, return.
456+
3. If `--no-require-module` is not enabled
436457
a. let CONDITIONS = ["node", "require", "module-sync"]
437458
b. Else, let CONDITIONS = ["node", "require"]
438-
6. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
459+
4. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(PACKAGE_DIR), "." + SUBPATH,
439460
`package.json` "exports", CONDITIONS) defined in the ESM resolver.
440-
7. RESOLVE_ESM_MATCH(MATCH)
461+
5. RESOLVE_ESM_MATCH(MATCH)
441462
442463
LOAD_PACKAGE_SELF(X, DIR)
443464
1. Find the closest package scope SCOPE to DIR.

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.