GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — module: implement the "module-sync" exports condition · nodejs/node@df8a045

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • doc/api
    • modules.md
    • packages.md
  • lib/internal/modules
    • esm
      • get_format.js
      • utils.js
    • helpers.js
  • test
    • es-module
      • test-import-module-conditional-exports-module.mjs
      • test-require-module-conditional-exports-module.js
    • fixtures/es-modules/module-condition
      • dynamic_import.js
      • import.mjs
      • node_modules
        • import-module-require
          • import.js
          • module.js
          • package.json
          • require.cjs
        • module-and-import
          • import.js
          • module.js
          • package.json
        • module-and-require
          • module.js
          • package.json
          • require.cjs
        • module-import-require
          • import.js
          • module.js
          • package.json
          • require.cjs
        • module-only
          • module.js
          • package.json
        • module-require-import
          • import.js
          • module.js
          • package.json
          • require.cjs
        • require-module-import
          • import.js
          • module.js
          • package.json
          • require.cjs
      • require.cjs
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/modules.md‎

Copy file name to clipboardExpand all lines: doc/api/modules.md
+12-6Lines changed: 12 additions & 6 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,12 @@ LOAD_PACKAGE_IMPORTS(X, DIR)
342342
1. Find the closest package scope SCOPE to DIR.
343343
2. If no scope was found, return.
344344
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).
348351
349352
LOAD_PACKAGE_EXPORTS(X, DIR)
350353
1. Try to interpret X as a combination of NAME and SUBPATH where the name
@@ -353,9 +356,12 @@ LOAD_PACKAGE_EXPORTS(X, DIR)
353356
return.
354357
3. Parse DIR/NAME/package.json, and look for "exports" field.
355358
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)
359365
360366
LOAD_PACKAGE_SELF(X, DIR)
361367
1. Find the closest package scope SCOPE to DIR.
Collapse file

‎doc/api/packages.md‎

Copy file name to clipboardExpand all lines: doc/api/packages.md
+17-2Lines changed: 17 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,10 @@ specific to least specific as conditions should be defined:
665665
formats include CommonJS, JSON, native addons, and ES modules
666666
if `--experimental-require-module` is enabled. _Always mutually
667667
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.
668672
* `"default"` - the generic fallback that always matches. Can be a CommonJS
669673
or ES module file. _This condition should always come last._
670674

@@ -769,7 +773,7 @@ In node, conditions have very few restrictions, but specifically these include:
769773

770774
### Community Conditions Definitions
771775

772-
Condition strings other than the `"import"`, `"require"`, `"node"`,
776+
Condition strings other than the `"import"`, `"require"`, `"node"`, `"module-sync"`,
773777
`"node-addons"` and `"default"` conditions
774778
[implemented in Node.js core](#conditional-exports) are ignored by default.
775779

@@ -900,6 +904,17 @@ $ node other.js
900904

901905
## Dual CommonJS/ES module packages
902906

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+
903918
Prior to the introduction of support for ES modules in Node.js, it was a common
904919
pattern for package authors to include both CommonJS and ES module JavaScript
905920
sources in their package, with `package.json` [`"main"`][] specifying the
@@ -912,7 +927,7 @@ ignores) the top-level `"module"` field.
912927
Node.js can now run ES module entry points, and a package can contain both
913928
CommonJS and ES module entry points (either via separate specifiers such as
914929
`'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,
916931
or ES module files are transpiled into CommonJS on the fly before evaluation by
917932
Node.js, the files referenced by the ES module entry point are evaluated as ES
918933
modules.
Collapse file

‎lib/internal/modules/esm/get_format.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/get_format.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function underNodeModules(url) {
9797
let typelessPackageJsonFilesWarnedAbout;
9898
function warnTypelessPackageJsonFile(pjsonPath, url) {
9999
typelessPackageJsonFilesWarnedAbout ??= new SafeSet();
100-
if (!typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) {
100+
if (!underNodeModules(url) && !typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) {
101101
const warning = `Module type of ${url} is not specified and it doesn't parse as CommonJS.\n` +
102102
'Reparsing as ES module because module syntax was detected. This incurs a performance overhead.\n' +
103103
`To eliminate this warning, add "type": "module" to ${pjsonPath}.`;
Collapse file

‎lib/internal/modules/esm/utils.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/utils.js
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ function initializeDefaultConditions() {
8383
...userConditions,
8484
]);
8585
defaultConditionsSet = new SafeSet(defaultConditions);
86+
if (getOptionValue('--experimental-require-module')) {
87+
defaultConditionsSet.add('module-sync');
88+
}
8689
}
8790

8891
/**
Collapse file

‎lib/internal/modules/helpers.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/helpers.js
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ function initializeCjsConditions() {
7676
...addonConditions,
7777
...userConditions,
7878
]);
79+
if (getOptionValue('--experimental-require-module')) {
80+
cjsConditions.add('module-sync');
81+
}
7982
}
8083

8184
/**
Collapse file

‎test/es-module/test-import-module-conditional-exports-module.mjs‎

Copy file name to clipboard
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff 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');
Collapse file

‎test/es-module/test-require-module-conditional-exports-module.js‎

Copy file name to clipboard
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff 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');
Collapse file

‎test/fixtures/es-modules/module-condition/dynamic_import.js‎

Copy file name to clipboard
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function load(id) {
2+
return import(id);
3+
}
4+
5+
export { load as import };
Collapse file

‎test/fixtures/es-modules/module-condition/import.mjs‎

Copy file name to clipboard
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff 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';
Collapse file

‎test/fixtures/es-modules/module-condition/node_modules/import-module-require/import.js‎

Copy file name to clipboardExpand all lines: test/fixtures/es-modules/module-condition/node_modules/import-module-require/import.js
+1Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.