From 4f33767f54ec4c30844c2d9314c17eb125325a47 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 14 Jul 2024 13:00:49 -0700 Subject: [PATCH] module: support 'module.exports' interop export in require(esm) PR-URL: https://github.com/nodejs/node/pull/54563 Reviewed-By: Matteo Collina Reviewed-By: Antoine du Hamel Reviewed-By: James M Snell Reviewed-By: Joyee Cheung --- doc/api/modules.md | 66 ++++++++++++++++++- lib/internal/modules/cjs/loader.js | 11 ++-- .../es-module/test-require-as-esm-interop.mjs | 51 ++++++++++++++ .../node_modules/interop-cjs-esm/false-esm.js | 3 + .../node_modules/interop-cjs-esm/false.js | 3 + .../interop-cjs-esm/fauxesmdefault-esm.js | 3 + .../interop-cjs-esm/fauxesmdefault.js | 3 + .../interop-cjs-esm/fauxesmmixed-esm.js | 4 ++ .../interop-cjs-esm/fauxesmmixed.js | 3 + .../interop-cjs-esm/fauxesmnamed-esm.js | 3 + .../interop-cjs-esm/fauxesmnamed.js | 3 + .../interop-cjs-esm/object-esm.js | 3 + .../node_modules/interop-cjs-esm/object.js | 3 + .../node_modules/interop-cjs-esm/package.json | 17 +++++ .../interop-cjs-esm/string-esm.js | 3 + .../node_modules/interop-cjs-esm/string.js | 3 + .../node_modules/interop-cjs/false-esm.js | 1 + .../node_modules/interop-cjs/false.js | 1 + .../interop-cjs/fauxesmdefault-esm.js | 1 + .../interop-cjs/fauxesmdefault.js | 1 + .../interop-cjs/fauxesmmixed-esm.js | 1 + .../node_modules/interop-cjs/fauxesmmixed.js | 1 + .../interop-cjs/fauxesmnamed-esm.js | 1 + .../node_modules/interop-cjs/fauxesmnamed.js | 1 + .../node_modules/interop-cjs/object-esm.js | 1 + .../node_modules/interop-cjs/object.js | 1 + .../node_modules/interop-cjs/package.json | 17 +++++ .../node_modules/interop-cjs/string-esm.js | 1 + .../node_modules/interop-cjs/string.js | 1 + .../interop-cjsdep-false-esm/dep.js | 3 + .../interop-cjsdep-false-esm/package.json | 4 ++ .../node_modules/interop-cjsdep-false/dep.js | 1 + .../interop-cjsdep-false/package.json | 4 ++ .../interop-cjsdep-fauxesmdefault-esm/dep.js | 7 ++ .../package.json | 4 ++ .../interop-cjsdep-fauxesmdefault/dep.js | 2 + .../package.json | 4 ++ .../interop-cjsdep-fauxesmmixed-esm/dep.js | 9 +++ .../package.json | 4 ++ .../interop-cjsdep-fauxesmmixed/dep.js | 4 ++ .../interop-cjsdep-fauxesmmixed/package.json | 4 ++ .../interop-cjsdep-fauxesmnamed-esm/dep.js | 8 +++ .../package.json | 4 ++ .../interop-cjsdep-fauxesmnamed/dep.js | 3 + .../interop-cjsdep-fauxesmnamed/package.json | 4 ++ .../interop-cjsdep-object-esm/dep.js | 8 +++ .../interop-cjsdep-object-esm/package.json | 4 ++ .../node_modules/interop-cjsdep-object/dep.js | 2 + .../interop-cjsdep-object/package.json | 4 ++ .../interop-cjsdep-string-esm/dep.js | 3 + .../interop-cjsdep-string-esm/package.json | 4 ++ .../node_modules/interop-cjsdep-string/dep.js | 1 + .../interop-cjsdep-string/package.json | 4 ++ test/fixtures/pkgexports.mjs | 4 ++ 54 files changed, 308 insertions(+), 6 deletions(-) create mode 100644 test/es-module/test-require-as-esm-interop.mjs create mode 100644 test/fixtures/node_modules/interop-cjs-esm/false-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/false.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/object-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/object.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjs-esm/string-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs-esm/string.js create mode 100644 test/fixtures/node_modules/interop-cjs/false-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/false.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmdefault-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmdefault.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmmixed-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmmixed.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmnamed-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/fauxesmnamed.js create mode 100644 test/fixtures/node_modules/interop-cjs/object-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/object.js create mode 100644 test/fixtures/node_modules/interop-cjs/package.json create mode 100644 test/fixtures/node_modules/interop-cjs/string-esm.js create mode 100644 test/fixtures/node_modules/interop-cjs/string.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-false-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-false-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-false/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-false/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-object-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-object-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-object/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-object/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-string-esm/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-string-esm/package.json create mode 100644 test/fixtures/node_modules/interop-cjsdep-string/dep.js create mode 100644 test/fixtures/node_modules/interop-cjsdep-string/package.json diff --git a/doc/api/modules.md b/doc/api/modules.md index 7aa84fe15e8020..0e79d1b8d68f4d 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -176,6 +176,9 @@ changes: - version: REPLACEME pr-url: https://github.com/nodejs/node/pull/55085 description: require() now supports loading synchronous ES modules by default. + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/54563 + description: Support `'module.exports'` interop export in `require(esm)`. --> > Stability: 1.1 - Active Development. Enable this API with the @@ -208,10 +211,9 @@ export function distance(a, b) { return (b.x - a.x) ** 2 + (b.y - a.y) ** 2; } ```mjs // point.mjs -class Point { +export default class Point { constructor(x, y) { this.x = x; this.y = y; } } -export default Point; ``` A CommonJS module can load them with `require()`: @@ -240,6 +242,66 @@ This property is experimental and can change in the future. It should only be us by tools converting ES modules into CommonJS modules, following existing ecosystem conventions. Code authored directly in CommonJS should avoid depending on it. +When a ES Module contains both named exports and a default export, the result returned by `require()` +is the module namespace object, which places the default export in the `.default` property, similar to +the results returned by `import()`. +To customize what should be returned by `require(esm)` directly, the ES Module can export the +desired value using the string name `"module.exports"`. + + + +```mjs +// point.mjs +export default class Point { + constructor(x, y) { this.x = x; this.y = y; } +} + +// `distance` is lost to CommonJS consumers of this module, unless it's +// added to `Point` as a static property. +export function distance(a, b) { return (b.x - a.x) ** 2 + (b.y - a.y) ** 2; } +export { Point as 'module.exports' } +``` + + + +```cjs +const Point = require('./point.mjs'); +console.log(Point); // [class Point] + +// Named exports are lost when 'module.exports' is used +const { distance } = require('./point.mjs'); +console.log(distance); // undefined +``` + +Notice in the example above, when the `module.exports` export name is used, named exports +will be lost to CommonJS consumers. To allow CommonJS consumers to continue accessing +named exports, the module can make sure that the default export is an object with the +named exports attached to it as properties. For example with the example above, +`distance` can be attached to the default export, the `Point` class, as a static method. + + + +```mjs +export function distance(a, b) { return (b.x - a.x) ** 2 + (b.y - a.y) ** 2; } + +export default class Point { + constructor(x, y) { this.x = x; this.y = y; } + static distance = distance; +} + +export { Point as 'module.exports' } +``` + + + +```cjs +const Point = require('./point.mjs'); +console.log(Point); // [class Point] + +const { distance } = require('./point.mjs'); +console.log(distance); // [Function: distance] +``` + If the module being `require()`'d contains top-level `await`, or the module graph it `import`s contains top-level `await`, [`ERR_REQUIRE_ASYNC_MODULE`][] will be thrown. In this case, users should diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 9d3818603f4e2b..315c7ca08a9f07 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1416,10 +1416,13 @@ function loadESMFromCJS(mod, filename) { // createRequiredModuleFacade() to `wrap` which is a ModuleWrap wrapping // over the original module. - // We don't do this to modules that don't have default exports to avoid - // the unnecessary overhead. If __esModule is already defined, we will - // also skip the extension to allow users to override it. - if (!ObjectHasOwn(namespace, 'default') || ObjectHasOwn(namespace, '__esModule')) { + // We don't do this to modules that are marked as CJS ESM or that + // don't have default exports to avoid the unnecessary overhead. + // If __esModule is already defined, we will also skip the extension + // to allow users to override it. + if (ObjectHasOwn(namespace, 'module.exports')) { + mod.exports = namespace['module.exports']; + } else if (!ObjectHasOwn(namespace, 'default') || ObjectHasOwn(namespace, '__esModule')) { mod.exports = namespace; } else { mod.exports = createRequiredModuleFacade(wrap); diff --git a/test/es-module/test-require-as-esm-interop.mjs b/test/es-module/test-require-as-esm-interop.mjs new file mode 100644 index 00000000000000..8364fd6c2fceca --- /dev/null +++ b/test/es-module/test-require-as-esm-interop.mjs @@ -0,0 +1,51 @@ +// Flags: --experimental-require-module +import '../common/index.mjs'; +import assert from 'assert'; +import { directRequireFixture, importFixture } from '../fixtures/pkgexports.mjs'; + +const tests = { + 'false': false, + 'string': 'cjs', + 'object': { a: 'cjs a', b: 'cjs b' }, + 'fauxesmdefault': { default: 'faux esm default' }, + 'fauxesmmixed': { default: 'faux esm default', a: 'faux esm a', b: 'faux esm b' }, + 'fauxesmnamed': { a: 'faux esm a', b: 'faux esm b' } +}; + +// This test demonstrates interop between CJS and CJS represented as ESM +// under the new `export { ... as 'module.exports'}` pattern, for the above cases. +for (const [test, exactShape] of Object.entries(tests)) { + // Each case represents a CJS dependency, which has the expected shape in CJS: + assert.deepStrictEqual(directRequireFixture(`interop-cjsdep-${test}`), exactShape); + + // Each dependency is reexported through CJS as if it is a library being consumed, + // which in CJS is fully shape-preserving: + assert.deepStrictEqual(directRequireFixture(`interop-cjs/${test}`), exactShape); + + // Now we have ESM conversions of these dependencies, using `export ... as "module.exports"` + // staring with the conversion of those dependencies into ESM under require(esm): + assert.deepStrictEqual(directRequireFixture(`interop-cjsdep-${test}-esm`), exactShape); + + // When importing these ESM conversions, from require(esm), we should preserve the shape: + assert.deepStrictEqual(directRequireFixture(`interop-cjs/${test}-esm`), exactShape); + + // Now if the importer itself is converted into ESM, it should still be able to load the original + // CJS and reexport it, preserving the shape: + assert.deepStrictEqual(directRequireFixture(`interop-cjs-esm/${test}`), exactShape); + + // And then if we have the converted CJS to ESM importing from converted CJS to ESM, + // that should also work: + assert.deepStrictEqual(directRequireFixture(`interop-cjs-esm/${test}-esm`), exactShape); + + // Finally, the CJS ESM representation under `import()` should match all these cases equivalently, + // where the CJS module is exported as the default export: + const esmCjsImport = await importFixture(`interop-cjsdep-${test}`); + assert.deepStrictEqual(esmCjsImport.default, exactShape); + + assert.deepStrictEqual((await importFixture(`interop-cjsdep-${test}`)).default, exactShape); + assert.deepStrictEqual((await importFixture(`interop-cjs/${test}`)).default, exactShape); + assert.deepStrictEqual((await importFixture(`interop-cjsdep-${test}-esm`)).default, exactShape); + assert.deepStrictEqual((await importFixture(`interop-cjs/${test}-esm`)).default, exactShape); + assert.deepStrictEqual((await importFixture(`interop-cjs-esm/${test}`)).default, exactShape); + assert.deepStrictEqual((await importFixture(`interop-cjs-esm/${test}-esm`)).default, exactShape); +} diff --git a/test/fixtures/node_modules/interop-cjs-esm/false-esm.js b/test/fixtures/node_modules/interop-cjs-esm/false-esm.js new file mode 100644 index 00000000000000..44dd289dd080f4 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/false-esm.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-false-esm'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/false.js b/test/fixtures/node_modules/interop-cjs-esm/false.js new file mode 100644 index 00000000000000..63d896a4736bd6 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/false.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-false'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js new file mode 100644 index 00000000000000..3b87be4bd0c0bc --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault-esm.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-fauxesmdefault-esm'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js new file mode 100644 index 00000000000000..325fa352e16a81 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmdefault.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-fauxesmdefault'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js new file mode 100644 index 00000000000000..9390b24f8d8bf4 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed-esm.js @@ -0,0 +1,4 @@ +import dep from 'interop-cjsdep-fauxesmmixed-esm'; +export default dep; +export { dep as 'module.exports' } + diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js new file mode 100644 index 00000000000000..d649233736c31c --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmmixed.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-fauxesmmixed'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js new file mode 100644 index 00000000000000..6ba7e266bc57bd --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed-esm.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-fauxesmnamed-esm'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed.js b/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed.js new file mode 100644 index 00000000000000..7c6c6bfc14adcd --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/fauxesmnamed.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-fauxesmnamed'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/object-esm.js b/test/fixtures/node_modules/interop-cjs-esm/object-esm.js new file mode 100644 index 00000000000000..0a4e4283625e5b --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/object-esm.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-object-esm'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/object.js b/test/fixtures/node_modules/interop-cjs-esm/object.js new file mode 100644 index 00000000000000..08ef3ba4f96f3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/object.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-object'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/package.json b/test/fixtures/node_modules/interop-cjs-esm/package.json new file mode 100644 index 00000000000000..95315e635e7c30 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/package.json @@ -0,0 +1,17 @@ +{ + "type": "module", + "exports": { + "./false-esm": "./false-esm.js", + "./false": "./false.js", + "./fauxesmdefault-esm": "./fauxesmdefault-esm.js", + "./fauxesmdefault": "./fauxesmdefault.js", + "./fauxesmmixed-esm": "./fauxesmmixed-esm.js", + "./fauxesmmixed": "./fauxesmmixed.js", + "./fauxesmnamed-esm": "./fauxesmnamed-esm.js", + "./fauxesmnamed": "./fauxesmnamed.js", + "./object-esm": "./object-esm.js", + "./object": "./object.js", + "./string-esm": "./string-esm.js", + "./string": "./string.js" + } +} diff --git a/test/fixtures/node_modules/interop-cjs-esm/string-esm.js b/test/fixtures/node_modules/interop-cjs-esm/string-esm.js new file mode 100644 index 00000000000000..6072f01bc95eed --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/string-esm.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-string-esm'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs-esm/string.js b/test/fixtures/node_modules/interop-cjs-esm/string.js new file mode 100644 index 00000000000000..74297e8eee8d39 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs-esm/string.js @@ -0,0 +1,3 @@ +import dep from 'interop-cjsdep-string'; +export default dep; +export { dep as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjs/false-esm.js b/test/fixtures/node_modules/interop-cjs/false-esm.js new file mode 100644 index 00000000000000..eeb934952b51de --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/false-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-false-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/false.js b/test/fixtures/node_modules/interop-cjs/false.js new file mode 100644 index 00000000000000..459ccbeee45944 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/false.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-false'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmdefault-esm.js b/test/fixtures/node_modules/interop-cjs/fauxesmdefault-esm.js new file mode 100644 index 00000000000000..45e91e3c3c80da --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmdefault-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmdefault-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmdefault.js b/test/fixtures/node_modules/interop-cjs/fauxesmdefault.js new file mode 100644 index 00000000000000..c6e5176f528416 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmdefault.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmdefault'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmmixed-esm.js b/test/fixtures/node_modules/interop-cjs/fauxesmmixed-esm.js new file mode 100644 index 00000000000000..6b16d657b0e42d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmmixed-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmmixed-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmmixed.js b/test/fixtures/node_modules/interop-cjs/fauxesmmixed.js new file mode 100644 index 00000000000000..8897d00fb3e563 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmmixed.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmmixed'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmnamed-esm.js b/test/fixtures/node_modules/interop-cjs/fauxesmnamed-esm.js new file mode 100644 index 00000000000000..67ed05bfa7f6d4 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmnamed-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmnamed-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/fauxesmnamed.js b/test/fixtures/node_modules/interop-cjs/fauxesmnamed.js new file mode 100644 index 00000000000000..092ec333260157 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/fauxesmnamed.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-fauxesmnamed'); diff --git a/test/fixtures/node_modules/interop-cjs/object-esm.js b/test/fixtures/node_modules/interop-cjs/object-esm.js new file mode 100644 index 00000000000000..f0e0d3fa3dad07 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/object-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-object-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/object.js b/test/fixtures/node_modules/interop-cjs/object.js new file mode 100644 index 00000000000000..ff2d57e11b824f --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/object.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-object'); diff --git a/test/fixtures/node_modules/interop-cjs/package.json b/test/fixtures/node_modules/interop-cjs/package.json new file mode 100644 index 00000000000000..9e8c0b3f59712c --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/package.json @@ -0,0 +1,17 @@ +{ + "type": "commonjs", + "exports": { + "./false-esm": "./false-esm.js", + "./false": "./false.js", + "./fauxesmdefault-esm": "./fauxesmdefault-esm.js", + "./fauxesmdefault": "./fauxesmdefault.js", + "./fauxesmmixed-esm": "./fauxesmmixed-esm.js", + "./fauxesmmixed": "./fauxesmmixed.js", + "./fauxesmnamed-esm": "./fauxesmnamed-esm.js", + "./fauxesmnamed": "./fauxesmnamed.js", + "./object-esm": "./object-esm.js", + "./object": "./object.js", + "./string-esm": "./string-esm.js", + "./string": "./string.js" + } +} diff --git a/test/fixtures/node_modules/interop-cjs/string-esm.js b/test/fixtures/node_modules/interop-cjs/string-esm.js new file mode 100644 index 00000000000000..bdd23a1b1db4da --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/string-esm.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-string-esm'); diff --git a/test/fixtures/node_modules/interop-cjs/string.js b/test/fixtures/node_modules/interop-cjs/string.js new file mode 100644 index 00000000000000..65010183f2f76b --- /dev/null +++ b/test/fixtures/node_modules/interop-cjs/string.js @@ -0,0 +1 @@ +module.exports = require('interop-cjsdep-string'); diff --git a/test/fixtures/node_modules/interop-cjsdep-false-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-false-esm/dep.js new file mode 100644 index 00000000000000..7ef62281a771cb --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-false-esm/dep.js @@ -0,0 +1,3 @@ +const output = false; +export default output; +export { output as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjsdep-false-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-false-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-false-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-false/dep.js b/test/fixtures/node_modules/interop-cjsdep-false/dep.js new file mode 100644 index 00000000000000..a5d30209bd0bbc --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-false/dep.js @@ -0,0 +1 @@ +module.exports = false; diff --git a/test/fixtures/node_modules/interop-cjsdep-false/package.json b/test/fixtures/node_modules/interop-cjsdep-false/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-false/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/dep.js new file mode 100644 index 00000000000000..731bf61547a427 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/dep.js @@ -0,0 +1,7 @@ +const exports = {}; +Object.defineProperty(exports, '__esModule', { value: true }); +exports.default = 'faux esm default'; + +export default exports; + +export { exports as 'module.exports' } \ No newline at end of file diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/dep.js new file mode 100644 index 00000000000000..5cd0b37b27d054 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/dep.js @@ -0,0 +1,2 @@ +Object.defineProperty(exports, '__esModule', { value: true }); +exports.default = 'faux esm default'; diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmdefault/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/dep.js new file mode 100644 index 00000000000000..0eef418de77ea7 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/dep.js @@ -0,0 +1,9 @@ +const exports = {}; +Object.defineProperty(exports, '__esModule', { value: true }); +exports.default = 'faux esm default'; +exports.a = 'faux esm a'; +exports.b = 'faux esm b'; + +export default exports; + +export { exports as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/dep.js new file mode 100644 index 00000000000000..926ce033f829a0 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/dep.js @@ -0,0 +1,4 @@ +Object.defineProperty(exports, '__esModule', { value: true }); +exports.default = 'faux esm default'; +exports.a = 'faux esm a'; +exports.b = 'faux esm b'; diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmmixed/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/dep.js new file mode 100644 index 00000000000000..ac048c7b1634a7 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/dep.js @@ -0,0 +1,8 @@ +const exports = {}; +Object.defineProperty(exports, '__esModule', { value: true }); +exports.a = 'faux esm a'; +exports.b = 'faux esm b'; + +export default exports; + +export { exports as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/dep.js b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/dep.js new file mode 100644 index 00000000000000..e3218c09b35752 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/dep.js @@ -0,0 +1,3 @@ +Object.defineProperty(exports, '__esModule', { value: true }); +exports.a = 'faux esm a'; +exports.b = 'faux esm b'; diff --git a/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/package.json b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-fauxesmnamed/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-object-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-object-esm/dep.js new file mode 100644 index 00000000000000..f53cd1c055bd0a --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-object-esm/dep.js @@ -0,0 +1,8 @@ +const output = { + a: 'cjs a', + b: 'cjs b' +}; + +export default output; + +export { output as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjsdep-object-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-object-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-object-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-object/dep.js b/test/fixtures/node_modules/interop-cjsdep-object/dep.js new file mode 100644 index 00000000000000..c37089bccc741e --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-object/dep.js @@ -0,0 +1,2 @@ +exports.a = 'cjs a'; +exports.b = 'cjs b'; diff --git a/test/fixtures/node_modules/interop-cjsdep-object/package.json b/test/fixtures/node_modules/interop-cjsdep-object/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-object/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-string-esm/dep.js b/test/fixtures/node_modules/interop-cjsdep-string-esm/dep.js new file mode 100644 index 00000000000000..8b718c32a1fab5 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-string-esm/dep.js @@ -0,0 +1,3 @@ +const output = 'cjs'; +export default output; +export { output as 'module.exports' } diff --git a/test/fixtures/node_modules/interop-cjsdep-string-esm/package.json b/test/fixtures/node_modules/interop-cjsdep-string-esm/package.json new file mode 100644 index 00000000000000..f5b94a85497063 --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-string-esm/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./dep.js" +} diff --git a/test/fixtures/node_modules/interop-cjsdep-string/dep.js b/test/fixtures/node_modules/interop-cjsdep-string/dep.js new file mode 100644 index 00000000000000..b2825bd3c9949b --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-string/dep.js @@ -0,0 +1 @@ +module.exports = 'cjs'; diff --git a/test/fixtures/node_modules/interop-cjsdep-string/package.json b/test/fixtures/node_modules/interop-cjsdep-string/package.json new file mode 100644 index 00000000000000..e6fc9863573e3d --- /dev/null +++ b/test/fixtures/node_modules/interop-cjsdep-string/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "exports": "./dep.js" +} diff --git a/test/fixtures/pkgexports.mjs b/test/fixtures/pkgexports.mjs index 7d642c443e6b71..b71566b95c79ac 100644 --- a/test/fixtures/pkgexports.mjs +++ b/test/fixtures/pkgexports.mjs @@ -3,6 +3,10 @@ import { createRequire } from 'module'; const rawRequire = createRequire(fileURLToPath(import.meta.url)); +export function directRequireFixture(specifier) { + return rawRequire(specifier); +} + export async function requireFixture(specifier) { return { default: rawRequire(specifier ) }; }