| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 249d82b commit df8a045
34 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -342,9 +342,12 @@ LOAD_PACKAGE_IMPORTS(X, DIR) | |||
| 342 | 342 | 1. Find the closest package scope SCOPE to DIR. | |
| 343 | 343 | 2. If no scope was found, return. | |
| 344 | 344 | 3. If the SCOPE/package.json "imports" is null or undefined, return. | |
| 345 | - 4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), | ||
| 346 | - ["node", "require"]) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 347 | - 5. RESOLVE_ESM_MATCH(MATCH). | ||
| 345 | + 4. If `--experimental-require-module` is enabled | ||
| 346 | + a. let CONDITIONS = ["node", "require", "module-sync"] | ||
| 347 | + b. Else, let CONDITIONS = ["node", "require"] | ||
| 348 | + 5. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), | ||
| 349 | + CONDITIONS) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 350 | + 6. RESOLVE_ESM_MATCH(MATCH). | ||
| 348 | 351 | ||
| 349 | 352 | LOAD_PACKAGE_EXPORTS(X, DIR) | |
| 350 | 353 | 1. Try to interpret X as a combination of NAME and SUBPATH where the name | |
@@ -353,9 +356,12 @@ LOAD_PACKAGE_EXPORTS(X, DIR) | |||
| 353 | 356 | return. | |
| 354 | 357 | 3. Parse DIR/NAME/package.json, and look for "exports" field. | |
| 355 | 358 | 4. If "exports" is null or undefined, return. | |
| 356 | - 5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, | ||
| 357 | - `package.json` "exports", ["node", "require"]) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 358 | - 6. RESOLVE_ESM_MATCH(MATCH) | ||
| 359 | + 5. If `--experimental-require-module` is enabled | ||
| 360 | + a. let CONDITIONS = ["node", "require", "module-sync"] | ||
| 361 | + b. Else, let CONDITIONS = ["node", "require"] | ||
| 362 | + 6. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, | ||
| 363 | + `package.json` "exports", CONDITIONS) <a href="esm.md#resolver-algorithm-specification">defined in the ESM resolver</a>. | ||
| 364 | + 7. RESOLVE_ESM_MATCH(MATCH) | ||
| 359 | 365 | ||
| 360 | 366 | LOAD_PACKAGE_SELF(X, DIR) | |
| 361 | 367 | 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 | ||
@@ -769,7 +773,7 @@ In node, conditions have very few restrictions, but specifically these include: | |||
| 769 | 773 | ||
| 770 | 774 | ### Community Conditions Definitions | |
| 771 | 775 | ||
| 772 | - Condition strings other than the `"import"`, `"require"`, `"node"`, | ||
| 776 | + Condition strings other than the `"import"`, `"require"`, `"node"`, `"module-sync"`, | ||
| 773 | 777 | `"node-addons"` and `"default"` conditions | |
| 774 | 778 | [implemented in Node.js core](#conditional-exports) are ignored by default. | |
| 775 | 779 | ||
@@ -900,6 +904,17 @@ $ node other.js | |||
| 900 | 904 | ||
| 901 | 905 | ## Dual CommonJS/ES module packages | |
| 902 | 906 | ||
| 907 | + <!-- This section should not be in the API documentation: | ||
| 908 | + | ||
| 909 | + 1. It teaches opinionated practices that some consider dangerous, see | ||
| 910 | + https://github.com/nodejs/node/issues/52174 | ||
| 911 | + 2. It will soon be obsolete when we unflag --experimental-require-module. | ||
| 912 | + 3. It's difficult to understand a multi-file structure via long texts and snippets in | ||
| 913 | + a markdown document. | ||
| 914 | + | ||
| 915 | + TODO(?): Move this section to its own repository with example folders. | ||
| 916 | + --> | ||
| 917 | + | ||
| 903 | 918 | Prior to the introduction of support for ES modules in Node.js, it was a common | |
| 904 | 919 | pattern for package authors to include both CommonJS and ES module JavaScript | |
| 905 | 920 | sources in their package, with `package.json` [`"main"`][] specifying the | |
@@ -912,7 +927,7 @@ ignores) the top-level `"module"` field. | |||
| 912 | 927 | Node.js can now run ES module entry points, and a package can contain both | |
| 913 | 928 | CommonJS and ES module entry points (either via separate specifiers such as | |
| 914 | 929 | `'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional | |
| 915 | - exports][]). Unlike in the scenario where `"module"` is only used by bundlers, | ||
| 930 | + exports][]). Unlike in the scenario where top-level `"module"` field is only used by bundlers, | ||
| 916 | 931 | or ES module files are transpiled into CommonJS on the fly before evaluation by | |
| 917 | 932 | Node.js, the files referenced by the ES module entry point are evaluated as ES | |
| 918 | 933 | modules. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -97,7 +97,7 @@ function underNodeModules(url) { | |||
| 97 | 97 | let typelessPackageJsonFilesWarnedAbout; | |
| 98 | 98 | function warnTypelessPackageJsonFile(pjsonPath, url) { | |
| 99 | 99 | typelessPackageJsonFilesWarnedAbout ??= new SafeSet(); | |
| 100 | - if (!typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) { | ||
| 100 | + if (!underNodeModules(url) && !typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) { | ||
| 101 | 101 | const warning = `Module type of ${url} is not specified and it doesn't parse as CommonJS.\n` + | |
| 102 | 102 | 'Reparsing as ES module because module syntax was detected. This incurs a performance overhead.\n' + | |
| 103 | 103 | `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 | |
|---|---|---|---|
@@ -76,6 +76,9 @@ function initializeCjsConditions() { | |||
| 76 | 76 | ...addonConditions, | |
| 77 | 77 | ...userConditions, | |
| 78 | 78 | ]); | |
| 79 | + if (getOptionValue('--experimental-require-module')) { | ||
| 80 | + cjsConditions.add('module-sync'); | ||
| 81 | + } | ||
| 79 | 82 | } | |
| 80 | 83 | ||
| 81 | 84 | /** | |
| 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