My setup is as follows:
I have a package.json
file:
{
"name": "discord-app-test",
"version": "1.0.0",
"main": "src/index.ts",
"license": "ISC",
"scripts": {
"dev": "nodemon --exec \"yarn start\" --watch src --ext ts,json --ignore *.test.ts",
"start": "ts-node ."
},
"dependencies": {
"dotenv": "^10.0.0",
"node-fetch": "^3.0.0"
},
"devDependencies": {
"@types/node": "^16.11.6"
}
}
I have no tsconfig.json
file as I never need it, normally. Though, somehow when using the node-fetch
package, I get this error saying " require() of ES Module [...] is not supported
" even though I am importing it with the ES6 syntax:
import fetch from 'node-fetch';
I have tried specifying "type": "module"
in my package.json, but then I got the error " Unknown file extension ".ts" for [...]
".
You probably want to use "type": "module"
because this is the new way to import stuff in node. With this flag you tell node to use ESM for imports which is the syntax you've used in your question.
ESM is fairly new, so most tools have an opt-in for this and so does ts-node
, you've to add the --esm
argument.
$ ts-node --esm ./index.ts
Running this still fails with
$ ts-node --esm ./index.ts
ReferenceError: exports is not defined in ES module scope
at file:///path/to/index.ts:5:23
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
The error is because of tsc
s --module
default which ts-node
internally uses.
--target
: Default: ES3
--module
: Default CommonJS if target is ES3 or ES5,ES6/ES2015 otherwise.
https://www.typescriptlang.org/docs/handbook/compiler-options.html
tsc
will transpile scripts to CommonJS, because --target
default is ES3 and then the --module
default is CommonJS.
You can check this by manually running the TypeScript compiler.
index.ts
import fetch from "node-fetch";
fetch("https://example.org");
$ tsc ./index.ts
index.js (created by tsc)
"use strict";
exports.__esModule = true;
var node_fetch_1 = require("node-fetch");
(0, node_fetch_1["default"])("https://example.org");
The.ts file was transpiled for CommonJS (it uses require
).
When you define "type": "module"
inside your package.json
, you tell node to use the new import syntax, but tsc ignores that and still outputs it in the old format.
If you want to use the new import syntax natively in node, then you can fix the problem by defining the module to nodenext
which describes the ESM support for node.
$ tsc --module nodenext ./index.ts
index.js (created by tsc)
import fetch from "node-fetch";
fetch("https://example.org");
The easiest way to configure the --module
in for ts-node
is to create a tsconfig.json
with the following content:
{
"compilerOptions": {
"module": "nodenext"
},
"include": ["*.ts"]
}
Now after configuring the module, you can run ts-node
and it'll hopefully work well.
$ ts-node --esm ./index.ts
Here you can read more about ESM support in ts-node
: https://github.com/TypeStrong/ts-node/issues/1007
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.