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: support 'module.exports' interop export in require(esm) · nodejs/node@dc66632

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • doc/api
    • modules.md
  • lib/internal/modules/cjs
    • loader.js
  • test
    • es-module
      • test-require-as-esm-interop.mjs
    • fixtures
      • node_modules
        • interop-cjs-esm
          • false-esm.js
          • false.js
          • fauxesmdefault-esm.js
          • fauxesmdefault.js
          • fauxesmmixed-esm.js
          • fauxesmmixed.js
          • fauxesmnamed-esm.js
          • fauxesmnamed.js
          • object-esm.js
          • object.js
          • package.json
          • string-esm.js
          • string.js
        • interop-cjsdep-false-esm
          • dep.js
          • package.json
        • interop-cjsdep-false
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmdefault-esm
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmdefault
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmmixed-esm
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmmixed
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmnamed-esm
          • dep.js
          • package.json
        • interop-cjsdep-fauxesmnamed
          • dep.js
          • package.json
        • interop-cjsdep-object-esm
          • dep.js
          • package.json
        • interop-cjsdep-object
          • dep.js
          • package.json
        • interop-cjsdep-string-esm
          • dep.js
          • package.json
        • interop-cjsdep-string
          • dep.js
          • package.json
        • interop-cjs
          • false-esm.js
          • false.js
          • fauxesmdefault-esm.js
          • fauxesmdefault.js
          • fauxesmmixed-esm.js
          • fauxesmmixed.js
          • fauxesmnamed-esm.js
          • fauxesmnamed.js
          • object-esm.js
          • object.js
          • package.json
          • string-esm.js
          • string.js
      • pkgexports.mjs

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Expand file

‎doc/api/modules.md‎

Copy file name to clipboardExpand all lines: doc/api/modules.md
+64-2Lines changed: 64 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Collapse file

‎lib/internal/modules/cjs/loader.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/cjs/loader.js
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,10 +1382,13 @@ function loadESMFromCJS(mod, filename) {
13821382
// createRequiredModuleFacade() to `wrap` which is a ModuleWrap wrapping
13831383
// over the original module.
13841384

1385-
// We don't do this to modules that don't have default exports to avoid
1386-
// the unnecessary overhead. If __esModule is already defined, we will
1387-
// also skip the extension to allow users to override it.
1388-
if (!ObjectHasOwn(namespace, 'default') || ObjectHasOwn(namespace, '__esModule')) {
1385+
// We don't do this to modules that are marked as CJS ESM or that
1386+
// don't have default exports to avoid the unnecessary overhead.
1387+
// If __esModule is already defined, we will also skip the extension
1388+
// to allow users to override it.
1389+
if (ObjectHasOwn(namespace, 'module.exports')) {
1390+
mod.exports = namespace['module.exports'];
1391+
} else if (!ObjectHasOwn(namespace, 'default') || ObjectHasOwn(namespace, '__esModule')) {
13891392
mod.exports = namespace;
13901393
} else {
13911394
mod.exports = createRequiredModuleFacade(wrap);
Collapse file

‎test/es-module/test-require-as-esm-interop.mjs‎

Copy file name to clipboard
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Flags: --experimental-require-module
2+
import '../common/index.mjs';
3+
import assert from 'assert';
4+
import { directRequireFixture, importFixture } from '../fixtures/pkgexports.mjs';
5+
6+
const tests = {
7+
'false': false,
8+
'string': 'cjs',
9+
'object': { a: 'cjs a', b: 'cjs b' },
10+
'fauxesmdefault': { default: 'faux esm default' },
11+
'fauxesmmixed': { default: 'faux esm default', a: 'faux esm a', b: 'faux esm b' },
12+
'fauxesmnamed': { a: 'faux esm a', b: 'faux esm b' }
13+
};
14+
15+
// This test demonstrates interop between CJS and CJS represented as ESM
16+
// under the new `export { ... as 'module.exports'}` pattern, for the above cases.
17+
for (const [test, exactShape] of Object.entries(tests)) {
18+
// Each case represents a CJS dependency, which has the expected shape in CJS:
19+
assert.deepStrictEqual(directRequireFixture(`interop-cjsdep-${test}`), exactShape);
20+
21+
// Each dependency is reexported through CJS as if it is a library being consumed,
22+
// which in CJS is fully shape-preserving:
23+
assert.deepStrictEqual(directRequireFixture(`interop-cjs/${test}`), exactShape);
24+
25+
// Now we have ESM conversions of these dependencies, using `export ... as "module.exports"`
26+
// staring with the conversion of those dependencies into ESM under require(esm):
27+
assert.deepStrictEqual(directRequireFixture(`interop-cjsdep-${test}-esm`), exactShape);
28+
29+
// When importing these ESM conversions, from require(esm), we should preserve the shape:
30+
assert.deepStrictEqual(directRequireFixture(`interop-cjs/${test}-esm`), exactShape);
31+
32+
// Now if the importer itself is converted into ESM, it should still be able to load the original
33+
// CJS and reexport it, preserving the shape:
34+
assert.deepStrictEqual(directRequireFixture(`interop-cjs-esm/${test}`), exactShape);
35+
36+
// And then if we have the converted CJS to ESM importing from converted CJS to ESM,
37+
// that should also work:
38+
assert.deepStrictEqual(directRequireFixture(`interop-cjs-esm/${test}-esm`), exactShape);
39+
40+
// Finally, the CJS ESM representation under `import()` should match all these cases equivalently,
41+
// where the CJS module is exported as the default export:
42+
const esmCjsImport = await importFixture(`interop-cjsdep-${test}`);
43+
assert.deepStrictEqual(esmCjsImport.default, exactShape);
44+
45+
assert.deepStrictEqual((await importFixture(`interop-cjsdep-${test}`)).default, exactShape);
46+
assert.deepStrictEqual((await importFixture(`interop-cjs/${test}`)).default, exactShape);
47+
assert.deepStrictEqual((await importFixture(`interop-cjsdep-${test}-esm`)).default, exactShape);
48+
assert.deepStrictEqual((await importFixture(`interop-cjs/${test}-esm`)).default, exactShape);
49+
assert.deepStrictEqual((await importFixture(`interop-cjs-esm/${test}`)).default, exactShape);
50+
assert.deepStrictEqual((await importFixture(`interop-cjs-esm/${test}-esm`)).default, exactShape);
51+
}
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/false-esm.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/false-esm.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/false.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/false.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js
+4Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js
+3Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Collapse file

‎test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js‎

Copy file name to clipboardExpand all lines: test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js
+3Lines changed: 3 additions & 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.