Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

esm: add experimental support for addon modules #55844

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

legendecas
Copy link
Member

Add experimental support to loading .node extension modules in ESM.

An addon exports two names default and module.exports, as same as import(cjs) where
its export names can not be preparsed. Addon export names can not be inferred until it is evaluated.

Fixes: #40541
Fixes: #55821

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/gyp
  • @nodejs/loaders

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Nov 14, 2024
@legendecas legendecas force-pushed the esm/addon branch 2 times, most recently from 304bd08 to c6ce9fd Compare November 14, 2024 09:53
@aduh95
Copy link
Contributor

aduh95 commented Nov 14, 2024

The commit message does not meet our guidelines, the word after the subsystem should be an infinitive verb. I suggest esm: add experimental support for addon modules


// The addon must be loaded from file system with dlopen. Assert
// the source is null.
validateNull(source, 'source');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not an argument, it wouldn't make sense to throw ERR_INVALID_ARG_TYPE. TBH I think we can simply ignore the source

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO asserting it to be null could prevent loader from unexpectedly reading the .node file from fs. It is true that it is not used. Discarding it silently could be confusing.

Copy link
Contributor

@aduh95 aduh95 Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, let's not throw ERR_INVALID_ARG_TYPE, it's only going to be confusing. A more fitting error code would be ERR_INVALID_RETURN_PROPERTY_VALUE

Comment on lines +8 to +9
import('./test-esm.mjs')
.then(common.mustCall(), common.mustNotCall());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW the common.mustNotCall() is not necessary. I assume we also want to test if loading it with require works

Suggested change
import('./test-esm.mjs')
.then(common.mustCall(), common.mustNotCall());
import('./test-esm.mjs').then(common.mustCall());
require('./test-esm.mjs');

@legendecas legendecas changed the title esm: experimental addon modules esm: add experimental addon modules Nov 14, 2024
@legendecas legendecas changed the title esm: add experimental addon modules esm: add experimental support for addon modules Nov 14, 2024
added: REPLACEME
-->

Enable experimental addon modules with extension `.node` support.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Enable experimental addon modules with extension `.node` support.
> Stability: 1.0 - Early development
Enable experimental addon modules with extension `.node` support.

* @param {string} [source] - The source code of the module.
*/
function cjsPreparseModuleExports(filename, source) {
function cjsEmplaceModuleCacheEntry(filename) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this please get a JSDoc?

@@ -459,6 +509,19 @@ translators.set('wasm', async function(url, source) {
}).module;
});

// Strategy for loading a addon
translators.set('addon', async function(url, source, isMain) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This function doesn’t contain await, so it doesn’t need to be async?

Suggested change
translators.set('addon', async function(url, source, isMain) {
translators.set('addon', function(url, source, isMain) {

* @callback validateNull
* @param {*} value
* @param {string} name
* @returns {asserts value is null}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @returns {asserts value is null}
* @returns whether or not the value is null

Nit: The return description isn’t a value, it’s an explanation, so it doesn’t go in braces (I think?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -411,6 +411,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"Treat the entrypoint as a URL",
&EnvironmentOptions::entry_is_url,
kAllowedInEnvvar);
AddOption("--experimental-addon-modules",
"experimental ES Module support for addons",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"experimental ES Module support for addons",
"experimental import support for addons",

Technically we’re adding support to import, which exists in CommonJS too as import().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for import('./native.node') Can not import .node file in esm
5 participants