1# Modules: ECMAScript modules 2 3<!--introduced_in=v8.5.0--> 4 5<!-- type=misc --> 6 7<!-- YAML 8added: v8.5.0 9changes: 10 - version: v18.20.0 11 pr-url: https://github.com/nodejs/node/pull/50140 12 description: Add experimental support for import attributes. 13 - version: v18.19.0 14 pr-url: https://github.com/nodejs/node/pull/44710 15 description: Module customization hooks are executed off the main thread. 16 - version: 17 - v18.6.0 18 pr-url: https://github.com/nodejs/node/pull/42623 19 description: Add support for chaining module customization hooks. 20 - version: 21 - v17.1.0 22 - v16.14.0 23 pr-url: https://github.com/nodejs/node/pull/40250 24 description: Add experimental support for import assertions. 25 - version: 26 - v17.0.0 27 - v16.12.0 28 pr-url: https://github.com/nodejs/node/pull/37468 29 description: 30 Consolidate customization hooks, removed `getFormat`, `getSource`, 31 `transformSource`, and `getGlobalPreloadCode` hooks 32 added `load` and `globalPreload` hooks 33 allowed returning `format` from either `resolve` or `load` hooks. 34 - version: 35 - v15.3.0 36 - v14.17.0 37 - v12.22.0 38 pr-url: https://github.com/nodejs/node/pull/35781 39 description: Stabilize modules implementation. 40 - version: 41 - v14.13.0 42 - v12.20.0 43 pr-url: https://github.com/nodejs/node/pull/35249 44 description: Support for detection of CommonJS named exports. 45 - version: v14.8.0 46 pr-url: https://github.com/nodejs/node/pull/34558 47 description: Unflag Top-Level Await. 48 - version: 49 - v14.0.0 50 - v13.14.0 51 - v12.20.0 52 pr-url: https://github.com/nodejs/node/pull/31974 53 description: Remove experimental modules warning. 54 - version: 55 - v13.2.0 56 - v12.17.0 57 pr-url: https://github.com/nodejs/node/pull/29866 58 description: Loading ECMAScript modules no longer requires a command-line flag. 59 - version: v12.0.0 60 pr-url: https://github.com/nodejs/node/pull/26745 61 description: 62 Add support for ES modules using `.js` file extension via `package.json` 63 `"type"` field. 64--> 65 66> Stability: 2 - Stable 67 68## Introduction 69 70<!--name=esm--> 71 72ECMAScript modules are [the official standard format][] to package JavaScript 73code for reuse. Modules are defined using a variety of [`import`][] and 74[`export`][] statements. 75 76The following example of an ES module exports a function: 77 78```js 79// addTwo.mjs 80function addTwo(num) { 81 return num + 2; 82} 83 84export { addTwo }; 85``` 86 87The following example of an ES module imports the function from `addTwo.mjs`: 88 89```js 90// app.mjs 91import { addTwo } from './addTwo.mjs'; 92 93// Prints: 6 94console.log(addTwo(4)); 95``` 96 97Node.js fully supports ECMAScript modules as they are currently specified and 98provides interoperability between them and its original module format, 99[CommonJS][]. 100 101<!-- Anchors to make sure old links find a target --> 102 103<i id="esm_package_json_type_field"></i><i id="esm_package_scope_and_file_extensions"></i><i id="esm_input_type_flag"></i> 104 105## Enabling 106 107<!-- type=misc --> 108 109Node.js has two module systems: [CommonJS][] modules and ECMAScript modules. 110 111Authors can tell Node.js to use the ECMAScript modules loader via the `.mjs` 112file extension, the `package.json` [`"type"`][] field, the [`--input-type`][] 113flag, or the [`--experimental-default-type`][] flag. Outside of those cases, 114Node.js will use the CommonJS module loader. See [Determining module system][] 115for more details. 116 117<!-- Anchors to make sure old links find a target --> 118 119<i id="esm_package_entry_points"></i><i id="esm_main_entry_point_export"></i><i id="esm_subpath_exports"></i><i id="esm_package_exports_fallbacks"></i><i id="esm_exports_sugar"></i><i id="esm_conditional_exports"></i><i id="esm_nested_conditions"></i><i id="esm_self_referencing_a_package_using_its_name"></i><i id="esm_internal_package_imports"></i><i id="esm_dual_commonjs_es_module_packages"></i><i id="esm_dual_package_hazard"></i><i id="esm_writing_dual_packages_while_avoiding_or_minimizing_hazards"></i><i id="esm_approach_1_use_an_es_module_wrapper"></i><i id="esm_approach_2_isolate_state"></i> 120 121## Packages 122 123This section was moved to [Modules: Packages](packages.md). 124 125## `import` Specifiers 126 127### Terminology 128 129The _specifier_ of an `import` statement is the string after the `from` keyword, 130e.g. `'node:path'` in `import { sep } from 'node:path'`. Specifiers are also 131used in `export from` statements, and as the argument to an `import()` 132expression. 133 134There are three types of specifiers: 135 136* _Relative specifiers_ like `'./startup.js'` or `'../config.mjs'`. They refer 137 to a path relative to the location of the importing file. _The file extension 138 is always necessary for these._ 139 140* _Bare specifiers_ like `'some-package'` or `'some-package/shuffle'`. They can 141 refer to the main entry point of a package by the package name, or a 142 specific feature module within a package prefixed by the package name as per 143 the examples respectively. _Including the file extension is only necessary 144 for packages without an [`"exports"`][] field._ 145 146* _Absolute specifiers_ like `'file:///opt/nodejs/config.js'`. They refer 147 directly and explicitly to a full path. 148 149Bare specifier resolutions are handled by the [Node.js module 150resolution and loading algorithm][]. 151All other specifier resolutions are always only resolved with 152the standard relative [URL][] resolution semantics. 153 154Like in CommonJS, module files within packages can be accessed by appending a 155path to the package name unless the package's [`package.json`][] contains an 156[`"exports"`][] field, in which case files within packages can only be accessed 157via the paths defined in [`"exports"`][]. 158 159For details on these package resolution rules that apply to bare specifiers in 160the Node.js module resolution, see the [packages documentation](packages.md). 161 162### Mandatory file extensions 163 164A file extension must be provided when using the `import` keyword to resolve 165relative or absolute specifiers. Directory indexes (e.g. `'./startup/index.js'`) 166must also be fully specified. 167 168This behavior matches how `import` behaves in browser environments, assuming a 169typically configured server. 170 171### URLs 172 173ES modules are resolved and cached as URLs. This means that special characters 174must be [percent-encoded][], such as `#` with `%23` and `?` with `%3F`. 175 176`file:`, `node:`, and `data:` URL schemes are supported. A specifier like 177`'https://example.com/app.js'` is not supported natively in Node.js unless using 178a [custom HTTPS loader][]. 179 180#### `file:` URLs 181 182Modules are loaded multiple times if the `import` specifier used to resolve 183them has a different query or fragment. 184 185```js 186import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1" 187import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2" 188``` 189 190The volume root may be referenced via `/`, `//`, or `file:///`. Given the 191differences between [URL][] and path resolution (such as percent encoding 192details), it is recommended to use [url.pathToFileURL][] when importing a path. 193 194#### `data:` imports 195 196<!-- YAML 197added: v12.10.0 198--> 199 200[`data:` URLs][] are supported for importing with the following MIME types: 201 202* `text/javascript` for ES modules 203* `application/json` for JSON 204* `application/wasm` for Wasm 205 206```js 207import 'data:text/javascript,console.log("hello!");'; 208import _ from 'data:application/json,"world!"' with { type: 'json' }; 209``` 210 211`data:` URLs only resolve [bare specifiers][Terminology] for builtin modules 212and [absolute specifiers][Terminology]. Resolving 213[relative specifiers][Terminology] does not work because `data:` is not a 214[special scheme][]. For example, attempting to load `./foo` 215from `data:text/javascript,import "./foo";` fails to resolve because there 216is no concept of relative resolution for `data:` URLs. 217 218#### `node:` imports 219 220<!-- YAML 221added: 222 - v14.13.1 223 - v12.20.0 224changes: 225 - version: 226 - v16.0.0 227 - v14.18.0 228 pr-url: https://github.com/nodejs/node/pull/37246 229 description: Added `node:` import support to `require(...)`. 230--> 231 232`node:` URLs are supported as an alternative means to load Node.js builtin 233modules. This URL scheme allows for builtin modules to be referenced by valid 234absolute URL strings. 235 236```js 237import fs from 'node:fs/promises'; 238``` 239 240<a id="import-assertions"></a> 241 242## Import attributes 243 244<!-- YAML 245added: 246 - v17.1.0 247 - v16.14.0 248changes: 249 - version: v18.20.0 250 pr-url: https://github.com/nodejs/node/pull/50140 251 description: Switch from Import Assertions to Import Attributes. 252--> 253 254> Stability: 1.1 - Active development 255 256> This feature was previously named "Import assertions", and using the `assert` 257> keyword instead of `with`. Any uses in code of the prior `assert` keyword 258> should be updated to use `with` instead. 259 260The [Import Attributes proposal][] adds an inline syntax for module import 261statements to pass on more information alongside the module specifier. 262 263```js 264import fooData from './foo.json' with { type: 'json' }; 265 266const { default: barData } = 267 await import('./bar.json', { with: { type: 'json' } }); 268``` 269 270Node.js supports the following `type` values, for which the attribute is 271mandatory: 272 273| Attribute `type` | Needed for | 274| ---------------- | ---------------- | 275| `'json'` | [JSON modules][] | 276 277## Builtin modules 278 279[Core modules][] provide named exports of their public API. A 280default export is also provided which is the value of the CommonJS exports. 281The default export can be used for, among other things, modifying the named 282exports. Named exports of builtin modules are updated only by calling 283[`module.syncBuiltinESMExports()`][]. 284 285```js 286import EventEmitter from 'node:events'; 287const e = new EventEmitter(); 288``` 289 290```js 291import { readFile } from 'node:fs'; 292readFile('./foo.txt', (err, source) => { 293 if (err) { 294 console.error(err); 295 } else { 296 console.log(source); 297 } 298}); 299``` 300 301```js 302import fs, { readFileSync } from 'node:fs'; 303import { syncBuiltinESMExports } from 'node:module'; 304import { Buffer } from 'node:buffer'; 305 306fs.readFileSync = () => Buffer.from('Hello, ESM'); 307syncBuiltinESMExports(); 308 309fs.readFileSync === readFileSync; 310``` 311 312## `import()` expressions 313 314[Dynamic `import()`][] is supported in both CommonJS and ES modules. In CommonJS 315modules it can be used to load ES modules. 316 317## `import.meta` 318 319* {Object} 320 321The `import.meta` meta property is an `Object` that contains the following 322properties. 323 324### `import.meta.url` 325 326* {string} The absolute `file:` URL of the module. 327 328This is defined exactly the same as it is in browsers providing the URL of the 329current module file. 330 331This enables useful patterns such as relative file loading: 332 333```js 334import { readFileSync } from 'node:fs'; 335const buffer = readFileSync(new URL('./data.proto', import.meta.url)); 336``` 337 338### `import.meta.resolve(specifier)` 339 340<!-- YAML 341added: 342 - v13.9.0 343 - v12.16.2 344changes: 345 - version: v18.19.0 346 pr-url: https://github.com/nodejs/node/pull/49028 347 description: Unflag `import.meta.resolve``, with `parentURL` parameter still 348 flagged. 349 - version: v18.19.0 350 pr-url: https://github.com/nodejs/node/pull/49038 351 description: This API no longer throws when targeting `file:` URLs that do 352 not map to an existing file on the local FS. 353 - version: v18.19.0 354 pr-url: https://github.com/nodejs/node/pull/44710 355 description: This API now returns a string synchronously instead of a Promise. 356 - version: 357 - v16.2.0 358 - v14.18.0 359 pr-url: https://github.com/nodejs/node/pull/38587 360 description: Add support for WHATWG `URL` object to `parentURL` parameter. 361--> 362 363> Stability: 1.2 - Release candidate 364 365* `specifier` {string} The module specifier to resolve relative to the 366 current module. 367* Returns: {string} The absolute URL string that the specifier would resolve to. 368 369[`import.meta.resolve`][] is a module-relative resolution function scoped to 370each module, returning the URL string. 371 372```js 373const dependencyAsset = import.meta.resolve('component-lib/asset.css'); 374// file:///app/node_modules/component-lib/asset.css 375import.meta.resolve('./dep.js'); 376// file:///app/dep.js 377``` 378 379All features of the Node.js module resolution are supported. Dependency 380resolutions are subject to the permitted exports resolutions within the package. 381 382**Caveats**: 383 384* This can result in synchronous file-system operations, which 385 can impact performance similarly to `require.resolve`. 386* This feature is not available within custom loaders (it would 387 create a deadlock). 388 389**Non-standard API**: 390 391When using the `--experimental-import-meta-resolve` flag, that function accepts 392a second argument: 393 394* `parent` {string|URL} An optional absolute parent module URL to resolve from. 395 **Default:** `import.meta.url` 396 397## Interoperability with CommonJS 398 399### `import` statements 400 401An `import` statement can reference an ES module or a CommonJS module. 402`import` statements are permitted only in ES modules, but dynamic [`import()`][] 403expressions are supported in CommonJS for loading ES modules. 404 405When importing [CommonJS modules](#commonjs-namespaces), the 406`module.exports` object is provided as the default export. Named exports may be 407available, provided by static analysis as a convenience for better ecosystem 408compatibility. 409 410### `require` 411 412The CommonJS module `require` always treats the files it references as CommonJS. 413 414Using `require` to load an ES module is not supported because ES modules have 415asynchronous execution. Instead, use [`import()`][] to load an ES module 416from a CommonJS module. 417 418### CommonJS Namespaces 419 420CommonJS modules consist of a `module.exports` object which can be of any type. 421 422When importing a CommonJS module, it can be reliably imported using the ES 423module default import or its corresponding sugar syntax: 424 425<!-- eslint-disable no-duplicate-imports --> 426 427```js 428import { default as cjs } from 'cjs'; 429 430// The following import statement is "syntax sugar" (equivalent but sweeter) 431// for `{ default as cjsSugar }` in the above import statement: 432import cjsSugar from 'cjs'; 433 434console.log(cjs); 435console.log(cjs === cjsSugar); 436// Prints: 437// <module.exports> 438// true 439``` 440 441The ECMAScript Module Namespace representation of a CommonJS module is always 442a namespace with a `default` export key pointing to the CommonJS 443`module.exports` value. 444 445This Module Namespace Exotic Object can be directly observed either when using 446`import * as m from 'cjs'` or a dynamic import: 447 448<!-- eslint-skip --> 449 450```js 451import * as m from 'cjs'; 452console.log(m); 453console.log(m === await import('cjs')); 454// Prints: 455// [Module] { default: <module.exports> } 456// true 457``` 458 459For better compatibility with existing usage in the JS ecosystem, Node.js 460in addition attempts to determine the CommonJS named exports of every imported 461CommonJS module to provide them as separate ES module exports using a static 462analysis process. 463 464For example, consider a CommonJS module written: 465 466```cjs 467// cjs.cjs 468exports.name = 'exported'; 469``` 470 471The preceding module supports named imports in ES modules: 472 473<!-- eslint-disable no-duplicate-imports --> 474 475```js 476import { name } from './cjs.cjs'; 477console.log(name); 478// Prints: 'exported' 479 480import cjs from './cjs.cjs'; 481console.log(cjs); 482// Prints: { name: 'exported' } 483 484import * as m from './cjs.cjs'; 485console.log(m); 486// Prints: [Module] { default: { name: 'exported' }, name: 'exported' } 487``` 488 489As can be seen from the last example of the Module Namespace Exotic Object being 490logged, the `name` export is copied off of the `module.exports` object and set 491directly on the ES module namespace when the module is imported. 492 493Live binding updates or new exports added to `module.exports` are not detected 494for these named exports. 495 496The detection of named exports is based on common syntax patterns but does not 497always correctly detect named exports. In these cases, using the default 498import form described above can be a better option. 499 500Named exports detection covers many common export patterns, reexport patterns 501and build tool and transpiler outputs. See [cjs-module-lexer][] for the exact 502semantics implemented. 503 504### Differences between ES modules and CommonJS 505 506#### No `require`, `exports`, or `module.exports` 507 508In most cases, the ES module `import` can be used to load CommonJS modules. 509 510If needed, a `require` function can be constructed within an ES module using 511[`module.createRequire()`][]. 512 513#### No `__filename` or `__dirname` 514 515These CommonJS variables are not available in ES modules. 516 517`__filename` and `__dirname` use cases can be replicated via 518[`import.meta.url`][]. 519 520#### No Addon Loading 521 522[Addons][] are not currently supported with ES module imports. 523 524They can instead be loaded with [`module.createRequire()`][] or 525[`process.dlopen`][]. 526 527#### No `require.resolve` 528 529Relative resolution can be handled via `new URL('./local', import.meta.url)`. 530 531For a complete `require.resolve` replacement, there is the 532[import.meta.resolve][] API. 533 534Alternatively `module.createRequire()` can be used. 535 536#### No `NODE_PATH` 537 538`NODE_PATH` is not part of resolving `import` specifiers. Please use symlinks 539if this behavior is desired. 540 541#### No `require.extensions` 542 543`require.extensions` is not used by `import`. Module customization hooks can 544provide a replacement. 545 546#### No `require.cache` 547 548`require.cache` is not used by `import` as the ES module loader has its own 549separate cache. 550 551<i id="esm_experimental_json_modules"></i> 552 553## JSON modules 554 555> Stability: 1 - Experimental 556 557JSON files can be referenced by `import`: 558 559```js 560import packageConfig from './package.json' with { type: 'json' }; 561``` 562 563The `with { type: 'json' }` syntax is mandatory; see [Import Attributes][]. 564 565The imported JSON only exposes a `default` export. There is no support for named 566exports. A cache entry is created in the CommonJS cache to avoid duplication. 567The same object is returned in CommonJS if the JSON module has already been 568imported from the same path. 569 570<i id="esm_experimental_wasm_modules"></i> 571 572## Wasm modules 573 574> Stability: 1 - Experimental 575 576Importing WebAssembly modules is supported under the 577`--experimental-wasm-modules` flag, allowing any `.wasm` files to be 578imported as normal modules while also supporting their module imports. 579 580This integration is in line with the 581[ES Module Integration Proposal for WebAssembly][]. 582 583For example, an `index.mjs` containing: 584 585```js 586import * as M from './module.wasm'; 587console.log(M); 588``` 589 590executed under: 591 592```bash 593node --experimental-wasm-modules index.mjs 594``` 595 596would provide the exports interface for the instantiation of `module.wasm`. 597 598<i id="esm_experimental_top_level_await"></i> 599 600## Top-level `await` 601 602<!-- YAML 603added: v14.8.0 604--> 605 606The `await` keyword may be used in the top level body of an ECMAScript module. 607 608Assuming an `a.mjs` with 609 610```js 611export const five = await Promise.resolve(5); 612``` 613 614And a `b.mjs` with 615 616```js 617import { five } from './a.mjs'; 618 619console.log(five); // Logs `5` 620``` 621 622```bash 623node b.mjs # works 624``` 625 626If a top level `await` expression never resolves, the `node` process will exit 627with a `13` [status code][]. 628 629```js 630import { spawn } from 'node:child_process'; 631import { execPath } from 'node:process'; 632 633spawn(execPath, [ 634 '--input-type=module', 635 '--eval', 636 // Never-resolving Promise: 637 'await new Promise(() => {})', 638]).once('exit', (code) => { 639 console.log(code); // Logs `13` 640}); 641``` 642 643## HTTPS and HTTP imports 644 645> Stability: 1 - Experimental 646 647Importing network based modules using `https:` and `http:` is supported under 648the `--experimental-network-imports` flag. This allows web browser-like imports 649to work in Node.js with a few differences due to application stability and 650security concerns that are different when running in a privileged environment 651instead of a browser sandbox. 652 653### Imports are limited to HTTP/1 654 655Automatic protocol negotiation for HTTP/2 and HTTP/3 is not yet supported. 656 657### HTTP is limited to loopback addresses 658 659`http:` is vulnerable to man-in-the-middle attacks and is not allowed to be 660used for addresses outside of the IPv4 address `127.0.0.0/8` (`127.0.0.1` to 661`127.255.255.255`) and the IPv6 address `::1`. Support for `http:` is intended 662to be used for local development. 663 664### Authentication is never sent to the destination server. 665 666`Authorization`, `Cookie`, and `Proxy-Authorization` headers are not sent to the 667server. Avoid including user info in parts of imported URLs. A security model 668for safely using these on the server is being worked on. 669 670### CORS is never checked on the destination server 671 672CORS is designed to allow a server to limit the consumers of an API to a 673specific set of hosts. This is not supported as it does not make sense for a 674server-based implementation. 675 676### Cannot load non-network dependencies 677 678These modules cannot access other modules that are not over `http:` or `https:`. 679To still access local modules while avoiding the security concern, pass in 680references to the local dependencies: 681 682```mjs 683// file.mjs 684import worker_threads from 'node:worker_threads'; 685import { configure, resize } from 'https://example.com/imagelib.mjs'; 686configure({ worker_threads }); 687``` 688 689```mjs 690// https://example.com/imagelib.mjs 691let worker_threads; 692export function configure(opts) { 693 worker_threads = opts.worker_threads; 694} 695export function resize(img, size) { 696 // Perform resizing in worker_thread to avoid main thread blocking 697} 698``` 699 700### Network-based loading is not enabled by default 701 702For now, the `--experimental-network-imports` flag is required to enable loading 703resources over `http:` or `https:`. In the future, a different mechanism will be 704used to enforce this. Opt-in is required to prevent transitive dependencies 705inadvertently using potentially mutable state that could affect reliability 706of Node.js applications. 707 708<i id="esm_experimental_loaders"></i> 709 710## Loaders 711 712The former Loaders documentation is now at 713[Modules: Customization hooks][Module customization hooks]. 714 715## Resolution and loading algorithm 716 717### Features 718 719The default resolver has the following properties: 720 721* FileURL-based resolution as is used by ES modules 722* Relative and absolute URL resolution 723* No default extensions 724* No folder mains 725* Bare specifier package resolution lookup through node\_modules 726* Does not fail on unknown extensions or protocols 727* Can optionally provide a hint of the format to the loading phase 728 729The default loader has the following properties 730 731* Support for builtin module loading via `node:` URLs 732* Support for "inline" module loading via `data:` URLs 733* Support for `file:` module loading 734* Fails on any other URL protocol 735* Fails on unknown extensions for `file:` loading 736 (supports only `.cjs`, `.js`, and `.mjs`) 737 738### Resolution algorithm 739 740The algorithm to load an ES module specifier is given through the 741**ESM\_RESOLVE** method below. It returns the resolved URL for a 742module specifier relative to a parentURL. 743 744The resolution algorithm determines the full resolved URL for a module 745load, along with its suggested module format. The resolution algorithm 746does not determine whether the resolved URL protocol can be loaded, 747or whether the file extensions are permitted, instead these validations 748are applied by Node.js during the load phase 749(for example, if it was asked to load a URL that has a protocol that is 750not `file:`, `data:`, `node:`, or if `--experimental-network-imports` 751is enabled, `https:`). 752 753The algorithm also tries to determine the format of the file based 754on the extension (see `ESM_FILE_FORMAT` algorithm below). If it does 755not recognize the file extension (eg if it is not `.mjs`, `.cjs`, or 756`.json`), then a format of `undefined` is returned, 757which will throw during the load phase. 758 759The algorithm to determine the module format of a resolved URL is 760provided by **ESM\_FILE\_FORMAT**, which returns the unique module 761format for any file. The _"module"_ format is returned for an ECMAScript 762Module, while the _"commonjs"_ format is used to indicate loading through the 763legacy CommonJS loader. Additional formats such as _"addon"_ can be extended in 764future updates. 765 766In the following algorithms, all subroutine errors are propagated as errors 767of these top-level routines unless stated otherwise. 768 769_defaultConditions_ is the conditional environment name array, 770`["node", "import"]`. 771 772The resolver can throw the following errors: 773 774* _Invalid Module Specifier_: Module specifier is an invalid URL, package name 775 or package subpath specifier. 776* _Invalid Package Configuration_: package.json configuration is invalid or 777 contains an invalid configuration. 778* _Invalid Package Target_: Package exports or imports define a target module 779 for the package that is an invalid type or string target. 780* _Package Path Not Exported_: Package exports do not define or permit a target 781 subpath in the package for the given module. 782* _Package Import Not Defined_: Package imports do not define the specifier. 783* _Module Not Found_: The package or module requested does not exist. 784* _Unsupported Directory Import_: The resolved path corresponds to a directory, 785 which is not a supported target for module imports. 786 787### Resolution Algorithm Specification 788 789**ESM\_RESOLVE**(_specifier_, _parentURL_) 790 791> 1. Let _resolved_ be **undefined**. 792> 2. If _specifier_ is a valid URL, then 793> 1. Set _resolved_ to the result of parsing and reserializing 794> _specifier_ as a URL. 795> 3. Otherwise, if _specifier_ starts with _"/"_, _"./"_, or _"../"_, then 796> 1. Set _resolved_ to the URL resolution of _specifier_ relative to 797> _parentURL_. 798> 4. Otherwise, if _specifier_ starts with _"#"_, then 799> 1. Set _resolved_ to the result of 800> **PACKAGE\_IMPORTS\_RESOLVE**(_specifier_, 801> _parentURL_, _defaultConditions_). 802> 5. Otherwise, 803> 1. Note: _specifier_ is now a bare specifier. 804> 2. Set _resolved_ the result of 805> **PACKAGE\_RESOLVE**(_specifier_, _parentURL_). 806> 6. Let _format_ be **undefined**. 807> 7. If _resolved_ is a _"file:"_ URL, then 808> 1. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2F"_ 809> and _"%5C"_ respectively), then 810> 1. Throw an _Invalid Module Specifier_ error. 811> 2. If the file at _resolved_ is a directory, then 812> 1. Throw an _Unsupported Directory Import_ error. 813> 3. If the file at _resolved_ does not exist, then 814> 1. Throw a _Module Not Found_ error. 815> 4. Set _resolved_ to the real path of _resolved_, maintaining the 816> same URL querystring and fragment components. 817> 5. Set _format_ to the result of **ESM\_FILE\_FORMAT**(_resolved_). 818> 8. Otherwise, 819> 1. Set _format_ the module format of the content type associated with the 820> URL _resolved_. 821> 9. Return _format_ and _resolved_ to the loading phase 822 823**PACKAGE\_RESOLVE**(_packageSpecifier_, _parentURL_) 824 825> 1. Let _packageName_ be **undefined**. 826> 2. If _packageSpecifier_ is an empty string, then 827> 1. Throw an _Invalid Module Specifier_ error. 828> 3. If _packageSpecifier_ is a Node.js builtin module name, then 829> 1. Return the string _"node:"_ concatenated with _packageSpecifier_. 830> 4. If _packageSpecifier_ does not start with _"@"_, then 831> 1. Set _packageName_ to the substring of _packageSpecifier_ until the first 832> _"/"_ separator or the end of the string. 833> 5. Otherwise, 834> 1. If _packageSpecifier_ does not contain a _"/"_ separator, then 835> 1. Throw an _Invalid Module Specifier_ error. 836> 2. Set _packageName_ to the substring of _packageSpecifier_ 837> until the second _"/"_ separator or the end of the string. 838> 6. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then 839> 1. Throw an _Invalid Module Specifier_ error. 840> 7. Let _packageSubpath_ be _"."_ concatenated with the substring of 841> _packageSpecifier_ from the position at the length of _packageName_. 842> 8. If _packageSubpath_ ends in _"/"_, then 843> 1. Throw an _Invalid Module Specifier_ error. 844> 9. Let _selfUrl_ be the result of 845> **PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_). 846> 10. If _selfUrl_ is not **undefined**, return _selfUrl_. 847> 11. While _parentURL_ is not the file system root, 848> 1. Let _packageURL_ be the URL resolution of _"node\_modules/"_ 849> concatenated with _packageSpecifier_, relative to _parentURL_. 850> 2. Set _parentURL_ to the parent folder URL of _parentURL_. 851> 3. If the folder at _packageURL_ does not exist, then 852> 1. Continue the next loop iteration. 853> 4. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). 854> 5. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or 855> **undefined**, then 856> 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, 857> _packageSubpath_, _pjson.exports_, _defaultConditions_). 858> 6. Otherwise, if _packageSubpath_ is equal to _"."_, then 859> 1. If _pjson.main_ is a string, then 860> 1. Return the URL resolution of _main_ in _packageURL_. 861> 7. Otherwise, 862> 1. Return the URL resolution of _packageSubpath_ in _packageURL_. 863> 12. Throw a _Module Not Found_ error. 864 865**PACKAGE\_SELF\_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_) 866 867> 1. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_parentURL_). 868> 2. If _packageURL_ is **null**, then 869> 1. Return **undefined**. 870> 3. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). 871> 4. If _pjson_ is **null** or if _pjson_._exports_ is **null** or 872> **undefined**, then 873> 1. Return **undefined**. 874> 5. If _pjson.name_ is equal to _packageName_, then 875> 1. Return the result of **PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, 876> _packageSubpath_, _pjson.exports_, _defaultConditions_). 877> 6. Otherwise, return **undefined**. 878 879**PACKAGE\_EXPORTS\_RESOLVE**(_packageURL_, _subpath_, _exports_, _conditions_) 880 881> 1. If _exports_ is an Object with both a key starting with _"."_ and a key not 882> starting with _"."_, throw an _Invalid Package Configuration_ error. 883> 2. If _subpath_ is equal to _"."_, then 884> 1. Let _mainExport_ be **undefined**. 885> 2. If _exports_ is a String or Array, or an Object containing no keys 886> starting with _"."_, then 887> 1. Set _mainExport_ to _exports_. 888> 3. Otherwise if _exports_ is an Object containing a _"."_ property, then 889> 1. Set _mainExport_ to _exports_\[_"."_]. 890> 4. If _mainExport_ is not **undefined**, then 891> 1. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( 892> _packageURL_, _mainExport_, **null**, **false**, _conditions_). 893> 2. If _resolved_ is not **null** or **undefined**, return _resolved_. 894> 3. Otherwise, if _exports_ is an Object and all keys of _exports_ start with 895> _"."_, then 896> 1. Let _matchKey_ be the string _"./"_ concatenated with _subpath_. 897> 2. Let _resolved_ be the result of **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**( 898> _matchKey_, _exports_, _packageURL_, **false**, _conditions_). 899> 3. If _resolved_ is not **null** or **undefined**, return _resolved_. 900> 4. Throw a _Package Path Not Exported_ error. 901 902**PACKAGE\_IMPORTS\_RESOLVE**(_specifier_, _parentURL_, _conditions_) 903 904> 1. Assert: _specifier_ begins with _"#"_. 905> 2. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then 906> 1. Throw an _Invalid Module Specifier_ error. 907> 3. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_parentURL_). 908> 4. If _packageURL_ is not **null**, then 909> 1. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). 910> 2. If _pjson.imports_ is a non-null Object, then 911> 1. Let _resolved_ be the result of 912> **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**( 913> _specifier_, _pjson.imports_, _packageURL_, **true**, _conditions_). 914> 2. If _resolved_ is not **null** or **undefined**, return _resolved_. 915> 5. Throw a _Package Import Not Defined_ error. 916 917**PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**(_matchKey_, _matchObj_, _packageURL_, 918_isImports_, _conditions_) 919 920> 1. If _matchKey_ is a key of _matchObj_ and does not contain _"\*"_, then 921> 1. Let _target_ be the value of _matchObj_\[_matchKey_]. 922> 2. Return the result of **PACKAGE\_TARGET\_RESOLVE**(_packageURL_, 923> _target_, **null**, _isImports_, _conditions_). 924> 2. Let _expansionKeys_ be the list of keys of _matchObj_ containing only a 925> single _"\*"_, sorted by the sorting function **PATTERN\_KEY\_COMPARE** 926> which orders in descending order of specificity. 927> 3. For each key _expansionKey_ in _expansionKeys_, do 928> 1. Let _patternBase_ be the substring of _expansionKey_ up to but excluding 929> the first _"\*"_ character. 930> 2. If _matchKey_ starts with but is not equal to _patternBase_, then 931> 1. Let _patternTrailer_ be the substring of _expansionKey_ from the 932> index after the first _"\*"_ character. 933> 2. If _patternTrailer_ has zero length, or if _matchKey_ ends with 934> _patternTrailer_ and the length of _matchKey_ is greater than or 935> equal to the length of _expansionKey_, then 936> 1. Let _target_ be the value of _matchObj_\[_expansionKey_]. 937> 2. Let _patternMatch_ be the substring of _matchKey_ starting at the 938> index of the length of _patternBase_ up to the length of 939> _matchKey_ minus the length of _patternTrailer_. 940> 3. Return the result of **PACKAGE\_TARGET\_RESOLVE**(_packageURL_, 941> _target_, _patternMatch_, _isImports_, _conditions_). 942> 4. Return **null**. 943 944**PATTERN\_KEY\_COMPARE**(_keyA_, _keyB_) 945 946> 1. Assert: _keyA_ ends with _"/"_ or contains only a single _"\*"_. 947> 2. Assert: _keyB_ ends with _"/"_ or contains only a single _"\*"_. 948> 3. Let _baseLengthA_ be the index of _"\*"_ in _keyA_ plus one, if _keyA_ 949> contains _"\*"_, or the length of _keyA_ otherwise. 950> 4. Let _baseLengthB_ be the index of _"\*"_ in _keyB_ plus one, if _keyB_ 951> contains _"\*"_, or the length of _keyB_ otherwise. 952> 5. If _baseLengthA_ is greater than _baseLengthB_, return -1. 953> 6. If _baseLengthB_ is greater than _baseLengthA_, return 1. 954> 7. If _keyA_ does not contain _"\*"_, return 1. 955> 8. If _keyB_ does not contain _"\*"_, return -1. 956> 9. If the length of _keyA_ is greater than the length of _keyB_, return -1. 957> 10. If the length of _keyB_ is greater than the length of _keyA_, return 1. 958> 11. Return 0. 959 960**PACKAGE\_TARGET\_RESOLVE**(_packageURL_, _target_, _patternMatch_, 961_isImports_, _conditions_) 962 963> 1. If _target_ is a String, then 964> 1. If _target_ does not start with _"./"_, then 965> 1. If _isImports_ is **false**, or if _target_ starts with _"../"_ or 966> _"/"_, or if _target_ is a valid URL, then 967> 1. Throw an _Invalid Package Target_ error. 968> 2. If _patternMatch_ is a String, then 969> 1. Return **PACKAGE\_RESOLVE**(_target_ with every instance of _"\*"_ 970> replaced by _patternMatch_, _packageURL_ + _"/"_). 971> 3. Return **PACKAGE\_RESOLVE**(_target_, _packageURL_ + _"/"_). 972> 2. If _target_ split on _"/"_ or _"\\"_ contains any _""_, _"."_, _".."_, 973> or _"node\_modules"_ segments after the first _"."_ segment, case 974> insensitive and including percent encoded variants, throw an _Invalid 975> Package Target_ error. 976> 3. Let _resolvedTarget_ be the URL resolution of the concatenation of 977> _packageURL_ and _target_. 978> 4. Assert: _resolvedTarget_ is contained in _packageURL_. 979> 5. If _patternMatch_ is **null**, then 980> 1. Return _resolvedTarget_. 981> 6. If _patternMatch_ split on _"/"_ or _"\\"_ contains any _""_, _"."_, 982> _".."_, or _"node\_modules"_ segments, case insensitive and including 983> percent encoded variants, throw an _Invalid Module Specifier_ error. 984> 7. Return the URL resolution of _resolvedTarget_ with every instance of 985> _"\*"_ replaced with _patternMatch_. 986> 2. Otherwise, if _target_ is a non-null Object, then 987> 1. If _exports_ contains any index property keys, as defined in ECMA-262 988> [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error. 989> 2. For each property _p_ of _target_, in object insertion order as, 990> 1. If _p_ equals _"default"_ or _conditions_ contains an entry for _p_, 991> then 992> 1. Let _targetValue_ be the value of the _p_ property in _target_. 993> 2. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( 994> _packageURL_, _targetValue_, _patternMatch_, _isImports_, 995> _conditions_). 996> 3. If _resolved_ is equal to **undefined**, continue the loop. 997> 4. Return _resolved_. 998> 3. Return **undefined**. 999> 3. Otherwise, if _target_ is an Array, then 1000> 1. If \_target.length is zero, return **null**. 1001> 2. For each item _targetValue_ in _target_, do 1002> 1. Let _resolved_ be the result of **PACKAGE\_TARGET\_RESOLVE**( 1003> _packageURL_, _targetValue_, _patternMatch_, _isImports_, 1004> _conditions_), continuing the loop on any _Invalid Package Target_ 1005> error. 1006> 2. If _resolved_ is **undefined**, continue the loop. 1007> 3. Return _resolved_. 1008> 3. Return or throw the last fallback resolution **null** return or error. 1009> 4. Otherwise, if _target_ is _null_, return **null**. 1010> 5. Otherwise throw an _Invalid Package Target_ error. 1011 1012**ESM\_FILE\_FORMAT**(_url_) 1013 1014> 1. Assert: _url_ corresponds to an existing file. 1015> 2. If _url_ ends in _".mjs"_, then 1016> 1. Return _"module"_. 1017> 3. If _url_ ends in _".cjs"_, then 1018> 1. Return _"commonjs"_. 1019> 4. If _url_ ends in _".json"_, then 1020> 1. Return _"json"_. 1021> 5. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_url_). 1022> 6. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). 1023> 7. If _pjson?.type_ exists and is _"module"_, then 1024> 1. If _url_ ends in _".js"_ or has no file extension, then 1025> 1. If `--experimental-wasm-modules` is enabled and the file at _url_ 1026> contains the header for a WebAssembly module, then 1027> 1. Return _"wasm"_. 1028> 2. Otherwise, 1029> 1. Return _"module"_. 1030> 2. Return **undefined**. 1031> 8. Otherwise, 1032> 1. Return **undefined**. 1033 1034**LOOKUP\_PACKAGE\_SCOPE**(_url_) 1035 1036> 1. Let _scopeURL_ be _url_. 1037> 2. While _scopeURL_ is not the file system root, 1038> 1. Set _scopeURL_ to the parent URL of _scopeURL_. 1039> 2. If _scopeURL_ ends in a _"node\_modules"_ path segment, return **null**. 1040> 3. Let _pjsonURL_ be the resolution of _"package.json"_ within 1041> _scopeURL_. 1042> 4. if the file at _pjsonURL_ exists, then 1043> 1. Return _scopeURL_. 1044> 3. Return **null**. 1045 1046**READ\_PACKAGE\_JSON**(_packageURL_) 1047 1048> 1. Let _pjsonURL_ be the resolution of _"package.json"_ within _packageURL_. 1049> 2. If the file at _pjsonURL_ does not exist, then 1050> 1. Return **null**. 1051> 3. If the file at _packageURL_ does not parse as valid JSON, then 1052> 1. Throw an _Invalid Package Configuration_ error. 1053> 4. Return the parsed JSON source of the file at _pjsonURL_. 1054 1055### Customizing ESM specifier resolution algorithm 1056 1057> Stability: 1 - Experimental 1058 1059> Do not rely on this flag. We plan to remove it once the 1060> [Module customization hooks][] have advanced to the point that equivalent 1061> functionality can be achieved via custom hooks. 1062 1063The current specifier resolution does not support all default behavior of 1064the CommonJS loader. One of the behavior differences is automatic resolution 1065of file extensions and the ability to import directories that have an index 1066file. 1067 1068The `--experimental-specifier-resolution=[mode]` flag can be used to customize 1069the extension resolution algorithm. The default mode is `explicit`, which 1070requires the full path to a module be provided to the loader. To enable the 1071automatic extension resolution and importing from directories that include an 1072index file use the `node` mode. 1073 1074```console 1075$ node index.mjs 1076success! 1077$ node index # Failure! 1078Error: Cannot find module 1079$ node --experimental-specifier-resolution=node index 1080success! 1081``` 1082 1083<!-- Note: The cjs-module-lexer link should be kept in-sync with the deps version --> 1084 1085[6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index 1086[Addons]: addons.md 1087[CommonJS]: modules.md 1088[Core modules]: modules.md#core-modules 1089[Determining module system]: packages.md#determining-module-system 1090[Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import 1091[ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration 1092[Import Attributes]: #import-attributes 1093[Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes 1094[JSON modules]: #json-modules 1095[Module customization hooks]: module.md#customization-hooks 1096[Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification 1097[Terminology]: #terminology 1098[URL]: https://url.spec.whatwg.org/ 1099[`"exports"`]: packages.md#exports 1100[`"type"`]: packages.md#type 1101[`--experimental-default-type`]: cli.md#--experimental-default-typetype 1102[`--input-type`]: cli.md#--input-typetype 1103[`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs 1104[`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export 1105[`import()`]: #import-expressions 1106[`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve 1107[`import.meta.url`]: #importmetaurl 1108[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import 1109[`module.createRequire()`]: module.md#modulecreaterequirefilename 1110[`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports 1111[`package.json`]: packages.md#nodejs-packagejson-field-definitions 1112[`process.dlopen`]: process.md#processdlopenmodule-filename-flags 1113[cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 1114[custom https loader]: module.md#import-from-https 1115[import.meta.resolve]: #importmetaresolvespecifier 1116[percent-encoded]: url.md#percent-encoding-in-urls 1117[special scheme]: https://url.spec.whatwg.org/#special-scheme 1118[status code]: process.md#exit-codes 1119[the official standard format]: https://tc39.github.io/ecma262/#sec-modules 1120[url.pathToFileURL]: url.md#urlpathtofileurlpath 1121