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

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module #1975

Closed
shahinghasemi opened this issue Jan 31, 2022 · 7 comments
Closed

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module #1975

shahinghasemi opened this issue Jan 31, 2022 · 7 comments

Comments

@shahinghasemi
Copy link

shahinghasemi commented Jan 31, 2022

Hello, this is my code:

// ./src/index.ts
import { WebSocketServer, Server } from 'ws';
const conm = new WebSocketServer({port: 3000})
console.log('conn: ', conn)
// esbuild.js
esBuild.build({
    bundle: true,
    entryPoints: ['./src/index.ts'],
    outdir: 'dist',
    external: ['./node_modules/*'],
    platform: 'node',
    sourcemap: true,
    watch: true,
}).then((result)=>{
    console.log('backend is ready. looking for changes...')
})
// tsconfig.json
    "compilerOptions": {
        "allowUnreachableCode": false,
        "noImplicitAny": true,
        "exactOptionalPropertyTypes": true,
        "noImplicitOverride": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "strict": true,

        "module": "CommonJS",
        "moduleResolution": "Node",

        "target": "ES2021",

        "allowJs": true,
        "checkJs": true,

        "downlevelIteration": true,
        "noEmitOnError": true,

        "outDir": "dist",
        "noEmit": true,

        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "importHelpers": true,
        "noFallthroughCasesInSwitch": true,
        "baseUrl": "./",

        "resolveJsonModule": true,

    },

And this is the built(bundled) file:

// src/index.ts
**var import_ws = require("../node_modules/ws/wrapper.mjs");** // PROBLEM is here
var conn = new import_ws.WebSocketServer({ port: 3e3 });
console.log("conn: ", conn);
//# sourceMappingURL=index.js.map

However when I run node ./dist/index.js, it throws this error:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /absolut/path/to/backend/node_modules/ws/wrapper.mjs

I checked ws's package.json and I guess the problem is for this:

  "exports": {
    "import": "./wrapper.mjs",
    "require": "./index.js"
  },

According to docs, setting platform:node will set format to cjs so it should use ws's index.js not wrapper.mjs. I don't know what's the problem. I also set format: esm and again run bundled file but it throws

SyntaxError: Cannot use import statement outside a module
@xinaesthete
Copy link

xinaesthete commented Feb 1, 2022

I am having related problems, also with ws.

In your case, perhaps you need to explicity specify format: 'cjs' in your esbuild configuration - that might also depend on parts of your package.json that you didn't mention (and that I'm not sure about myself).

I might try to see if I can reproduce your issue. I was previously using ws with esbuild targetting cjs without issue, but am trying to change that because of a problem with clipboardy when built as cjs.

In my case (at the moment, I've been through some other permutations), I have format=esm in my esbuild args, and "target": "es2018", "module": "esnext" in tsconfig. This results in Error: Dynamic require of "stream" is not supported when it gets to this point of the built file:

// node_modules/ws/wrapper.mjs
var import_stream = __toESM(require_stream(), 1);

I know that this is a different issue really, but seeing that it appears somewhat related I thought it might not do any harm to dump some of my experience here. I wasn't quite at the point that I was sure whether it was appropriate to file as an issue or not.

@xinaesthete
Copy link

p.s. you could also try making ws external, which may not be a solution, but may help diagnose, and may be a viable workaround if necessary.

@shahinghasemi
Copy link
Author

Setting type: module in package.json and format: esm in esbuild's config fixed the issue, but what remains unanswered is why setting format:cjs does resolve ws import to ./wrapper.mjs instead of ./index.js ?!

@xinaesthete
Copy link

xinaesthete commented Feb 1, 2022

Agreed. I'm also not sure why format: esm works for you, while I get Error: Dynamic require of "stream" is not supported.

In my case I am running node v16.6.0 in Windows 10, FWIW.

Also "esbuild": "^0.14.16", "ws": "^8.4.2" (both @latest as of this writing, I believe).

@relative
Copy link

relative commented Feb 15, 2022

but what remains unanswered is why setting format:cjs does resolve ws import to ./wrapper.mjs instead of ./index.js ?!

this only seems to occur when I supply external: ['./node_modules/*'], not when I manually supply each module's name

@BenGladman
Copy link

BenGladman commented Mar 3, 2022

I am having the same problem.

When I use the cli options --platfom=node --external:./node_modules/*, esbuild first resolves the import path as ESM, then matches it, and then uses the resolved path in the transformed code.

So (in my project) import ... from 'zod' becomes require("../../node_modules/zod/lib/index.mjs"). This fails at runtime because index.mjs is an ESM module.

Ideally in this case, I would like the transformed code to use the original bare module name - i.e. just require('zod'). Then node could apply its own rules to import it.

I can get around the problem by also specifying the particular problem package, i.e. --platfom=node --external:./node_modules/* --external=zod. When I do that, the transformed code contains many resolved node_modules paths, but zod in particular uses the bare module name require('zod').

But I think it would be nicer if I didn't have to do that, and the module resolution was left to node for all external packages.

@BenGladman
Copy link

This is the same issue as #1958 I think

@evanw evanw closed this as completed in 7277ffd Dec 13, 2022
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

No branches or pull requests

4 participants