| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 80f86e5 commit 5f7fad2
63 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -877,6 +877,18 @@ added: v11.8.0 | |||
| 877 | 877 | ||
| 878 | 878 | Use the specified file as a security policy. | |
| 879 | 879 | ||
| 880 | + ### `--experimental-require-module` | ||
| 881 | + | ||
| 882 | + <!-- YAML | ||
| 883 | + added: REPLACEME | ||
| 884 | + --> | ||
| 885 | + | ||
| 886 | + > Stability: 1.1 - Active Developement | ||
| 887 | + | ||
| 888 | + Supports loading a synchronous ES module graph in `require()`. | ||
| 889 | + | ||
| 890 | + See [Loading ECMAScript modules using `require()`][]. | ||
| 891 | + | ||
| 880 | 892 | ### `--experimental-sea-config` | |
| 881 | 893 | ||
| 882 | 894 | <!-- YAML | |
@@ -1584,6 +1596,18 @@ changes: | |||
| 1584 | 1596 | ||
| 1585 | 1597 | Identical to `-e` but prints the result. | |
| 1586 | 1598 | ||
| 1599 | + ### `--experimental-print-required-tla` | ||
| 1600 | + | ||
| 1601 | + <!-- YAML | ||
| 1602 | + added: REPLACEME | ||
| 1603 | + --> | ||
| 1604 | + | ||
| 1605 | + This flag is only useful when `--experimental-require-module` is enabled. | ||
| 1606 | + | ||
| 1607 | + If the ES module being `require()`'d contains top-level await, this flag | ||
| 1608 | + allows Node.js to evaluate the module, try to locate the | ||
| 1609 | + top-level awaits, and print their location to help users find them. | ||
| 1610 | + | ||
| 1587 | 1611 | ### `--prof` | |
| 1588 | 1612 | ||
| 1589 | 1613 | <!-- YAML | |
@@ -2534,6 +2558,8 @@ Node.js options that are allowed are: | |||
| 2534 | 2558 | * `--experimental-network-imports` | |
| 2535 | 2559 | * `--experimental-permission` | |
| 2536 | 2560 | * `--experimental-policy` | |
| 2561 | + * `--experimental-print-required-tla` | ||
| 2562 | + * `--experimental-require-module` | ||
| 2537 | 2563 | * `--experimental-shadow-realm` | |
| 2538 | 2564 | * `--experimental-specifier-resolution` | |
| 2539 | 2565 | * `--experimental-top-level-await` | |
@@ -3038,6 +3064,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 | |||
| 3038 | 3064 | [ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions | |
| 3039 | 3065 | [Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | |
| 3040 | 3066 | [File System Permissions]: permissions.md#file-system-permissions | |
| 3067 | + [Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require | ||
| 3041 | 3068 | [Module customization hooks]: module.md#customization-hooks | |
| 3042 | 3069 | [Module customization hooks: enabling]: module.md#enabling | |
| 3043 | 3070 | [Modules loaders]: packages.md#modules-loaders | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2487,6 +2487,19 @@ Accessing `Object.prototype.__proto__` has been forbidden using | |||
| 2487 | 2487 | [`Object.setPrototypeOf`][] should be used to get and set the prototype of an | |
| 2488 | 2488 | object. | |
| 2489 | 2489 | ||
| 2490 | + <a id="ERR_REQUIRE_ASYNC_MODULE"></a> | ||
| 2491 | + | ||
| 2492 | + ### `ERR_REQUIRE_ASYNC_MODULE` | ||
| 2493 | + | ||
| 2494 | + > Stability: 1 - Experimental | ||
| 2495 | + | ||
| 2496 | + When trying to `require()` a [ES Module][] under `--experimental-require-module`, | ||
| 2497 | + the module turns out to be asynchronous. That is, it contains top-level await. | ||
| 2498 | + | ||
| 2499 | + To see where the top-level await is, use | ||
| 2500 | + `--experimental-print-required-tla` (this would execute the modules | ||
| 2501 | + before looking for the top-level awaits). | ||
| 2502 | + | ||
| 2490 | 2503 | <a id="ERR_REQUIRE_ESM"></a> | |
| 2491 | 2504 | ||
| 2492 | 2505 | ### `ERR_REQUIRE_ESM` | |
@@ -2495,6 +2508,9 @@ object. | |||
| 2495 | 2508 | ||
| 2496 | 2509 | An attempt was made to `require()` an [ES Module][]. | |
| 2497 | 2510 | ||
| 2511 | + To enable `require()` for synchronous module graphs (without | ||
| 2512 | + top-level `await`), use `--experimental-require-module`. | ||
| 2513 | + | ||
| 2498 | 2514 | <a id="ERR_SCRIPT_EXECUTION_INTERRUPTED"></a> | |
| 2499 | 2515 | ||
| 2500 | 2516 | ### `ERR_SCRIPT_EXECUTION_INTERRUPTED` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -466,11 +466,10 @@ compatibility. | |||
| 466 | 466 | ||
| 467 | 467 | ### `require` | |
| 468 | 468 | ||
| 469 | - The CommonJS module `require` always treats the files it references as CommonJS. | ||
| 469 | + The CommonJS module `require` currently only supports loading synchronous ES | ||
| 470 | + modules when `--experimental-require-module` is enabled. | ||
| 470 | 471 | ||
| 471 | - Using `require` to load an ES module is not supported because ES modules have | ||
| 472 | - asynchronous execution. Instead, use [`import()`][] to load an ES module | ||
| 473 | - from a CommonJS module. | ||
| 472 | + See [Loading ECMAScript modules using `require()`][] for details. | ||
| 474 | 473 | ||
| 475 | 474 | ### CommonJS Namespaces | |
| 476 | 475 | ||
@@ -1142,6 +1141,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][]. | |||
| 1142 | 1141 | [Import Attributes]: #import-attributes | |
| 1143 | 1142 | [Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes | |
| 1144 | 1143 | [JSON modules]: #json-modules | |
| 1144 | + [Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require | ||
| 1145 | 1145 | [Module customization hooks]: module.md#customization-hooks | |
| 1146 | 1146 | [Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification | |
| 1147 | 1147 | [Terminology]: #terminology | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,16 +167,60 @@ variable. Since the module lookups using `node_modules` folders are all | |||
| 167 | 167 | relative, and based on the real path of the files making the calls to | |
| 168 | 168 | `require()`, the packages themselves can be anywhere. | |
| 169 | 169 | ||
| 170 | - ## The `.mjs` extension | ||
| 170 | + ## Loading ECMAScript modules using `require()` | ||
| 171 | 171 | ||
| 172 | - Due to the synchronous nature of `require()`, it is not possible to use it to | ||
| 173 | - load ECMAScript module files. Attempting to do so will throw a | ||
| 174 | - [`ERR_REQUIRE_ESM`][] error. Use [`import()`][] instead. | ||
| 175 | - | ||
| 176 | - The `.mjs` extension is reserved for [ECMAScript Modules][] which cannot be | ||
| 177 | - loaded via `require()`. See [Determining module system][] section for more info | ||
| 172 | + The `.mjs` extension is reserved for [ECMAScript Modules][]. | ||
| 173 | + Currently, if the flag `--experimental-require-module` is not used, loading | ||
| 174 | + an ECMAScript module using `require()` will throw a [`ERR_REQUIRE_ESM`][] | ||
| 175 | + error, and users need to use [`import()`][] instead. See | ||
| 176 | + [Determining module system][] section for more info | ||
| 178 | 177 | regarding which files are parsed as ECMAScript modules. | |
| 179 | 178 | ||
| 179 | + If `--experimental-require-module` is enabled, and the ECMAScript module being | ||
| 180 | + loaded by `require()` meets the following requirements: | ||
| 181 | + | ||
| 182 | + * Explicitly marked as an ES module with a `"type": "module"` field in | ||
| 183 | + the closest package.json or a `.mjs` extension. | ||
| 184 | + * Fully synchronous (contains no top-level `await`). | ||
| 185 | + | ||
| 186 | + `require()` will load the requested module as an ES Module, and return | ||
| 187 | + the module name space object. In this case it is similar to dynamic | ||
| 188 | + `import()` but is run synchronously and returns the name space object | ||
| 189 | + directly. | ||
| 190 | + | ||
| 191 | + ```mjs | ||
| 192 | + // point.mjs | ||
| 193 | + export function distance(a, b) { return (b.x - a.x) ** 2 + (b.y - a.y) ** 2; } | ||
| 194 | + class Point { | ||
| 195 | + constructor(x, y) { this.x = x; this.y = y; } | ||
| 196 | + } | ||
| 197 | + export default Point; | ||
| 198 | + ``` | ||
| 199 | + | ||
| 200 | + ```cjs | ||
| 201 | + const required = require('./point.mjs'); | ||
| 202 | + // [Module: null prototype] { | ||
| 203 | + // default: [class Point], | ||
| 204 | + // distance: [Function: distance] | ||
| 205 | + // } | ||
| 206 | + console.log(required); | ||
| 207 | + | ||
| 208 | + (async () => { | ||
| 209 | + const imported = await import('./point.mjs'); | ||
| 210 | + console.log(imported === required); // true | ||
| 211 | + })(); | ||
| 212 | + ``` | ||
| 213 | + | ||
| 214 | + If the module being `require()`'d contains top-level `await`, or the module | ||
| 215 | + graph it `import`s contains top-level `await`, | ||
| 216 | + [`ERR_REQUIRE_ASYNC_MODULE`][] will be thrown. In this case, users should | ||
| 217 | + load the asynchronous module using `import()`. | ||
| 218 | + | ||
| 219 | + If `--experimental-print-required-tla` is enabled, instead of throwing | ||
| 220 | + `ERR_REQUIRE_ASYNC_MODULE` before evaluation, Node.js will evaluate the | ||
| 221 | + module, try to locate the top-level awaits, and print their location to | ||
| 222 | + help users fix them. | ||
| 223 | + | ||
| 180 | 224 | ## All together | |
| 181 | 225 | ||
| 182 | 226 | <!-- type=misc --> | |
@@ -206,12 +250,24 @@ require(X) from module at path Y | |||
| 206 | 250 | ||
| 207 | 251 | LOAD_AS_FILE(X) | |
| 208 | 252 | 1. If X is a file, load X as its file extension format. STOP | |
| 209 | - 2. If X.js is a file, load X.js as JavaScript text. STOP | ||
| 210 | - 3. If X.json is a file, parse X.json to a JavaScript Object. STOP | ||
| 253 | + 2. If X.js is a file, | ||
| 254 | + a. Find the closest package scope SCOPE to X. | ||
| 255 | + b. If no scope was found, load X.js as a CommonJS module. STOP. | ||
| 256 | + c. If the SCOPE/package.json contains "type" field, | ||
| 257 | + 1. If the "type" field is "module", load X.js as an ECMAScript module. STOP. | ||
| 258 | + 2. Else, load X.js as an CommonJS module. STOP. | ||
| 259 | + 3. If X.json is a file, load X.json to a JavaScript Object. STOP | ||
| 211 | 260 | 4. If X.node is a file, load X.node as binary addon. STOP | |
| 261 | + 5. If X.mjs is a file, and `--experimental-require-module` is enabled, | ||
| 262 | + load X.mjs as an ECMAScript module. STOP | ||
| 212 | 263 | ||
| 213 | 264 | LOAD_INDEX(X) | |
| 214 | - 1. If X/index.js is a file, load X/index.js as JavaScript text. STOP | ||
| 265 | + 1. If X/index.js is a file | ||
| 266 | + a. Find the closest package scope SCOPE to X. | ||
| 267 | + b. If no scope was found, load X/index.js as a CommonJS module. STOP. | ||
| 268 | + c. If the SCOPE/package.json contains "type" field, | ||
| 269 | + 1. If the "type" field is "module", load X/index.js as an ECMAScript module. STOP. | ||
| 270 | + 2. Else, load X/index.js as an CommonJS module. STOP. | ||
| 215 | 271 | 2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP | |
| 216 | 272 | 3. If X/index.node is a file, load X/index.node as binary addon. STOP | |
| 217 | 273 | ||
@@ -1085,6 +1141,7 @@ This section was moved to | |||
| 1085 | 1141 | [GLOBAL_FOLDERS]: #loading-from-the-global-folders | |
| 1086 | 1142 | [`"main"`]: packages.md#main | |
| 1087 | 1143 | [`"type"`]: packages.md#type | |
| 1144 | + [`ERR_REQUIRE_ASYNC_MODULE`]: errors.md#err_require_async_module | ||
| 1088 | 1145 | [`ERR_REQUIRE_ESM`]: errors.md#err_require_esm | |
| 1089 | 1146 | [`ERR_UNSUPPORTED_DIR_IMPORT`]: errors.md#err_unsupported_dir_import | |
| 1090 | 1147 | [`MODULE_NOT_FOUND`]: errors.md#module_not_found | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -133,14 +133,15 @@ There is the CommonJS module loader: | |||
| 133 | 133 | `process.dlopen()`. | |
| 134 | 134 | * It treats all files that lack `.json` or `.node` extensions as JavaScript | |
| 135 | 135 | text files. | |
| 136 | - * It cannot be used to load ECMAScript modules (although it is possible to | ||
| 137 | - [load ECMASCript modules from CommonJS modules][]). When used to load a | ||
| 138 | - JavaScript text file that is not an ECMAScript module, it loads it as a | ||
| 139 | - CommonJS module. | ||
| 136 | + * It can only be used to [load ECMASCript modules from CommonJS modules][] if | ||
| 137 | + the module graph is synchronous (that contains no top-level `await`) when | ||
| 138 | + `--experimental-require-module` is enabled. | ||
| 139 | + When used to load a JavaScript text file that is not an ECMAScript module, | ||
| 140 | + the file will be loaded as a CommonJS module. | ||
| 140 | 141 | ||
| 141 | 142 | There is the ECMAScript module loader: | |
| 142 | 143 | ||
| 143 | - * It is asynchronous. | ||
| 144 | + * It is asynchronous, unless it's being used to load modules for `require()`. | ||
| 144 | 145 | * It is responsible for handling `import` statements and `import()` expressions. | |
| 145 | 146 | * It is not monkey patchable, can be customized using [loader hooks][]. | |
| 146 | 147 | * It does not support folders as modules, directory indexes (e.g. | |
@@ -623,9 +624,9 @@ specific to least specific as conditions should be defined: | |||
| 623 | 624 | * `"require"` - matches when the package is loaded via `require()`. The | |
| 624 | 625 | referenced file should be loadable with `require()` although the condition | |
| 625 | 626 | matches regardless of the module format of the target file. Expected | |
| 626 | - formats include CommonJS, JSON, and native addons but not ES modules as | ||
| 627 | - `require()` doesn't support them. _Always mutually exclusive with | ||
| 628 | - `"import"`._ | ||
| 627 | + formats include CommonJS, JSON, native addons, and ES modules | ||
| 628 | + if `--experimental-require-module` is enabled. _Always mutually | ||
| 629 | + exclusive with `"import"`._ | ||
| 629 | 630 | * `"default"` - the generic fallback that always matches. Can be a CommonJS | |
| 630 | 631 | or ES module file. _This condition should always come last._ | |
| 631 | 632 | ||
@@ -1371,7 +1372,7 @@ This field defines [subpath imports][] for the current package. | |||
| 1371 | 1372 | [entry points]: #package-entry-points | |
| 1372 | 1373 | [folders as modules]: modules.md#folders-as-modules | |
| 1373 | 1374 | [import maps]: https://github.com/WICG/import-maps | |
| 1374 | - [load ECMASCript modules from CommonJS modules]: modules.md#the-mjs-extension | ||
| 1375 | + [load ECMASCript modules from CommonJS modules]: modules.md#loading-ecmascript-modules-using-require | ||
| 1375 | 1376 | [loader hooks]: esm.md#loaders | |
| 1376 | 1377 | [packages folder mapping]: https://github.com/WICG/import-maps#packages-via-trailing-slashes | |
| 1377 | 1378 | [self-reference]: #self-referencing-a-package-using-its-name | |
| Back | FazBrowse Home | New Git URL |
0 commit comments