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

[BUG] CommonJS file with ESM syntax is exported as "module" #692

Closed
2 tasks done
cdauth opened this issue Mar 6, 2023 · 4 comments
Closed
2 tasks done

[BUG] CommonJS file with ESM syntax is exported as "module" #692

cdauth opened this issue Mar 6, 2023 · 4 comments

Comments

@cdauth
Copy link

cdauth commented Mar 6, 2023

Before you begin...

  • I have searched the existing issues
  • I am not using version 13.x of node (if so, please upgrade)

Description of the problem

The exports in package.json currently contains this:

  "main": "./dist/index.js",
  "exports": {
    ".": {
      "node": {
        "module": "./dist/esm-node/index.js",
        "require": "./dist/index.js",
        "import": "./wrapper.mjs"
      },
      "browser": {
        "import": "./dist/esm-browser/index.js",
        "require": "./dist/commonjs-browser/index.js"
      },
      "default": "./dist/esm-browser/index.js"
    },
    "./package.json": "./package.json"
  },
  "module": "./dist/esm-node/index.js",

In a Node.js environment, the .js files are interpreted as CommonJS and the .mjs file as ESM, since no "type": "module" is defined. This means that the files in ./dist/esm-*/*.js are interpreted as CJS, even though they contain ESM code.

In a normal Node.js ESM environment, this is not a problem, since it will resolve to the .mjs file defined in the node.import export. However, there are other environments which resolve dependencies in a different way but still interpret the file extensions in the same way as Node.js.

Problem with esbuild

In particular, I'm having trouble with a project that is compiled using esbuild. According to its docs, in node mode, the modules condition is included by default, so the node.module export is used, leading to the following error:

import { v4 } from "../../node_modules/uuid/dist/esm-node/index.js";
         ^^
SyntaxError: Named export 'v4' not found. The requested module '../../node_modules/uuid/dist/esm-node/index.js' is a CommonJS module, which may not support all module.exports as named exports

As a workaround, I specified conditions: [] in my esbuild config.

Problem with jest

I'm also experiencing the same problem with Jest that is reported in #678. Testing has revealed that Jest (at least in a jsdom environment) uses the browser.import export.

Suggested solution

In other issues reported here I have seen comments about needing to add "type": "module", which would have a lot of side effects and break things. I think this is not needed, it is only needed to rename the ESM bundles to .mjs. I believe this would also make the wrapper.mjs file unnecessary.

There might be some outdated build tools that don't support the .mjs extension yet. In immerjs/immer#939, we had this problem with Metro, however the underlying issue facebook/metro#535 seems to have been fixed by now. If support for such outdated build tools should be preserved, a .js ESM file should be referenced in the module field in package.json (while a .mjs file should be in the exports.module field).

Recipe for reproducing

To reproduce the issue with esbuild, create a file test.mjs that imports uuid:

import { v4 } from 'uuid';

Then build the file by executing a Node.js script with the following content:

import { build } from 'esbuild';
import { fileURLToPath } from 'url';

await build({
    entryPoints: [fileURLToPath(new URL('./test.mjs', import.meta.url))],
    platform: 'node',
    bundle: true,
    format: 'esm',
    outfile: './out.mjs',
    external: ['./node_modules/*']
});

It is important to use a recent version of esbuild, as older versions were not using the module condition.

Additional information

No response

Environment

No response

@github-actions
Copy link

github-actions bot commented Jun 5, 2023

Marking as stale due to 90 days with no activity.

@github-actions github-actions bot added stale and removed stale labels Jun 5, 2023
@github-actions
Copy link

github-actions bot commented Sep 5, 2023

Marking as stale due to 90 days with no activity.

@github-actions github-actions bot added the stale label Sep 5, 2023
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

Closing issue due to 30 days since being marked as stale.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 6, 2023
@bjmc
Copy link

bjmc commented Mar 19, 2024

We're running into this issue with Jest tests in a jsdom test environment. Is there any interest from the maintainers in accepting a patch?

The fix suggested by @cdauth sounds like it should be relatively low impact (compared to adding "type": "module")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants