Skip to content

Commit

Permalink
fixup! esm: add experimental support for addon modules
Browse files Browse the repository at this point in the history
  • Loading branch information
legendecas committed Dec 6, 2024
1 parent 2ea455d commit 389b5c5
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 16 deletions.
23 changes: 12 additions & 11 deletions lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,14 @@ function createCJSNoSourceModuleWrap(url, isMain) {

// Addon export names are not known until the addon is loaded.
const exportNames = ['default', 'module.exports'];
return new ModuleWrap(url, undefined, exportNames, function() {
return new ModuleWrap(url, undefined, exportNames, function evaluationCallback() {
debug(`Loading CJSModule ${url}`);

if (!module.loaded) {
wrapModuleLoad(filename, null, isMain);
}

/** @type {import('./loader').ModuleExports} */
let exports;
if (module[kModuleExport] !== undefined) {
exports = module[kModuleExport];
Expand Down Expand Up @@ -323,18 +324,18 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) {
*/
function cjsEmplaceModuleCacheEntry(filename, exportNames) {
// TODO: Do we want to keep hitting the user mutable CJS loader here?
let module = CJSModule._cache[filename];
if (module) {
return module;
let cjsMod = CJSModule._cache[filename];
if (cjsMod) {
return cjsMod;
}

module = new CJSModule(filename);
module.filename = filename;
module.paths = CJSModule._nodeModulePaths(module.path);
module[kIsCachedByESMLoader] = true;
CJSModule._cache[filename] = module;
cjsMod = new CJSModule(filename);
cjsMod.filename = filename;
cjsMod.paths = CJSModule._nodeModulePaths(cjsMod.path);
cjsMod[kIsCachedByESMLoader] = true;
CJSModule._cache[filename] = cjsMod;

return module;
return cjsMod;
}

/**
Expand Down Expand Up @@ -510,7 +511,7 @@ translators.set('wasm', async function(url, source) {
});

// Strategy for loading a addon
translators.set('addon', function(url, source, isMain) {
translators.set('addon', function translateAddon(url, source, isMain) {
emitExperimentalWarning('Importing addons');

// The addon must be loaded from file system with dlopen. Assert
Expand Down
1 change: 1 addition & 0 deletions test/addons/esm-package-dependent/node_modules/esm-package

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

10 changes: 10 additions & 0 deletions test/addons/esm-package-dependent/test-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Flags: --experimental-addon-modules
'use strict';
const common = require('../../common');
const assert = require('node:assert');

import(`esm-package/${common.buildType}`)
.then((mod) => {
assert.strictEqual(mod.default.hello(), 'world');
})
.then(common.mustCall());
10 changes: 10 additions & 0 deletions test/addons/esm-package-dependent/test-require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Flags: --experimental-addon-modules
'use strict';
const common = require('../../common');
const assert = require('node:assert');

require(`esm-package/${common.buildType}`)
.then((mod) => {
assert.strictEqual(mod.hello(), 'world');
})
.then(common.mustCall());
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions test/addons/esm-package/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "esm-package",
"exports": {
"./Debug": {
"node-addons": "./build/Debug/binding.node"
},
"./Release": {
"node-addons": "./build/Release/binding.node"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* This file is supposed to be loaded by `test-import.js` and `test-require.js`
* to verify that `import('*.node')` is working properly either been loaded with
* the ESM loader or the CJS loader.
*/

// eslint-disable-next-line node-core/require-common-first
import { buildType } from '../../common/index.mjs';
import assert from 'node:assert';
Expand All @@ -9,6 +15,7 @@ export async function run() {
// binding.node
{
const bindingPath = require.resolve(`./build/${buildType}/binding.node`);
// Test with order of import+require
const { default: binding, 'module.exports': exports } = await import(bindingPath);
assert.strictEqual(binding, exports);
assert.strictEqual(binding.hello(), 'world');
Expand All @@ -28,14 +35,14 @@ export async function run() {
// binding-export-default.node
{
const bindingPath = require.resolve(`./build/${buildType}/binding-export-default.node`);
// Test with order of require+import
const bindingRequire = require(bindingPath);
const ns = await import(bindingPath);
assert.strictEqual(ns.default, bindingRequire);

// As same as ESM-import-CJS, the default export is the value of `module.exports`.
assert.strictEqual(ns.default, ns['module.exports']);
assert.strictEqual(ns.default.default(), 'hello world');

const bindingRequire = require(bindingPath);
assert.strictEqual(ns.default, bindingRequire);
}

// binding-export-primitive.node
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Flags: --experimental-addon-modules

'use strict';
const common = require('../../common');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Flags: --experimental-addon-modules
'use strict';

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

require('./test-esm.mjs')
Expand Down

0 comments on commit 389b5c5

Please sign in to comment.