36

I'm trying to upgrade my api to use node-fetch 3.0.0. Part of the breaking changes in their documentation is that node-fetch is now a pure ESM module.

https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md

My unit tests have started breaking from this change. I was using jest.requireActual("node-fetch") for the Response object

const { Response } = jest.requireActual("node-fetch");

However, with the new change, I get:

"Property 'Response' does not exist on type '{}'."

I tried changing to an import statement which seems to fix that error:

import { Response } from "node-fetch"

Now, I get the following error when I run my unit tests:

Test suite failed to run
                                                                                                                                                                                                                                                                                                                                                                                         
    Jest encountered an unexpected token                                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                                                                                         
    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                                                         
    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".                                                                                                                                                                                                                                                                          

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\Users\{mypath}\api\node_modules\node-fetch\src\index.js:9
    import http from 'http';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      2 | import { AuthProvider, TokenCache } from "./tokenTypes";
      3 | import { getUserEmail, getUserId, getUserRole } from "../common/authUtil";
    > 4 | import fetch from "node-fetch";

The error seems to be occurring within node-fetch itself.

I tried changing the test script in my package.json to match what the jest documentation suggests for ESM modules. https://jestjs.io/docs/ecmascript-modules

package.json

"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"

The documentation also suggests changing the transform property in jest.config.js to take an empty object, but my transform object looks like the following for typescript and ts-jest:

jest.config.js

transform: { "^.+\\.ts?$": "ts-jest" }

If I change this to an empty object all of my tests break. I'm not very familiar with CJS vs ESM, so any help would be appreciated.

2 Answers 2

13

Fetch 3.0 is designed for using esmodules instead of commonjs. Therefore you have to make sure you import it into a module.

For example: to import it to app.js : Add "type":"module" in your package.json and then import it.

For importing it to other files or app.js even, you can also change the extension from .js to mjs that will tell nodejs to treat as a esmodule.

Otherwise downgrade fetch to use an older version that supports commonjs like 2.something.

npm install node-fetch@2
npm install @types/node-fetch@2
Sign up to request clarification or add additional context in comments.

4 Comments

I've added "type":"module" and changed my jest.config.js to be "export default" instead of module.export. I'm still getting the following errors. "import http from 'http'; ^^^^^^` SyntaxError: Cannot use import statement outside a module 1 | import { jest } from "@jest/globals"; > 2 | import { Response } from "node-fetch";" Same with 4 | import fetch from "node-fetch";
This is not a solution to the problem
downgrading to @2 worked for me and was ok because I only need it during tests
I added "type":"module" but it still does not work. :(
4

I had the same problem! adding

 transform: {
    "^.+\\.(ts|tsx)$": "ts-jest",
    "^.+\\.(js)$": "babel-jest",
  },
  transformIgnorePatterns: [
  ],

to my jest.config.js file solved it. and btw these are my versions:

    "jest": "^27.3.1",
    "ts-jest": "^27.0.7",
    "node-fetch": "^3.1.0"

4 Comments

Using the same transform option for ts-jest and still encountering the error.
It solved my case
adding the empty array for transformIgnorePatterns fixed it for me
This solution may not be practical as an empty array for transformIgnorePatterns means it will transform all your node_modules

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.