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

Make ESM named imports work in Node #531

Merged
merged 2 commits into from
Jul 10, 2023
Merged

Make ESM named imports work in Node #531

merged 2 commits into from
Jul 10, 2023

Conversation

alcuadrado
Copy link
Member

Importing slang from a native ESM module is pretty cumbersome in Node right now. Here's an example of an error you may get if you try to use a normal named import:

% node index.mjs
file:///private/tmp/npmproject-4/index.mjs:6
import { ProductionKind } from "@nomicfoundation/slang/syntax/parser/index.js";
         ^^^^^^^^^^^^^^
SyntaxError: Named export 'ProductionKind' not found. The requested module '@nomicfoundation/slang/syntax/parser/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@nomicfoundation/slang/syntax/parser/index.js';
const { ProductionKind } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)

Node.js v18.16.1

This PR changes how we export things in JavaScript so that named imports from ESM modules work in Node.js.

The difference is really subtle and may be hard to understand at first glance, so here's an explanation:

  • CJS and ESM aren't really compatible, but Node implements a compatibility mode which is not fully transparent.
  • One of the things that is not transparent is the default export, as that doesn't exist in CJS.
  • The compatibility layer hence treats reassigning module.exports as a default exports, hoping that it was the original intention of the author. That leads to named imports from ESM not working if you reassign it.
  • If you keep the original module.exports and just add properties to it, those are treated as named exports.

@alcuadrado alcuadrado requested a review from a team as a code owner July 10, 2023 16:58
@changeset-bot
Copy link

changeset-bot bot commented Jul 10, 2023

🦋 Changeset detected

Latest commit: 4a15766

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Collaborator

@OmarTawfik OmarTawfik left a comment

Choose a reason for hiding this comment

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

Thank you for catching this!

@OmarTawfik OmarTawfik added this pull request to the merge queue Jul 10, 2023
Merged via the queue into main with commit e3450be Jul 10, 2023
@OmarTawfik OmarTawfik deleted the fix-node-esm branch July 10, 2023 23:16
github-merge-queue bot pushed a commit that referenced this pull request Jul 12, 2023
Looks like #531 broke CI, since it used a changeset with a different
package name. This absorbs the remaining changeset to unblock CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants