| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 17fd327 commit 06206af
23 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1034,6 +1034,10 @@ following permissions are restricted: | |||
| 1034 | 1034 | added: | |
| 1035 | 1035 | - v22.0.0 | |
| 1036 | 1036 | - v20.17.0 | |
| 1037 | + changes: | ||
| 1038 | + - version: REPLACEME | ||
| 1039 | + pr-url: https://github.com/nodejs/node/pull/55085 | ||
| 1040 | + description: This is now true by default. | ||
| 1037 | 1041 | --> | |
| 1038 | 1042 | ||
| 1039 | 1043 | > Stability: 1.1 - Active Development | |
@@ -1659,6 +1663,24 @@ added: v16.6.0 | |||
| 1659 | 1663 | ||
| 1660 | 1664 | Use this flag to disable top-level await in REPL. | |
| 1661 | 1665 | ||
| 1666 | + ### `--no-experimental-require-module` | ||
| 1667 | + | ||
| 1668 | + <!-- YAML | ||
| 1669 | + added: | ||
| 1670 | + - v22.0.0 | ||
| 1671 | + - v20.17.0 | ||
| 1672 | + changes: | ||
| 1673 | + - version: REPLACEME | ||
| 1674 | + pr-url: https://github.com/nodejs/node/pull/55085 | ||
| 1675 | + description: This is now false by default. | ||
| 1676 | + --> | ||
| 1677 | + | ||
| 1678 | + > Stability: 1.1 - Active Development | ||
| 1679 | + | ||
| 1680 | + Disable support for loading a synchronous ES module graph in `require()`. | ||
| 1681 | + | ||
| 1682 | + See [Loading ECMAScript modules using `require()`][]. | ||
| 1683 | + | ||
| 1662 | 1684 | ### `--no-experimental-websocket` | |
| 1663 | 1685 | ||
| 1664 | 1686 | <!-- YAML | |
@@ -1875,9 +1897,7 @@ added: | |||
| 1875 | 1897 | - v20.17.0 | |
| 1876 | 1898 | --> | |
| 1877 | 1899 | ||
| 1878 | - This flag is only useful when `--experimental-require-module` is enabled. | ||
| 1879 | - | ||
| 1880 | - If the ES module being `require()`'d contains top-level await, this flag | ||
| 1900 | + If the ES module being `require()`'d contains top-level `await`, this flag | ||
| 1881 | 1901 | allows Node.js to evaluate the module, try to locate the | |
| 1882 | 1902 | top-level awaits, and print their location to help users find them. | |
| 1883 | 1903 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2426,8 +2426,8 @@ object. | |||
| 2426 | 2426 | ||
| 2427 | 2427 | > Stability: 1 - Experimental | |
| 2428 | 2428 | ||
| 2429 | - When trying to `require()` a [ES Module][] under `--experimental-require-module`, | ||
| 2430 | - a CommonJS to ESM or ESM to CommonJS edge participates in an immediate cycle. | ||
| 2429 | + When trying to `require()` a [ES Module][], a CommonJS to ESM or ESM to CommonJS edge | ||
| 2430 | + participates in an immediate cycle. | ||
| 2431 | 2431 | This is not allowed because ES Modules cannot be evaluated while they are | |
| 2432 | 2432 | already being evaluated. | |
| 2433 | 2433 | ||
@@ -2441,8 +2441,8 @@ module, and should be done lazily in an inner function. | |||
| 2441 | 2441 | ||
| 2442 | 2442 | > Stability: 1 - Experimental | |
| 2443 | 2443 | ||
| 2444 | - When trying to `require()` a [ES Module][] under `--experimental-require-module`, | ||
| 2445 | - the module turns out to be asynchronous. That is, it contains top-level await. | ||
| 2444 | + When trying to `require()` a [ES Module][], the module turns out to be asynchronous. | ||
| 2445 | + That is, it contains top-level await. | ||
| 2446 | 2446 | ||
| 2447 | 2447 | To see where the top-level await is, use | |
| 2448 | 2448 | `--experimental-print-required-tla` (this would execute the modules | |
@@ -2452,12 +2452,20 @@ before looking for the top-level awaits). | |||
| 2452 | 2452 | ||
| 2453 | 2453 | ### `ERR_REQUIRE_ESM` | |
| 2454 | 2454 | ||
| 2455 | - > Stability: 1 - Experimental | ||
| 2455 | + <!-- YAML | ||
| 2456 | + changes: | ||
| 2457 | + - version: REPLACEME | ||
| 2458 | + pr-url: https://github.com/nodejs/node/pull/55085 | ||
| 2459 | + description: require() now supports loading synchronous ES modules by default. | ||
| 2460 | + --> | ||
| 2461 | + | ||
| 2462 | + > Stability: 0 - Deprecated | ||
| 2456 | 2463 | ||
| 2457 | 2464 | An attempt was made to `require()` an [ES Module][]. | |
| 2458 | 2465 | ||
| 2459 | - To enable `require()` for synchronous module graphs (without | ||
| 2460 | - top-level `await`), use `--experimental-require-module`. | ||
| 2466 | + This error has been deprecated since `require()` now supports loading synchronous | ||
| 2467 | + ES modules. When `require()` encounters an ES module that contains top-level | ||
| 2468 | + `await`, it will throw [`ERR_REQUIRE_ASYNC_MODULE`][] instead. | ||
| 2461 | 2469 | ||
| 2462 | 2470 | <a id="ERR_SCRIPT_EXECUTION_INTERRUPTED"></a> | |
| 2463 | 2471 | ||
@@ -4061,6 +4069,7 @@ Type stripping is not supported for files descendent of a `node_modules` directo | |||
| 4061 | 4069 | [`ERR_INVALID_ARG_TYPE`]: #err_invalid_arg_type | |
| 4062 | 4070 | [`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: #err_missing_message_port_in_transfer_list | |
| 4063 | 4071 | [`ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST`]: #err_missing_transferable_in_transfer_list | |
| 4072 | + [`ERR_REQUIRE_ASYNC_MODULE`]: #err_require_async_module | ||
| 4064 | 4073 | [`EventEmitter`]: events.md#class-eventemitter | |
| 4065 | 4074 | [`MessagePort`]: worker_threads.md#class-messageport | |
| 4066 | 4075 | [`Object.getPrototypeOf`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -468,7 +468,7 @@ compatibility. | |||
| 468 | 468 | ### `require` | |
| 469 | 469 | ||
| 470 | 470 | The CommonJS module `require` currently only supports loading synchronous ES | |
| 471 | - modules when `--experimental-require-module` is enabled. | ||
| 471 | + modules (that is, ES modules that do not use top-level `await`). | ||
| 472 | 472 | ||
| 473 | 473 | See [Loading ECMAScript modules using `require()`][] for details. | |
| 474 | 474 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -170,15 +170,18 @@ relative, and based on the real path of the files making the calls to | |||
| 170 | 170 | ||
| 171 | 171 | ## Loading ECMAScript modules using `require()` | |
| 172 | 172 | ||
| 173 | + <!-- YAML | ||
| 174 | + changes: | ||
| 175 | + - version: REPLACEME | ||
| 176 | + pr-url: https://github.com/nodejs/node/pull/55085 | ||
| 177 | + description: require() now supports loading synchronous ES modules by default. | ||
| 178 | + --> | ||
| 179 | + | ||
| 173 | 180 | 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 | ||
| 181 | + See [Determining module system][] section for more info | ||
| 178 | 182 | regarding which files are parsed as ECMAScript modules. | |
| 179 | 183 | ||
| 180 | - If `--experimental-require-module` is enabled, and the ECMAScript module being | ||
| 181 | - loaded by `require()` meets the following requirements: | ||
| 184 | + `require()` only supports loading ECMAScript modules that meet the following requirements: | ||
| 182 | 185 | ||
| 183 | 186 | * The module is fully synchronous (contains no top-level `await`); and | |
| 184 | 187 | * One of these conditions are met: | |
@@ -187,8 +190,8 @@ loaded by `require()` meets the following requirements: | |||
| 187 | 190 | 3. The file has a `.js` extension, the closest `package.json` does not contain | |
| 188 | 191 | `"type": "commonjs"`, and the module contains ES module syntax. | |
| 189 | 192 | ||
| 190 | - `require()` will load the requested module as an ES Module, and return | ||
| 191 | - the module namespace object. In this case it is similar to dynamic | ||
| 193 | + If the ES Module being loaded meet the requirements, `require()` can load it and | ||
| 194 | + return the module namespace object. In this case it is similar to dynamic | ||
| 192 | 195 | `import()` but is run synchronously and returns the name space object | |
| 193 | 196 | directly. | |
| 194 | 197 | ||
@@ -207,7 +210,7 @@ class Point { | |||
| 207 | 210 | export default Point; | |
| 208 | 211 | ``` | |
| 209 | 212 | ||
| 210 | - A CommonJS module can load them with `require()` under `--experimental-detect-module`: | ||
| 213 | + A CommonJS module can load them with `require()`: | ||
| 211 | 214 | ||
| 212 | 215 | ```cjs | |
| 213 | 216 | const distance = require('./distance.mjs'); | |
@@ -236,13 +239,19 @@ conventions. Code authored directly in CommonJS should avoid depending on it. | |||
| 236 | 239 | If the module being `require()`'d contains top-level `await`, or the module | |
| 237 | 240 | graph it `import`s contains top-level `await`, | |
| 238 | 241 | [`ERR_REQUIRE_ASYNC_MODULE`][] will be thrown. In this case, users should | |
| 239 | - load the asynchronous module using `import()`. | ||
| 242 | + load the asynchronous module using [`import()`][]. | ||
| 240 | 243 | ||
| 241 | 244 | If `--experimental-print-required-tla` is enabled, instead of throwing | |
| 242 | 245 | `ERR_REQUIRE_ASYNC_MODULE` before evaluation, Node.js will evaluate the | |
| 243 | 246 | module, try to locate the top-level awaits, and print their location to | |
| 244 | 247 | help users fix them. | |
| 245 | 248 | ||
| 249 | + Support for loading ES modules using `require()` is currently | ||
| 250 | + experimental and can be disabled using `--no-experimental-require-module`. | ||
| 251 | + When `require()` actually encounters an ES module for the | ||
| 252 | + first time in the process, it will emit an experimental warning. The | ||
| 253 | + warning is expected to be removed when this feature stablizes. | ||
| 254 | + | ||
| 246 | 255 | ## All together | |
| 247 | 256 | ||
| 248 | 257 | <!-- type=misc --> | |
@@ -272,8 +281,7 @@ require(X) from module at path Y | |||
| 272 | 281 | ||
| 273 | 282 | MAYBE_DETECT_AND_LOAD(X) | |
| 274 | 283 | 1. If X parses as a CommonJS module, load X as a CommonJS module. STOP. | |
| 275 | - 2. Else, if `--experimental-require-module` is | ||
| 276 | - enabled, and the source code of X can be parsed as ECMAScript module using | ||
| 284 | + 2. Else, if the source code of X can be parsed as ECMAScript module using | ||
| 277 | 285 | <a href="esm.md#resolver-algorithm-specification">DETECT_MODULE_SYNTAX defined in | |
| 278 | 286 | the ESM resolver</a>, | |
| 279 | 287 | a. Load X as an ECMAScript module. STOP. | |
@@ -1190,7 +1198,6 @@ This section was moved to | |||
| 1190 | 1198 | [`"main"`]: packages.md#main | |
| 1191 | 1199 | [`"type"`]: packages.md#type | |
| 1192 | 1200 | [`ERR_REQUIRE_ASYNC_MODULE`]: errors.md#err_require_async_module | |
| 1193 | - [`ERR_REQUIRE_ESM`]: errors.md#err_require_esm | ||
| 1194 | 1201 | [`ERR_UNSUPPORTED_DIR_IMPORT`]: errors.md#err_unsupported_dir_import | |
| 1195 | 1202 | [`MODULE_NOT_FOUND`]: errors.md#module_not_found | |
| 1196 | 1203 | [`__dirname`]: #__dirname | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -172,8 +172,7 @@ There is the CommonJS module loader: | |||
| 172 | 172 | * It treats all files that lack `.json` or `.node` extensions as JavaScript | |
| 173 | 173 | text files. | |
| 174 | 174 | * It can only be used to [load ECMASCript modules from CommonJS modules][] if | |
| 175 | - the module graph is synchronous (that contains no top-level `await`) when | ||
| 176 | - `--experimental-require-module` is enabled. | ||
| 175 | + the module graph is synchronous (that contains no top-level `await`). | ||
| 177 | 176 | When used to load a JavaScript text file that is not an ECMAScript module, | |
| 178 | 177 | the file will be loaded as a CommonJS module. | |
| 179 | 178 | ||
@@ -662,8 +661,7 @@ specific to least specific as conditions should be defined: | |||
| 662 | 661 | * `"require"` - matches when the package is loaded via `require()`. The | |
| 663 | 662 | referenced file should be loadable with `require()` although the condition | |
| 664 | 663 | matches regardless of the module format of the target file. Expected | |
| 665 | - formats include CommonJS, JSON, native addons, and ES modules | ||
| 666 | - if `--experimental-require-module` is enabled. _Always mutually | ||
| 664 | + formats include CommonJS, JSON, native addons, and ES modules. _Always mutually | ||
| 667 | 665 | exclusive with `"import"`._ | |
| 668 | 666 | * `"module-sync"` - matches no matter the package is loaded via `import`, | |
| 669 | 667 | `import()` or `require()`. The format is expected to be ES modules that does | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -438,7 +438,6 @@ function initializeCJS() { | |||
| 438 | 438 | Module._extensions['.ts'] = loadTS; | |
| 439 | 439 | } | |
| 440 | 440 | if (getOptionValue('--experimental-require-module')) { | |
| 441 | - emitExperimentalWarning('Support for loading ES Module in require()'); | ||
| 442 | 441 | Module._extensions['.mjs'] = loadESMFromCJS; | |
| 443 | 442 | if (tsEnabled) { | |
| 444 | 443 | Module._extensions['.mts'] = loadESMFromCJS; | |
@@ -1386,6 +1385,7 @@ function loadESMFromCJS(mod, filename) { | |||
| 1386 | 1385 | // ESM won't be accessible via process.mainModule. | |
| 1387 | 1386 | setOwnProperty(process, 'mainModule', undefined); | |
| 1388 | 1387 | } else { | |
| 1388 | + emitExperimentalWarning('Support for loading ES Module in require()'); | ||
| 1389 | 1389 | const { | |
| 1390 | 1390 | wrap, | |
| 1391 | 1391 | namespace, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -131,11 +131,6 @@ async function defaultLoad(url, context = kEmptyObject) { | |||
| 131 | 131 | ||
| 132 | 132 | validateAttributes(url, format, importAttributes); | |
| 133 | 133 | ||
| 134 | - // Use the synchronous commonjs translator which can deal with cycles. | ||
| 135 | - if (format === 'commonjs' && getOptionValue('--experimental-require-module')) { | ||
| 136 | - format = 'commonjs-sync'; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | 134 | if (getOptionValue('--experimental-strip-types') && | |
| 140 | 135 | (format === 'module-typescript' || format === 'commonjs-typescript') && | |
| 141 | 136 | isUnderNodeModules(url)) { | |
@@ -191,11 +186,6 @@ function defaultLoadSync(url, context = kEmptyObject) { | |||
| 191 | 186 | ||
| 192 | 187 | validateAttributes(url, format, importAttributes); | |
| 193 | 188 | ||
| 194 | - // Use the synchronous commonjs translator which can deal with cycles. | ||
| 195 | - if (format === 'commonjs' && getOptionValue('--experimental-require-module')) { | ||
| 196 | - format = 'commonjs-sync'; | ||
| 197 | - } | ||
| 198 | - | ||
| 199 | 189 | return { | |
| 200 | 190 | __proto__: null, | |
| 201 | 191 | format, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -373,15 +373,15 @@ class ModuleLoader { | |||
| 373 | 373 | ||
| 374 | 374 | defaultLoadSync ??= require('internal/modules/esm/load').defaultLoadSync; | |
| 375 | 375 | const loadResult = defaultLoadSync(url, { format, importAttributes }); | |
| 376 | - const { | ||
| 377 | - format: finalFormat, | ||
| 378 | - source, | ||
| 379 | - } = loadResult; | ||
| 376 | + | ||
| 377 | + // Use the synchronous commonjs translator which can deal with cycles. | ||
| 378 | + const finalFormat = loadResult.format === 'commonjs' ? 'commonjs-sync' : loadResult.format; | ||
| 380 | 379 | ||
| 381 | 380 | if (finalFormat === 'wasm') { | |
| 382 | 381 | assert.fail('WASM is currently unsupported by require(esm)'); | |
| 383 | 382 | } | |
| 384 | 383 | ||
| 384 | + const { source } = loadResult; | ||
| 385 | 385 | const isMain = (parentURL === undefined); | |
| 386 | 386 | const wrap = this.#translate(url, finalFormat, source, isMain); | |
| 387 | 387 | assert(wrap instanceof ModuleWrap, `Translator used for require(${url}) should not be async`); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -361,6 +361,7 @@ class ModuleJobSync extends ModuleJobBase { | |||
| 361 | 361 | } | |
| 362 | 362 | ||
| 363 | 363 | runSync() { | |
| 364 | + // TODO(joyeecheung): add the error decoration logic from the async instantiate. | ||
| 364 | 365 | this.module.instantiateSync(); | |
| 365 | 366 | setHasStartedUserESMExecution(); | |
| 366 | 367 | const namespace = this.module.evaluateSync(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -75,17 +75,15 @@ function initializeDefaultConditions() { | |||
| 75 | 75 | const userConditions = getOptionValue('--conditions'); | |
| 76 | 76 | const noAddons = getOptionValue('--no-addons'); | |
| 77 | 77 | const addonConditions = noAddons ? [] : ['node-addons']; | |
| 78 | - | ||
| 78 | + const moduleConditions = getOptionValue('--experimental-require-module') ? ['module-sync'] : []; | ||
| 79 | 79 | defaultConditions = ObjectFreeze([ | |
| 80 | 80 | 'node', | |
| 81 | 81 | 'import', | |
| 82 | + ...moduleConditions, | ||
| 82 | 83 | ...addonConditions, | |
| 83 | 84 | ...userConditions, | |
| 84 | 85 | ]); | |
| 85 | 86 | defaultConditionsSet = new SafeSet(defaultConditions); | |
| 86 | - if (getOptionValue('--experimental-require-module')) { | ||
| 87 | - defaultConditionsSet.add('module-sync'); | ||
| 88 | - } | ||
| 89 | 87 | } | |
| 90 | 88 | ||
| 91 | 89 | /** | |
| Back | FazBrowse Home | New Git URL |
0 commit comments