Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does import of an ESM module in a CommonJS TypeScript project, result in ERR_REQUIRE_ESM?

I am trying to import the package p-limit into my typescript project. When trying to run the project using tsc && node serve.js, I run into the error below.

Im stuck at this for a few hours now...

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /project/node_modules/p-limit/index.js
require() of ES modules is not supported.
require() of /project/node_modules/p-limit/index.js from /project/dist/services/file.ts is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /project/node_modules/p-limit/package.json.

This piece of code in file.ts is causing the issue:

import pLimit from 'p-limit';
const limit = pLimit(1);

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "rootDir": "src",
    "outDir": "dist",
    "sourceMap": true,
    "experimentalDecorators": true,
    "types": [
      "node",
      "express"
    ],
    "strictNullChecks": true
  },
  "files": [
    "./node_modules/@types/node/index.d.ts",
    "./node_modules/p-limit/index.d.ts"
  ],
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

Node version: v14.18.0

like image 676
Joel'-' Avatar asked Dec 15 '25 18:12

Joel'-'


2 Answers

p-limit 4.0.0 and above are now ESM only. You can downgrade p-limit to 3.1.0 which is commonjs and it should work fine.

This package is now pure ESM. Please read this.

https://github.com/sindresorhus/p-limit/releases/tag/v4.0.0

Alternatively you can switch your project from CJS to ESM, but that's a larger issue.

https://nodejs.org/api/esm.html

like image 127
SNyamathi Avatar answered Dec 17 '25 10:12

SNyamathi


Starting from version 22.12.0, nodejs is able to require() ecmascript modules (ESM) with some constraints, you can check the documentation and constraints here.

In this case, p-limit can be loaded using this feature

Example

Using [email protected] (current latest LTS version)

npm init && npm i -DE [email protected] [email protected] @types/node
// test.ts
import pLimit from "p-limit"

const throttle = pLimit(2)

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))

const run = async () => {
    console.log("== START ==")

    const promises = Array(20).fill(0).map((_, idx) => throttle(async () => {
        await delay(1000)
        console.log("done", idx)
    }))
    
    await Promise.all(promises)

    console.log("== FINISH ==")
}

run()
# transpile to js
tsc --module commonjs test.ts

# run
node test.js

References:

  • Joyee Cheung's Blog, 2024-03-18: require(esm) in Node.js
like image 31
mateus Avatar answered Dec 17 '25 10:12

mateus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!