There's dozens of other questions with basically the same title, but none of the answers seem to be relevant and just add to the confusion.
This is my tsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": ["es2017", "es7", "es6", "dom"],
"declaration": true,
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"exclude": [
"node_modules",
"dist"
]
}
This is what I typed:
import md5 from 'js-md5';
import got from 'got';
import { Design } from './Design';
...
This is my error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\Users\...\node_modules\got\dist\source\index.js require() of ES modules is not supported.
What. I'm not using require
, I'm using import
. I haven't had this error on any other modules, so why is Got different (and why is nothing ever simple)?
Why is this happening and how do I fix it?
As per @jsejcksn's answer, I tried changing my tsconfig.json
to the following:
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"lib": ["es2017", "es7", "es6", "dom"],
"declaration": true,
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"exclude": [
"node_modules",
"dist"
]
}
... and added "type": "module"
to my package.json
:
{
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"fs-extra": "^10.0.0",
"got": "^12.0.1",
"js-md5": "^0.7.3",
"moment": "^2.29.1",
"semver": "^7.3.5",
"typescript": "^4.4.3",
"uuid": "^8.3.2",
"@types/node": "^16.9.2",
"@types/express": "^4.17.13",
"@types/fs-extra": "^9.0.13",
"@types/semver": "^7.3.9",
"@types/uuid": "^8.3.1",
"@types/js-md5": "^0.4.3"
},
"type": "module"
}
But now I just get different errors :|
src/Logging.ts:1:20 - error TS2792: Cannot find module 'moment'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
1 import moment from 'moment';
src/SyncAPI.ts:2:17 - error TS2792: Cannot find module 'got'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
2 import got from 'got';
You have configured TypeScript to compile your modules to CommonJS format (your TSConfig option compilerOptions.module
is set to "commonjs"
). You'll need to set that option to an ESM-compatible setting (such as "esnext"
) so that the compiled JavaScript emitted by the TS compiler is in ESM format.
In your package.json
, you'll probably also need to set the "type"
field to "module"
.
Edit: To use npm packages by name as bare specifiers in your import statements, you'll also need to update your TSConfig compilerOptions.moduleResolution
to "node"
. In your current config, you have included "dom"
in the compilerOptions.lib
array. "dom"
is for environments with a DOM (which Node does not natively have), so that shouldn't be there. Instead, setting that array to ["es2017"]
will include the others you have specified.
Edit: In attempt to provide more direct guidance:
^16.x.x
)^4.5.x
)./src
(if they're not already in that directory), and./tsconfig.json
:{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"esModuleInterop": true,
"lib": [
"es2021"
],
"module": "esnext",
"moduleResolution": "node",
"outDir": "dist",
"strict": true,
"target": "es2021"
},
"include": [
"src/**/*"
]
}
./package.json
is set to "module":{
// ...
"type": "module"
// ...
}
You shouldn't have any trouble with import
statement module system compatibility after that.