jest: [Bug]: Jest ESM (ts-jest) can't find import from CJS module
Version
27.4.3
Steps to reproduce
Minimal repro: https://github.com/themaskedavenger/jest-esm-apollo-client
run yarn
and then yarn test:jest
also to see the original issue replace the imports (lines 4-10) with:
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
useQuery,
gql
} from '@apollo/client';
Expected behavior
Would expect to have Jest be able to properly import those components and see the tests run (and hopefully pass!).
Actual behavior
When using these imports:
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
useQuery,
gql
} from '@apollo/client';
Each of the imports gives an error like SyntaxError: The requested module '@apollo/client' does not provide an export named 'ApolloProvider'
. Looking at the @apollo/client
’s package.json, the "main"
key is set to "./main.cjs"
, which is re-exporting things in cjs style:
var core = require('./core');
var react = require('./react');
for (var k in core) {
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = core[k];
}
for (var k in react) {
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = react[k];
}
For some reason I guess this cjs is not recognized with the recommended jest config. To get around it, can directly import the specific exports directly from esm files in the @apollo/client
package like this:
import {
ApolloClient,
InMemoryCache,
} from '@apollo/client/core';
import { ApolloProvider } from '@apollo/client/react/context/ApolloProvider';
import { useQuery } from '@apollo/client/react/hooks';
import { gql } from 'graphql-tag';
Then there’s a new error for a dependency:
/path/to/project/node_modules/ts-invariant/process/index.js:15
export function install() {
^^^^^^
SyntaxError: Unexpected token 'export'
Adding transformIgnorePatterns
to jest config doesn’t seem to help:
"transformIgnorePatterns": [
"node_modules/(?!(ts-invariant)/)"
],
Any thoughts on how to fix?
Full jest config:
"jest": {
"resetMocks": true,
"testEnvironment": "node",
"testMatch": [
"**/src/**/*.(spec|test).[tj]s?(x)"
],
"preset": "ts-jest/presets/default-esm",
"transform": {},
"transformIgnorePatterns": [
"node_modules/(?!(ts-invariant)/)"
],
"extensionsToTreatAsEsm": [
".ts",
".tsx"
],
"globals": {
"ts-jest": {
"useESM": true
}
},
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.js$": "$1"
}
}
and tsconfig:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"downlevelIteration": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"jsx": "react",
"outDir": "build",
"sourceMap": true,
"strictNullChecks": true,
"baseUrl": ".",
"lib": [
"ESNext",
"dom"
],
"moduleResolution": "Node",
"target": "ESNext",
"module": "ESNext"
},
"include": [
"src/**/*"
]
}
Additional context
Also tried using this jest resolver suggested in the docs:
module.exports = (request, options) => {
// Call the defaultResolver, so we leverage its cache, error handling, etc.
return options.defaultResolver(request, {
...options,
// Use packageFilter to process parsed `package.json` before the resolution (see https://www.npmjs.com/package/resolve#resolveid-opts-cb)
packageFilter: (pkg) => {
return {
...pkg,
// Alter the value of `main` before resolving the package
main: pkg.module || pkg.main,
};
},
});
};
I notice that the @apollo/client
package has both "module"
and "main"
keys. But using this resolver it errors for other modules:
/Users/justin/dev/sandbox/jest-esm-apollo-client/node_modules/@testing-library/react/dist/@testing-library/react.esm.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import _extends from '@babel/runtime/helpers/esm/extends';
^^^^^^
SyntaxError: Cannot use import statement outside a module
Is it possible to utilize the esm "module"
field in package.json with jest ESM? Seemed like the obvious choice for ESM jest but it creates all kinds of errors like this. Is it because cjs modules in node_modules are trying to load the ESM exports?
Environment
npx: installed 1 in 1.509s
System:
OS: macOS 11.6
CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
Binaries:
Node: 14.17.6 - /usr/local/bin/node
Yarn: 1.22.0 - /usr/local/bin/yarn
npm: 6.14.15 - /usr/local/bin/npm
npmPackages:
jest: ^27.4.3 => 27.4.3
npx envinfo@latest --preset apollo --clipboard
npx: installed 1 in 1.563s
System:
OS: macOS 11.6
Binaries:
Node: 14.17.6 - /usr/local/bin/node
Yarn: 1.22.0 - /usr/local/bin/yarn
npm: 6.14.15 - /usr/local/bin/npm
Browsers:
Chrome: 96.0.4664.55
Edge: 80.0.361.54
Firefox: 89.0.2
Safari: 14.1.2
npmPackages:
@apollo/client: ^3.5.5 => 3.5.5
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 22
- Comments: 15 (4 by maintainers)
I’m having a similar issue, I think it fits in here.
My problem is that, even though the packages from
node_modules
being imported have both CJS and ESM modules, and that in “my” (well, my company’s)package.json
andtsconfig.files
we have it to work with CJS… When Jest runs, it tries to load the ESM variants instead, and then it complains about theexport
keyword because it does not understand it.Of course I could try to apply some of the transformations referred in this thread, but what confuses me is why is it even trying to load the ESM files when we have CJS ones available (and they are properly declared in the respective
package.json
files of the packages we have innode_modules
, via the"exports"
section).I’m also experiencing this issue, did you create an issue or managed to resolve it?
@NiklasPor I didn’t had time to prepare a minimum reproducible example for this problem and to write a detailed issue yet. Will do.
Better open new issue with minimal reproduction. It is impossible to guess what is going on from your description.
Hi, I had the same issue, spent a lot time on it but eventually fixed by changing jest config like described here https://github.com/facebook/jest/issues/11783#issuecomment-1107861603