Skip to content

Commit

Permalink
module: implement the "module" exports condition
Browse files Browse the repository at this point in the history
The "module" exports condition has been used by bundlers in
the wild to support require(esm) in bundles targeting the
Node.js environment. This patch implements the same condition
for the native require(esm) implementation in Node.js to match
bundler behaviors in the ecosystem.

The tests added in this patch match the output from webpack
bundles.

Refs: https://gist.github.com/sokra/e032a0f17c1721c71cfced6f14516c62
  • Loading branch information
joyeecheung committed Aug 29, 2024
1 parent 321a14b commit 89c1e4f
Show file tree
Hide file tree
Showing 32 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/internal/modules/esm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ function initializeDefaultConditions() {
defaultConditions = ObjectFreeze([
'node',
'import',
'module',
...addonConditions,
...userConditions,
]);
Expand Down
3 changes: 3 additions & 0 deletions lib/internal/modules/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ function initializeCjsConditions() {
...addonConditions,
...userConditions,
]);
if (getOptionValue('--experimental-require-module')) {
cjsConditions.add('module');
}
}

/**
Expand Down
27 changes: 27 additions & 0 deletions test/es-module/test-import-module-conditional-exports-module.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import '../common/index.mjs';
import assert from 'node:assert';
import * as staticImport from '../fixtures/es-modules/module-condition/import.mjs';
import { import as _import } from '../fixtures/es-modules/module-condition/dynamic_import.js';

async function dynamicImport(id) {
const result = await _import(id);
return result.resolved;
}

assert.deepStrictEqual({ ...staticImport }, {
import_module_require: 'import',
module_and_import: 'module',
module_and_require: 'module',
module_import_require: 'module',
module_only: 'module',
module_require_import: 'module',
require_module_import: 'module',
});

assert.strictEqual(await dynamicImport('import-module-require'), 'import');
assert.strictEqual(await dynamicImport('module-and-import'), 'module');
assert.strictEqual(await dynamicImport('module-and-require'), 'module');
assert.strictEqual(await dynamicImport('module-import-require'), 'module');
assert.strictEqual(await dynamicImport('module-only'), 'module');
assert.strictEqual(await dynamicImport('module-require-import'), 'module');
assert.strictEqual(await dynamicImport('require-module-import'), 'module');
15 changes: 15 additions & 0 deletions test/es-module/test-require-module-conditional-exports-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Flags: --experimental-require-module
'use strict';

require('../common');
const assert = require('assert');

const loader = require('../fixtures/es-modules/module-condition/require.cjs');

assert.strictEqual(loader.require('import-module-require').resolved, 'module');
assert.strictEqual(loader.require('module-and-import').resolved, 'module');
assert.strictEqual(loader.require('module-and-require').resolved, 'module');
assert.strictEqual(loader.require('module-import-require').resolved, 'module');
assert.strictEqual(loader.require('module-only').resolved, 'module');
assert.strictEqual(loader.require('module-require-import').resolved, 'module');
assert.strictEqual(loader.require('require-module-import').resolved, 'require');
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export async function resolve(specifier, context, defaultResolve) {

deepStrictEqual([...context.conditions].sort(), [
'import',
'module',
'node',
'node-addons',
]);
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/es-modules/module-condition/dynamic_import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function load(id) {
return import(id);
}

export { load as import };
7 changes: 7 additions & 0 deletions test/fixtures/es-modules/module-condition/import.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { resolved as import_module_require } from 'import-module-require';
export { resolved as module_and_import } from 'module-and-import';
export { resolved as module_and_require } from 'module-and-require';
export { resolved as module_import_require } from 'module-import-require';
export { resolved as module_only } from 'module-only';
export { resolved as module_require_import } from 'module-require-import';
export { resolved as require_module_import } from 'require-module-import';

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/es-modules/module-condition/require.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.require = require;

0 comments on commit 89c1e4f

Please sign in to comment.