th3g3ntl3man
th3g3ntl3man

Reputation: 2106

Can't import node-fetch into Typescript

I'm trying to import node-fetch into my Typescript project but I fall into this error:

[ERR_REQUIRE_ESM]: Must use import to load ES Module : /Users/xxx/xxx/xxx/xxx/xxx/xxx/xxx/node_modules/node-fetch/src/index.js require() of ES module is not supportes.

This is my setup:

  1. node: v16.1.0
  2. typescript: 4.5.2

The node-fetch package is imported in my project as followed: import fetch from 'node-fetch';'

This is my tscongif.json:

{
  "compilerOptions": {
    "module": "CommonJS",
    "sModuleInterop": true,
    "target": "ES2020",
    "allowJs": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "outDir": "dist",
    "baseUrl": ".",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true,
    "typeRoots": [ 
      "src/@types/",
      "node_modules/@types",
    ],
    "strict": true,
    "strictNullChecks": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "noEmit": true,
    "skipLibCheck": true,
  },
  "include": [
    "src/**/*",
    "config/**/*"
  ]
}

I tried alse to add "type": "module" into the package.json and set "module": "ES2020" into the tsconfig.json but I got a new error:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"

To run my code I use nodemon configured as follow:

{
  "watch": ["src"],
  "ext": "ts, js, json",
  "execMap": {
    "ts": "NODE_ENV=development ts-node -T"
  }
}

Upvotes: 15

Views: 18384

Answers (2)

jsejcksn
jsejcksn

Reputation: 33739

The issue you are experiencing is not a problem in your application code, but is caused by project misconfiguration. ESM support in ts-node is currently experimental. See this GitHub issue to understand the current situation:

https://github.com/TypeStrong/ts-node/issues/1007

According to the data in the repo link you shared in your comment, along with the information in the above issue and the documentation notes here, the following changes will allow you to run your app using the npm start:dev script in the reproduction repo.


./package.json:

Add the following entry to the top-level of the object (this will tell Node that your transpiled *.js files are ES modules and to run them in that mode):

{
  "type": "module"
}

./tsconfig.json:

Modify the value of compilerOptions.module to "esnext" (this will tell TypeScript to emit modules in ESM format instead of CJS):

{
  "compilerOptions": {
    "module": "esnext"
  }
}

./nodemon.json:

Modify the value of execMap.ts to the following (configuring the NODE_OPTIONS environment variable this way enables native ESM support in ts-node):

{
  "execMap": {
    "ts": "NODE_ENV=development NODE_OPTIONS='--loader ts-node/esm' ts-node -T"
  }
}

Console output:

$ npm run start:dev

> [email protected] start:dev
> NODE_ENV=development nodemon ./src/index.ts

[nodemon] 2.0.15
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/*
[nodemon] watching extensions: ts,js,json
[nodemon] starting `NODE_ENV=development NODE_OPTIONS='--loader ts-node/esm' ts-node -T ./src/index.ts`
(node:3273) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
START
[nodemon] clean exit - waiting for changes before restart

Upvotes: 7

Flash Noob
Flash Noob

Reputation: 500

node-fetch from v3 is an ESM-only module - you are not able to import it with require(), according to doc.

did u tried using this:

import * as fetch from 'node-fetch';

Upvotes: -6

Related Questions