node/test/es-module/test-require-module-dynamic-import-1.js
Joyee Cheung e77aac2a5f module: add __esModule to require()'d ESM
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>
2024-07-11 18:59:31 +00:00

32 lines
1.0 KiB
JavaScript

// Flags: --experimental-require-module
'use strict';
// Tests that previously dynamically import()'ed results are reference equal to
// require()'d results.
const common = require('../common');
const assert = require('assert');
const path = require('path');
const { pathToFileURL } = require('url');
(async () => {
const modules = [
'../fixtures/es-module-loaders/module-named-exports.mjs',
'../fixtures/es-modules/import-esm.mjs',
'../fixtures/es-modules/require-cjs.mjs',
'../fixtures/es-modules/cjs-exports.mjs',
'../common/index.mjs',
'../fixtures/es-modules/package-type-module/index.js',
];
for (const id of modules) {
const url = pathToFileURL(path.resolve(__dirname, id));
const imported = await import(url);
const required = require(id);
common.expectRequiredModule(required, imported);
}
const id = '../fixtures/es-modules/data-import.mjs';
const imported = await import(id);
const required = require(id);
assert.strictEqual(imported.data, required.data);
})().then(common.mustCall());