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

Add support for package.json exports field #904

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sgammon
Copy link

@sgammon sgammon commented Mar 24, 2025

If a module package.json specifies exports, GraalJs will now read them and prefer exports over standard resolution; export types can be registered by the developer as preferred. In lieu of these types (and as a default), the following export types are preferred, in order:

  • graaljs
  • import (in ESM)
  • require
  • default

Fixes and closes #903

This is quick and dirty and probably not mergeable as expressed, but we are using it effectively downstream.

cc / @woess

If a module `package.json` specifies `exports`, GraalJs will now read
them and prefer exports over standard resolution; export types can be
registered by the developer as preferred. In lieu of these types (and
as a default), the following export types are preferred, in order:

- `graaljs`
- `import` (in ESM)
- `require`
- `default`

Fixes and closes oracle#903

Relates-to: oracle#903
Signed-off-by: Sam Gammon <[email protected]>
@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Mar 24, 2025
@sgammon sgammon changed the title Add support for package.json exports field Add support for package.json exports field. Mar 24, 2025
@sgammon sgammon changed the title Add support for package.json exports field. Add support for package.json exports field Mar 24, 2025
@sgammon
Copy link
Author

sgammon commented Mar 24, 2025

I don't know how to add tests to GraalJs yet. I'm happy to figure it out and add tests if there is any desire to merge this

@sgammon sgammon mentioned this pull request Mar 24, 2025
12 tasks
);
}

public static void registerPreferredExportType(String exportType) {
Copy link
Member

Choose a reason for hiding this comment

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

Where is this used and for what?

Copy link
Author

Choose a reason for hiding this comment

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

This would be used by embedders:

NpmCompatibleESModuleLoader.registerPreferredExportType("elide");

... would register the engine elide as a preferred token, greater in precedence than graaljs, import, require, or default. Perhaps a browser builder could register "browser" to prefer imports of that type.

Copy link
Member

Choose a reason for hiding this comment

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

I see... could you do this in a way that does not require modifying a static final list?

Copy link
Author

@sgammon sgammon Mar 27, 2025

Choose a reason for hiding this comment

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

@woess I can try; for example, what if the embedder registers a callback to provide a list of candidate strings? I just figure the callback would probably not need to be dynamic in nature (these strings are likely registered once at startup and not again).

I could wrap the list in an atomic, but that wouldn't do much. What would you recommend as an approach for this one?

@woess
Copy link
Member

woess commented Mar 26, 2025

Happy to accept contributions in that area. The commonjs support has been a bit neglected tbh...

We will need some test coverage for it.

I think you can find most of the tests here:
graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/builtins/CommonJSRequireTest.java
graal-js/src/com.oracle.truffle.js.test/commonjs
graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/builtins/CommonJSWithCustomFsTest.java

@sgammon
Copy link
Author

sgammon commented Mar 26, 2025

@woess Thanks for the review. I'll take a look at adding some tests

// 1.1: is it specified within the exports?
if (exports.containsKey(preferred)) {
// 1.2: if so, resolve the import from the package root. make sure to slice off the `./` prefix.
return packageUrl.resolve(exports.get(preferred).substring(2));
Copy link
Member

@woess woess Mar 26, 2025

Choose a reason for hiding this comment

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

I don't see a check that the string actually starts with ./ or is has length >= 2, only a startsWith(".").

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, will add

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for exports in package.json
2 participants