jefflau / jest-fetch-mock

Jest mock for fetch
MIT License
882 stars 116 forks source link

Import errors caused by node-fetch 2.6.0 (dependency of the cross-fetch dependency) #161

Open hbroer opened 4 years ago

hbroer commented 4 years ago

Hi,

i have some problems with jest-fetch-mock from the 3.0.x version range. It is not a problem with this package directly, it is caused by a dependency of a dependency of this package. When I update I get this Error:

    ...projectpath.../node_modules/node-fetch/lib/index.mjs:1
    import Stream from 'stream';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      4 | import {GlobalWithFetchMock} from "jest-fetch-mock";
      5 | const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock;
    > 6 | customGlobal.fetch = require("jest-fetch-mock");
        |                      ^
      7 | customGlobal.fetchMock = customGlobal.fetch;

If I downgrade jest-fetch-mock back to 2.1.2 then it works again. I am using this package together with typescript, jest, ts-jest, babel-jest. Another workaround can be found at the end of this Issue.

Environment

package.json (only unit test relevant dependencies)

  "devDependencies": {
    "@babel/core": "^7.9.6",
    "@babel/preset-env": "^7.9.6",
    "@types/enzyme": "^3.10.5",
    "@types/jest": "^25.2.1",
    "babel-jest": "^26.0.1",
    "babel-plugin-transform-react-jsx": "^6.24.1",
    "core-js": "^3.6.5",
    "enzyme": "^3.11.0",
    "enzyme-adapter-preact-pure": "^2.2.0",
    "enzyme-to-json": "^3.4.4",
    "jest": "^26.0.1",
    "jest-environment-jsdom-sixteen": "^1.0.3",
    "jest-fetch-mock": "^3.0.3",
    "jest-junit": "^10.0.0",
    "ts-jest": "^25.5.1-alpha.0",
    "typescript": "^3.8.3",
  },
  "browserslist": [
    "since 2018-11 and >0%",
    "node >= 12"
  ],

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,

    "rootDir": "src",
    "baseUrl": "src",
    "sourceMap": true,

    "experimentalDecorators": true,

    "strict": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,

    "removeComments": false,
    "noEmitHelpers": false,
    "declaration": false,

    "jsx": "react",
    "jsxFactory": "h",
    "resolveJsonModule": true
  },
  "include": [
    "src"
  ],
  "exclude": [
    "**/*.test.ts"
  ]
}

jest.config.js (part of it)

module.exports = {
    preset: "ts-jest",
    testEnvironment: "jest-environment-jsdom-sixteen",

    globals: {
        "ts-jest": {
            babelConfig: ".babelrc",
        },
    },

    moduleDirectories: ["src", "node_modules"],
    moduleFileExtensions: ["ts", "tsx", "mjs", "js"],
    moduleNameMapper: {
        "\\.(jpg|png|otf|svg|ttf|woff|woff2)$": "<rootDir>/test/jest-file-stub.js",
        "\\.(css)$": "identity-obj-proxy",
    },

    rootDir: "src",
    setupFiles: ["<rootDir>/test/jest-setup.js"],

    testMatch: ["**/**\\.test\\.ts", "**/**\\.test\\.tsx"],
    testPathIgnorePatterns: ["/node_modules/"],

    transform: {
        "^.+\\.ts$": "ts-jest",
        "^.+\\.tsx$": "ts-jest",
        "^.+\\.js$": "babel-jest",
    },
};

.babelrc

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "shippedProposals": true,
                "corejs": 3
            }
        ]
    ],
    "plugins": [
        ["transform-react-jsx", {"pragma": "h"}],
        "@babel/plugin-proposal-optional-chaining"
    ]
}

This version and its dependencies work:

package.json of node-fetch 2.1.2

{
  "main": "lib/index.js",
  "module": "lib/index.es.js",
}

This version fails:

package.json of node-fetch 2.6.0

{
  "main": "lib/index",
  "module": "lib/index.mjs",
}

This is the problem AFAIK. I had the same problem with a dependency of another dependency while compiling with Webpack if it has a module with the mjs extension.

The maintainers of node-fetch seems to found the problem or fixed it by accident in the @next version my setting module to a file with a js extension:

package.json of node-fetch @next

{
    "main": "./dist/index.js",
    "module": "./src/index.js",
}

Changing the dependency of cross-fetch to node-fetch@next then it works again. (aside of the Fact that it wants absolute urls so fetch("some-file.json") will not work. If that got fixed the tests run again)

Workaround

Removing the mjs extension from moduleFileExtensions in jest.config.js works. I found this while putting this report together... ^^

I will open this issue nevertheless because it might help someone find a solution for this or a similar problem. I needed a while... :D

privatenumber commented 2 years ago

If I'm understanding this correctly... If this is being caused by node-fetch/blob/v2.6.1/package.json#L5 not having a .js extension, I think this issue should be filed in node-fetch instead to report the accidental breaking change.

jimmywarting commented 2 years ago

2.6.2 now has extension in the main file