mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
Tooling in the ecosystem have been using the __esModule property to
recognize transpiled ESM in consuming code. For example, a 'log'
package written in ESM:
export function log(val) { console.log(val); }
Can be transpiled as:
exports.__esModule = true;
exports.default = function log(val) { console.log(val); }
The consuming code may be written like this in ESM:
import log from 'log'
Which gets transpiled to:
const _mod = require('log');
const log = _mod.__esModule ? _mod.default : _mod;
So to allow transpiled consuming code to recognize require()'d real ESM
as ESM and pick up the default exports, we add a __esModule property by
building a source text module facade for any module that has a default
export and add .__esModule = true to the exports. We don't do this to
modules that don't have default exports to avoid the unnecessary
overhead. This maintains the enumerability of the re-exported names
and the live binding of the exports.
The source of the facade is defined as a constant per-isolate property
required_module_facade_source_string, which looks like this
export * from 'original';
export { default } from 'original';
export const __esModule = true;
And the 'original' module request is always resolved by
createRequiredModuleFacade() to wrap which is a ModuleWrap wrapping
over the original module.
PR-URL: https://github.com/nodejs/node/pull/52166
Refs: https://github.com/nodejs/node/issues/52134
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
55 lines
1.5 KiB
JavaScript
55 lines
1.5 KiB
JavaScript
// Flags: --experimental-require-module
|
|
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
|
|
common.expectWarning(
|
|
'ExperimentalWarning',
|
|
'Support for loading ES Module in require() is an experimental feature ' +
|
|
'and might change at any time'
|
|
);
|
|
|
|
// Test named exports.
|
|
{
|
|
const mod = require('../fixtures/es-module-loaders/module-named-exports.mjs');
|
|
common.expectRequiredModule(mod, { foo: 'foo', bar: 'bar' });
|
|
}
|
|
|
|
// Test ESM that import ESM.
|
|
{
|
|
const mod = require('../fixtures/es-modules/import-esm.mjs');
|
|
common.expectRequiredModule(mod, { hello: 'world' });
|
|
}
|
|
|
|
// Test ESM that import CJS.
|
|
{
|
|
const mod = require('../fixtures/es-modules/cjs-exports.mjs');
|
|
common.expectRequiredModule(mod, { });
|
|
}
|
|
|
|
// Test ESM that require() CJS.
|
|
{
|
|
const mjs = require('../common/index.mjs');
|
|
// Only comparing a few properties because the ESM version of test/common doesn't
|
|
// re-export everything from the CJS version.
|
|
assert.strictEqual(common.mustCall, mjs.mustCall);
|
|
assert.strictEqual(common.localIPv6Hosts, mjs.localIPv6Hosts);
|
|
}
|
|
|
|
// Test "type": "module" and "main" field in package.json.
|
|
// Also, test default export.
|
|
{
|
|
const mod = require('../fixtures/es-modules/package-type-module');
|
|
common.expectRequiredModule(mod, { default: 'package-type-module' });
|
|
}
|
|
|
|
// Test data: import.
|
|
{
|
|
const mod = require('../fixtures/es-modules/data-import.mjs');
|
|
common.expectRequiredModule(mod, {
|
|
data: { hello: 'world' },
|
|
id: 'data:text/javascript,export default %7B%20hello%3A%20%22world%22%20%7D'
|
|
});
|
|
}
|