| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 30b859f commit cad46af
63 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -974,6 +974,18 @@ added: v11.8.0 | |||
| 974 | 974 | ||
| 975 | 975 | Use the specified file as a security policy. | |
| 976 | 976 | ||
| 977 | + ### `--experimental-require-module` | ||
| 978 | + | ||
| 979 | + <!-- YAML | ||
| 980 | + added: REPLACEME | ||
| 981 | + --> | ||
| 982 | + | ||
| 983 | + > Stability: 1.1 - Active Developement | ||
| 984 | + | ||
| 985 | + Supports loading a synchronous ES module graph in `require()`. | ||
| 986 | + | ||
| 987 | + See [Loading ECMAScript modules using `require()`][]. | ||
| 988 | + | ||
| 977 | 989 | ### `--experimental-sea-config` | |
| 978 | 990 | ||
| 979 | 991 | <!-- YAML | |
@@ -1695,6 +1707,18 @@ changes: | |||
| 1695 | 1707 | ||
| 1696 | 1708 | Identical to `-e` but prints the result. | |
| 1697 | 1709 | ||
| 1710 | + ### `--experimental-print-required-tla` | ||
| 1711 | + | ||
| 1712 | + <!-- YAML | ||
| 1713 | + added: REPLACEME | ||
| 1714 | + --> | ||
| 1715 | + | ||
| 1716 | + This flag is only useful when `--experimental-require-module` is enabled. | ||
| 1717 | + | ||
| 1718 | + If the ES module being `require()`'d contains top-level await, this flag | ||
| 1719 | + allows Node.js to evaluate the module, try to locate the | ||
| 1720 | + top-level awaits, and print their location to help users find them. | ||
| 1721 | + | ||
| 1698 | 1722 | ### `--prof` | |
| 1699 | 1723 | ||
| 1700 | 1724 | <!-- YAML | |
@@ -2642,6 +2666,8 @@ one is included in the list below. | |||
| 2642 | 2666 | * `--experimental-network-imports` | |
| 2643 | 2667 | * `--experimental-permission` | |
| 2644 | 2668 | * `--experimental-policy` | |
| 2669 | + * `--experimental-print-required-tla` | ||
| 2670 | + * `--experimental-require-module` | ||
| 2645 | 2671 | * `--experimental-shadow-realm` | |
| 2646 | 2672 | * `--experimental-specifier-resolution` | |
| 2647 | 2673 | * `--experimental-top-level-await` | |
@@ -3111,6 +3137,7 @@ done | |||
| 3111 | 3137 | [ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions | |
| 3112 | 3138 | [Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | |
| 3113 | 3139 | [File System Permissions]: permissions.md#file-system-permissions | |
| 3140 | + [Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require | ||
| 3114 | 3141 | [Module customization hooks]: module.md#customization-hooks | |
| 3115 | 3142 | [Module customization hooks: enabling]: module.md#enabling | |
| 3116 | 3143 | [Modules loaders]: packages.md#modules-loaders | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2521,6 +2521,19 @@ Accessing `Object.prototype.__proto__` has been forbidden using | |||
| 2521 | 2521 | [`Object.setPrototypeOf`][] should be used to get and set the prototype of an | |
| 2522 | 2522 | object. | |
| 2523 | 2523 | ||
| 2524 | + <a id="ERR_REQUIRE_ASYNC_MODULE"></a> | ||
| 2525 | + | ||
| 2526 | + ### `ERR_REQUIRE_ASYNC_MODULE` | ||
| 2527 | + | ||
| 2528 | + > Stability: 1 - Experimental | ||
| 2529 | + | ||
| 2530 | + When trying to `require()` a [ES Module][] under `--experimental-require-module`, | ||
| 2531 | + the module turns out to be asynchronous. That is, it contains top-level await. | ||
| 2532 | + | ||
| 2533 | + To see where the top-level await is, use | ||
| 2534 | + `--experimental-print-required-tla` (this would execute the modules | ||
| 2535 | + before looking for the top-level awaits). | ||
| 2536 | + | ||
| 2524 | 2537 | <a id="ERR_REQUIRE_ESM"></a> | |
| 2525 | 2538 | ||
| 2526 | 2539 | ### `ERR_REQUIRE_ESM` | |
@@ -2529,6 +2542,9 @@ object. | |||
| 2529 | 2542 | ||
| 2530 | 2543 | An attempt was made to `require()` an [ES Module][]. | |
| 2531 | 2544 | ||
| 2545 | + To enable `require()` for synchronous module graphs (without | ||
| 2546 | + top-level `await`), use `--experimental-require-module`. | ||
| 2547 | + | ||
| 2532 | 2548 | <a id="ERR_SCRIPT_EXECUTION_INTERRUPTED"></a> | |
| 2533 | 2549 | ||
| 2534 | 2550 | ### `ERR_SCRIPT_EXECUTION_INTERRUPTED` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -449,11 +449,10 @@ compatibility. | |||
| 449 | 449 | ||
| 450 | 450 | ### `require` | |
| 451 | 451 | ||
| 452 | - The CommonJS module `require` always treats the files it references as CommonJS. | ||
| 452 | + The CommonJS module `require` currently only supports loading synchronous ES | ||
| 453 | + modules when `--experimental-require-module` is enabled. | ||
| 453 | 454 | ||
| 454 | - Using `require` to load an ES module is not supported because ES modules have | ||
| 455 | - asynchronous execution. Instead, use [`import()`][] to load an ES module | ||
| 456 | - from a CommonJS module. | ||
| 455 | + See [Loading ECMAScript modules using `require()`][] for details. | ||
| 457 | 456 | ||
| 458 | 457 | ### CommonJS Namespaces | |
| 459 | 458 | ||
@@ -1132,6 +1131,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][]. | |||
| 1132 | 1131 | [Import Attributes]: #import-attributes | |
| 1133 | 1132 | [Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes | |
| 1134 | 1133 | [JSON modules]: #json-modules | |
| 1134 | + [Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require | ||
| 1135 | 1135 | [Module customization hooks]: module.md#customization-hooks | |
| 1136 | 1136 | [Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification | |
| 1137 | 1137 | [Terminology]: #terminology | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -168,16 +168,60 @@ variable. Since the module lookups using `node_modules` folders are all | |||
| 168 | 168 | relative, and based on the real path of the files making the calls to | |
| 169 | 169 | `require()`, the packages themselves can be anywhere. | |
| 170 | 170 | ||
| 171 | - ## The `.mjs` extension | ||
| 171 | + ## Loading ECMAScript modules using `require()` | ||
| 172 | 172 | ||
| 173 | - Due to the synchronous nature of `require()`, it is not possible to use it to | ||
| 174 | - load ECMAScript module files. Attempting to do so will throw a | ||
| 175 | - [`ERR_REQUIRE_ESM`][] error. Use [`import()`][] instead. | ||
| 176 | - | ||
| 177 | - The `.mjs` extension is reserved for [ECMAScript Modules][] which cannot be | ||
| 178 | - loaded via `require()`. See [Determining module system][] section for more info | ||
| 173 | + The `.mjs` extension is reserved for [ECMAScript Modules][]. | ||
| 174 | + Currently, if the flag `--experimental-require-module` is not used, loading | ||
| 175 | + an ECMAScript module using `require()` will throw a [`ERR_REQUIRE_ESM`][] | ||
| 176 | + error, and users need to use [`import()`][] instead. See | ||
| 177 | + [Determining module system][] section for more info | ||
| 179 | 178 | regarding which files are parsed as ECMAScript modules. | |
| 180 | 179 | ||
| 180 | + If `--experimental-require-module` is enabled, and the ECMAScript module being | ||
| 181 | + loaded by `require()` meets the following requirements: | ||
| 182 | + | ||
| 183 | + * Explicitly marked as an ES module with a `"type": "module"` field in | ||
| 184 | + the closest package.json or a `.mjs` extension. | ||
| 185 | + * Fully synchronous (contains no top-level `await`). | ||
| 186 | + | ||
| 187 | + `require()` will load the requested module as an ES Module, and return | ||
| 188 | + the module name space object. In this case it is similar to dynamic | ||
| 189 | + `import()` but is run synchronously and returns the name space object | ||
| 190 | + directly. | ||
| 191 | + | ||
| 192 | + ```mjs | ||
| 193 | + // point.mjs | ||
| 194 | + export function distance(a, b) { return (b.x - a.x) ** 2 + (b.y - a.y) ** 2; } | ||
| 195 | + class Point { | ||
| 196 | + constructor(x, y) { this.x = x; this.y = y; } | ||
| 197 | + } | ||
| 198 | + export default Point; | ||
| 199 | + ``` | ||
| 200 | + | ||
| 201 | + ```cjs | ||
| 202 | + const required = require('./point.mjs'); | ||
| 203 | + // [Module: null prototype] { | ||
| 204 | + // default: [class Point], | ||
| 205 | + // distance: [Function: distance] | ||
| 206 | + // } | ||
| 207 | + console.log(required); | ||
| 208 | + | ||
| 209 | + (async () => { | ||
| 210 | + const imported = await import('./point.mjs'); | ||
| 211 | + console.log(imported === required); // true | ||
| 212 | + })(); | ||
| 213 | + ``` | ||
| 214 | + | ||
| 215 | + If the module being `require()`'d contains top-level `await`, or the module | ||
| 216 | + graph it `import`s contains top-level `await`, | ||
| 217 | + [`ERR_REQUIRE_ASYNC_MODULE`][] will be thrown. In this case, users should | ||
| 218 | + load the asynchronous module using `import()`. | ||
| 219 | + | ||
| 220 | + If `--experimental-print-required-tla` is enabled, instead of throwing | ||
| 221 | + `ERR_REQUIRE_ASYNC_MODULE` before evaluation, Node.js will evaluate the | ||
| 222 | + module, try to locate the top-level awaits, and print their location to | ||
| 223 | + help users fix them. | ||
| 224 | + | ||
| 181 | 225 | ## All together | |
| 182 | 226 | ||
| 183 | 227 | <!-- type=misc --> | |
@@ -207,12 +251,24 @@ require(X) from module at path Y | |||
| 207 | 251 | ||
| 208 | 252 | LOAD_AS_FILE(X) | |
| 209 | 253 | 1. If X is a file, load X as its file extension format. STOP | |
| 210 | - 2. If X.js is a file, load X.js as JavaScript text. STOP | ||
| 211 | - 3. If X.json is a file, parse X.json to a JavaScript Object. STOP | ||
| 254 | + 2. If X.js is a file, | ||
| 255 | + a. Find the closest package scope SCOPE to X. | ||
| 256 | + b. If no scope was found, load X.js as a CommonJS module. STOP. | ||
| 257 | + c. If the SCOPE/package.json contains "type" field, | ||
| 258 | + 1. If the "type" field is "module", load X.js as an ECMAScript module. STOP. | ||
| 259 | + 2. Else, load X.js as an CommonJS module. STOP. | ||
| 260 | + 3. If X.json is a file, load X.json to a JavaScript Object. STOP | ||
| 212 | 261 | 4. If X.node is a file, load X.node as binary addon. STOP | |
| 262 | + 5. If X.mjs is a file, and `--experimental-require-module` is enabled, | ||
| 263 | + load X.mjs as an ECMAScript module. STOP | ||
| 213 | 264 | ||
| 214 | 265 | LOAD_INDEX(X) | |
| 215 | - 1. If X/index.js is a file, load X/index.js as JavaScript text. STOP | ||
| 266 | + 1. If X/index.js is a file | ||
| 267 | + a. Find the closest package scope SCOPE to X. | ||
| 268 | + b. If no scope was found, load X/index.js as a CommonJS module. STOP. | ||
| 269 | + c. If the SCOPE/package.json contains "type" field, | ||
| 270 | + 1. If the "type" field is "module", load X/index.js as an ECMAScript module. STOP. | ||
| 271 | + 2. Else, load X/index.js as an CommonJS module. STOP. | ||
| 216 | 272 | 2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP | |
| 217 | 273 | 3. If X/index.node is a file, load X/index.node as binary addon. STOP | |
| 218 | 274 | ||
@@ -1097,6 +1153,7 @@ This section was moved to | |||
| 1097 | 1153 | [GLOBAL_FOLDERS]: #loading-from-the-global-folders | |
| 1098 | 1154 | [`"main"`]: packages.md#main | |
| 1099 | 1155 | [`"type"`]: packages.md#type | |
| 1156 | + [`ERR_REQUIRE_ASYNC_MODULE`]: errors.md#err_require_async_module | ||
| 1100 | 1157 | [`ERR_REQUIRE_ESM`]: errors.md#err_require_esm | |
| 1101 | 1158 | [`ERR_UNSUPPORTED_DIR_IMPORT`]: errors.md#err_unsupported_dir_import | |
| 1102 | 1159 | [`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