I have seen this question a lot on GitHub and Stack Overflow, but using all of the answers that I found, none of them have worked. Everything seems to be set up correctly. I have a monorepo that has a packages/package-a
, packages/package-b
, etc. In the package-a
directory I have a Jest test command in the scripts "test": "jest"
. which I am running like this: npm run test -w packages/package-a
. When it starts up, I get the following error details:
Details:
node_modules/components/src/ui/label.js:2
import { jsx as _jsx } from "react/jsx-runtime";
SyntaxError: Cannot use import statement outside a module
> 1 | import { Label } from '@/ui/label';
| ^
2 |
3 | export function HelloWorld() {
4 | return (
The full component that this is looking at looks like this (src/hello-world.tsx
):
import { Label } from '@/ui/label';
export function HelloWorld() {
return (
<h1>
<Label>Hello World</Label>
</h1>
);
}
I then have a Jest test that looks like this (__tests__/hello-world.test.tsx
):
import { render } from '@testing-library/react';
import { HelloWorld } from '../src/hello-world';
describe('Renders the dashboard', () => {
it('Load Hello World Component', () => {
const { getByText } = render(<HelloWorld />);
expect(getByText('Hello World')).toBeInTheDocument();
});
});
I have two Jest configs, one in packages/project-a
that re-exports the base config found in the root. The base config looks like this (minus things that don't seem relevant to the problem):
import path from 'path';
const __dirname = new URL('.', import.meta.url).pathname;
export default {
moduleFileExtensions: ['tsx', 'ts', 'jsx', 'js', 'json', 'node'],
testMatch: ['<rootDir>/__test(s)?__/**/*.(spec|test).[jt]s?(x)'],
setupFilesAfterEnv: [path.join(__dirname, 'jest.setup.ts')],
rootDir: './',
testEnvironment: 'jsdom',
transform: {
'\\.[jt]sx?$': [
'babel-jest',
{
configFile: path.join(__dirname, 'babel.config.cjs'),
},
],
},
transformIgnorePatterns: [
'/node_modules/(?!next-auth|jose|@panva/hkdf|uuid|preact-render-to-string|preact)',
'^.+\\.module\\.(css|sass|scss)$',
],
};
In the same directory as the root, I have my base babel.config.cjs
, which sets up Babel. The configuration looks like this (I have tried both with and without the plugin):
module.exports = {
presets: [
// 'next/babel',
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
// plugins: [],
plugins: ['@babel/plugin-transform-modules-commonjs'],
};
Note: it is being used, as when I change a preset/plugin to something that doesn't exist, it throws an error saying it can't find the preset/plugin.
Why is it not transforming the import
to something that works with Jest?
I was finally able to get this to work by updating transformIgnorePatterns
in the Jest file, and updating my babel presets.
First, in the Jest file I removed this from the transformIgnorePatterns
:
'/node_modules/(?!next-auth|jose|@panva/hkdf|uuid|preact-render-to-string|preact)',
So now it looks like this:
export default {
transformIgnorePatterns: [
'^.+\\.module\\.(css|sass|scss)$',
]
}
Next, I updated my babel to look like this:
module.exports = {
presets: [
['@babel/preset-react', { runtime: 'automatic' }],
['@babel/preset-typescript', { isTSX: true, allExtensions: true }],
[
'@babel/preset-env',
{
targets: { node: 'current' },
modules: 'cjs',
},
],
],
plugins: [
'@babel/plugin-transform-modules-commonjs',
'@babel/plugin-transform-private-methods'
],
};
Now the tests run fine.