| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent bf69ae1 commit 111261e
34 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -335,9 +335,12 @@ LOAD_PACKAGE_IMPORTS(X, DIR) | |||
| 335 | 335 | 1. Find the closest package scope SCOPE to DIR. | |
| 336 | 336 | 2. If no scope was found, return. | |
| 337 | 337 | 3. If the SCOPE/package.json "imports" is null or undefined, return. | |
| 338 | - 4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), | ||
| 339 | - ["node", "require"]) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 340 | - 5. RESOLVE_ESM_MATCH(MATCH). | ||
| 338 | + 4. If `--experimental-require-module` is enabled | ||
| 339 | + a. let CONDITIONS = ["node", "require", "module-sync"] | ||
| 340 | + b. Else, let CONDITIONS = ["node", "require"] | ||
| 341 | + 5. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), | ||
| 342 | + CONDITIONS) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 343 | + 6. RESOLVE_ESM_MATCH(MATCH). | ||
| 341 | 344 | ||
| 342 | 345 | LOAD_PACKAGE_EXPORTS(X, DIR) | |
| 343 | 346 | 1. Try to interpret X as a combination of NAME and SUBPATH where the name | |
@@ -346,9 +349,12 @@ LOAD_PACKAGE_EXPORTS(X, DIR) | |||
| 346 | 349 | return. | |
| 347 | 350 | 3. Parse DIR/NAME/package.json, and look for "exports" field. | |
| 348 | 351 | 4. If "exports" is null or undefined, return. | |
| 349 | - 5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, | ||
| 350 | - `package.json` "exports", ["node", "require"]) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 351 | - 6. RESOLVE_ESM_MATCH(MATCH) | ||
| 352 | + 5. If `--experimental-require-module` is enabled | ||
| 353 | + a. let CONDITIONS = ["node", "require", "module-sync"] | ||
| 354 | + b. Else, let CONDITIONS = ["node", "require"] | ||
| 355 | + 6. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, | ||
| 356 | + `package.json` "exports", CONDITIONS) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 357 | + 7. RESOLVE_ESM_MATCH(MATCH) | ||
| 352 | 358 | ||
| 353 | 359 | LOAD_PACKAGE_SELF(X, DIR) | |
| 354 | 360 | 1. Find the closest package scope SCOPE to DIR. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -665,6 +665,10 @@ specific to least specific as conditions should be defined: | |||
| 665 | 665 | formats include CommonJS, JSON, native addons, and ES modules | |
| 666 | 666 | if `--experimental-require-module` is enabled. _Always mutually | |
| 667 | 667 | exclusive with `"import"`._ | |
| 668 | + * `"module-sync"` - matches no matter the package is loaded via `import`, | ||
| 669 | + `import()` or `require()`. The format is expected to be ES modules that does | ||
| 670 | + not contain top-level await in its module graph - if it does, | ||
| 671 | + `ERR_REQUIRE_ASYNC_MODULE` will be thrown when the module is `require()`-ed. | ||
| 668 | 672 | * `"default"` - the generic fallback that always matches. Can be a CommonJS | |
| 669 | 673 | or ES module file. _This condition should always come last._ | |
| 670 | 674 | ||
@@ -755,7 +759,7 @@ Any number of custom conditions can be set with repeat flags. | |||
| 755 | 759 | ||
| 756 | 760 | ### Community Conditions Definitions | |
| 757 | 761 | ||
| 758 | - Condition strings other than the `"import"`, `"require"`, `"node"`, | ||
| 762 | + Condition strings other than the `"import"`, `"require"`, `"node"`, `"module-sync"`, | ||
| 759 | 763 | `"node-addons"` and `"default"` conditions | |
| 760 | 764 | [implemented in Node.js core](#conditional-exports) are ignored by default. | |
| 761 | 765 | ||
@@ -886,6 +890,17 @@ $ node other.js | |||
| 886 | 890 | ||
| 887 | 891 | ## Dual CommonJS/ES module packages | |
| 888 | 892 | ||
| 893 | + <!-- This section should not be in the API documentation: | ||
| 894 | + | ||
| 895 | + 1. It teaches opinionated practices that some consider dangerous, see | ||
| 896 | + https://github.com/nodejs/node/issues/52174 | ||
| 897 | + 2. It will soon be obsolete when we unflag --experimental-require-module. | ||
| 898 | + 3. It's difficult to understand a multi-file structure via long texts and snippets in | ||
| 899 | + a markdown document. | ||
| 900 | + | ||
| 901 | + TODO(?): Move this section to its own repository with example folders. | ||
| 902 | + --> | ||
| 903 | + | ||
| 889 | 904 | Prior to the introduction of support for ES modules in Node.js, it was a common | |
| 890 | 905 | pattern for package authors to include both CommonJS and ES module JavaScript | |
| 891 | 906 | sources in their package, with `package.json` [`"main"`][] specifying the | |
@@ -898,7 +913,7 @@ ignores) the top-level `"module"` field. | |||
| 898 | 913 | Node.js can now run ES module entry points, and a package can contain both | |
| 899 | 914 | CommonJS and ES module entry points (either via separate specifiers such as | |
| 900 | 915 | `'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional | |
| 901 | - exports][]). Unlike in the scenario where `"module"` is only used by bundlers, | ||
| 916 | + exports][]). Unlike in the scenario where top-level `"module"` field is only used by bundlers, | ||
| 902 | 917 | or ES module files are transpiled into CommonJS on the fly before evaluation by | |
| 903 | 918 | Node.js, the files referenced by the ES module entry point are evaluated as ES | |
| 904 | 919 | modules. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -91,7 +91,7 @@ function underNodeModules(url) { | |||
| 91 | 91 | let typelessPackageJsonFilesWarnedAbout; | |
| 92 | 92 | function warnTypelessPackageJsonFile(pjsonPath, url) { | |
| 93 | 93 | typelessPackageJsonFilesWarnedAbout ??= new SafeSet(); | |
| 94 | - if (!typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) { | ||
| 94 | + if (!underNodeModules(url) && !typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) { | ||
| 95 | 95 | const warning = `Module type of ${url} is not specified and it doesn't parse as CommonJS.\n` + | |
| 96 | 96 | 'Reparsing as ES module because module syntax was detected. This incurs a performance overhead.\n' + | |
| 97 | 97 | `To eliminate this warning, add "type": "module" to ${pjsonPath}.`; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -83,6 +83,9 @@ function initializeDefaultConditions() { | |||
| 83 | 83 | ...userConditions, | |
| 84 | 84 | ]); | |
| 85 | 85 | defaultConditionsSet = new SafeSet(defaultConditions); | |
| 86 | + if (getOptionValue('--experimental-require-module')) { | ||
| 87 | + defaultConditionsSet.add('module-sync'); | ||
| 88 | + } | ||
| 86 | 89 | } | |
| 87 | 90 | ||
| 88 | 91 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -82,6 +82,9 @@ function initializeCjsConditions() { | |||
| 82 | 82 | ...addonConditions, | |
| 83 | 83 | ...userConditions, | |
| 84 | 84 | ]); | |
| 85 | + if (getOptionValue('--experimental-require-module')) { | ||
| 86 | + cjsConditions.add('module-sync'); | ||
| 87 | + } | ||
| 85 | 88 | } | |
| 86 | 89 | ||
| 87 | 90 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,29 @@ | |||
| 1 | + // Flags: --experimental-require-module | ||
| 2 | + | ||
| 3 | + import '../common/index.mjs'; | ||
| 4 | + import assert from 'node:assert'; | ||
| 5 | + import * as staticImport from '../fixtures/es-modules/module-condition/import.mjs'; | ||
| 6 | + import { import as _import } from '../fixtures/es-modules/module-condition/dynamic_import.js'; | ||
| 7 | + | ||
| 8 | + async function dynamicImport(id) { | ||
| 9 | + const result = await _import(id); | ||
| 10 | + return result.resolved; | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + assert.deepStrictEqual({ ...staticImport }, { | ||
| 14 | + import_module_require: 'import', | ||
| 15 | + module_and_import: 'module', | ||
| 16 | + module_and_require: 'module', | ||
| 17 | + module_import_require: 'module', | ||
| 18 | + module_only: 'module', | ||
| 19 | + module_require_import: 'module', | ||
| 20 | + require_module_import: 'module', | ||
| 21 | + }); | ||
| 22 | + | ||
| 23 | + assert.strictEqual(await dynamicImport('import-module-require'), 'import'); | ||
| 24 | + assert.strictEqual(await dynamicImport('module-and-import'), 'module'); | ||
| 25 | + assert.strictEqual(await dynamicImport('module-and-require'), 'module'); | ||
| 26 | + assert.strictEqual(await dynamicImport('module-import-require'), 'module'); | ||
| 27 | + assert.strictEqual(await dynamicImport('module-only'), 'module'); | ||
| 28 | + assert.strictEqual(await dynamicImport('module-require-import'), 'module'); | ||
| 29 | + assert.strictEqual(await dynamicImport('require-module-import'), 'module'); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,15 @@ | |||
| 1 | + // Flags: --experimental-require-module | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + const loader = require('../fixtures/es-modules/module-condition/require.cjs'); | ||
| 8 | + | ||
| 9 | + assert.strictEqual(loader.require('import-module-require').resolved, 'module'); | ||
| 10 | + assert.strictEqual(loader.require('module-and-import').resolved, 'module'); | ||
| 11 | + assert.strictEqual(loader.require('module-and-require').resolved, 'module'); | ||
| 12 | + assert.strictEqual(loader.require('module-import-require').resolved, 'module'); | ||
| 13 | + assert.strictEqual(loader.require('module-only').resolved, 'module'); | ||
| 14 | + assert.strictEqual(loader.require('module-require-import').resolved, 'module'); | ||
| 15 | + assert.strictEqual(loader.require('require-module-import').resolved, 'require'); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + function load(id) { | ||
| 2 | + return import(id); | ||
| 3 | + } | ||
| 4 | + | ||
| 5 | + export { load as import }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,7 @@ | |||
| 1 | + export { resolved as import_module_require } from 'import-module-require'; | ||
| 2 | + export { resolved as module_and_import } from 'module-and-import'; | ||
| 3 | + export { resolved as module_and_require } from 'module-and-require'; | ||
| 4 | + export { resolved as module_import_require } from 'module-import-require'; | ||
| 5 | + export { resolved as module_only } from 'module-only'; | ||
| 6 | + export { resolved as module_require_import } from 'module-require-import'; | ||
| 7 | + export { resolved as require_module_import } from 'require-module-import'; | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments