Reputation: 2158
I have spent a long time looking at other questions about this and looking at other projects on Github but none of the answers seem to work for me.
I am loading a third party library in my project, and when running Jest tests I get the error
export default portalCommunication;
^^^^^^
SyntaxError: Unexpected token export
> 1 | import portalCommunication from 'mathletics-portal-communication-service';
I have tried updating my Jest config in many ways to get it to transpile this library but I always get the same error.
This is my current jest.config.js file:
module.exports = {
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy',
'\\.svg$': '<rootDir>/test/mocks/svg-mock.js'
},
setupFiles: ['./test/test-setup.js'],
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!mathletics-portal-communication-service)'
]
};
I have also tried adding the transform property to run babel-jest against this mathletics-portal-communication-service directory.
Please help!
Upvotes: 48
Views: 50645
Reputation: 1010
This is what I found after reading your answers from here and the link provided by @NJCodeMonkey
The error I was getting was this one:
Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• 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/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/Users/fgabriel/nx-5/node_modules/flat/index.js:12
export function flatten (target, opts) {
^^^^^^
SyntaxError: Unexpected token 'export'
2 | import { RouterModule } from '@angular/router';
3 | import { NxWelcomeComponent } from './nx-welcome.component';
> 4 | import { flatten } from 'flat'
| ^
5 |
6 | @Component({
7 | imports: [NxWelcomeComponent, RouterModule],
at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1505:14)
at Object.<anonymous> (src/app/app.component.ts:4:1)
at Object.<anonymous> (src/app/app.component.spec.ts:2:1)
Now, first of all I would like to say that this started happening when I migrated to Nx latest version, to the moment when I'm writing this comment: 20.4.0
My previous setup was working and it stop working when upgrading Nx (this is just for context)
So I cloned the jest repo and looked into how they handle the transformIgnorePatterns:
return new RegExp(config.transformIgnorePatterns.join('|'));
For anyone wanting to check if the regex added in transformIgnorePatterns is correct, you can use the above code
This helped me to understand that the Regex was not the issue, so something had to be failing when the the transformer (alias transpiler) was trying to transpile this flat/index.js to be used in my tests
So, I took the babel path this time and the following configuration worked:
Files:
nx-workspace/apps/nx-5/babel.config.js
nx-workspace/apps/nx-5/jest.config.ts
Here is my babel.config.js:
module.exports = {
"presets": [
"@babel/preset-env"
]
};
and my jest.config.ts from a recently created Nx workspace for reproduction:
const config = {
displayName: 'nx-5',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../coverage/apps/nx-5',
transform: {
'^.+\\.js$': 'babel-jest', <---------
'^.+\\.(ts|html|mjs)$': [
'jest-preset-angular', <---------
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
// '^.+\\.(ts|mjs|js|html)$': [
},
transformIgnorePatterns: [
'node_modules/(?!(.*\\.mjs$)|(flat/index\\.js$))', <----
],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};
export default config;
It was very helpful to me to create a new Nx workspace to work on something smaller where I could reproduce and fix it
Upvotes: 0
Reputation: 356
It's worth noting if you're using Next.js that you might be affected by this issue. next/jest.js
makes it hard to transpile modules in node_modules, but you can modify the baked config in jest.config.mjs
like this:
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
dir: './',
})
// add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
...
// setting `transformIgnorePatterns` in here does not work
}
// work around https://github.com/vercel/next.js/issues/35634
async function hackJestConfig() {
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
const nextJestConfig = await createJestConfig(config)();
// /node_modules/ is the first pattern, so overwrite it with the correct version
nextJestConfig.transformIgnorePatterns[0] = '/node_modules/(?!(micromark-extension-gfm))/';
return nextJestConfig;
}
export default hackJestConfig
Upvotes: 2
Reputation: 921
The transformIgnorePatterns
didn't work for me until I changed my .babelrc
to babel.config.js
, like this:
module.exports = {
"presets": [
"@babel/preset-env"
]
};
as seen on this comment: https://github.com/facebook/jest/issues/6229#issuecomment-403539460
Upvotes: 65
Reputation: 711
Another team at my org added some common module. This was not transpiled and so the issue.
I followed this: https://babeljs.io/docs/en/configuration#whats-your-use-case
.babelrc
to babel.config.json
transformIgnorePatterns: ['/node_modules/(?!(@companyName)/).*/'],
This solved my problem.
Upvotes: 13
Reputation: 3790
Adding trailing slash fix this for me:
{
// ...
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!mathletics-portal-communication-service/)'
]
};
Upvotes: 6
Reputation: 2343
It might be your use of rootDir
. Try:
"transformIgnorePatterns": [
"node_modules/(?!(mathletics-portal-communication-service))"
]
Upvotes: -4
Reputation: 2158
As a workaround for now I have changed my config to use the moduleNameMapper
option to load a mock class for that library instead. I would have preferred to use transformIgnorePatterns
instead so would still appreciate any ideas.
New config:
module.exports = {
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy',
'\\.svg$': '<rootDir>/test/mocks/svg-mock.js',
'mathletics-portal-communication-service': '<rootDir>/test/mocks/mathletics-portal-communication-service-mock.js'
},
setupFiles: ['./test/test-setup.js']
};
Upvotes: 6