First of all, thanks for bringing Jest to Angular!
I previously had configured Jest in my Angular project by myself. In order to use lodash-es, I had to set transformIgnorePatterns to inlude the path to lodash-es:
"jest": {
"preset": "jest-preset-angular",
...
"transformIgnorePatterns": [
"<rootDir>/node_modules/(?!lodash-es/.*)"
],
Now, after migrating to the Jest config provided by Nx, I don't know where I can set this option. My tests currently fail with this error:
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:
• 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\Marvin\Projekte\hypershop-ng\node_modules\lodash-es\lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
1 | import { ComponentFixture } from "@angular/core/testing";
> 2 | import { isUndefined } from "lodash-es";
| ^
3 |
4 | export function expectElementFromFixture<T>(fixture: ComponentFixture<T>, domQuery?: string): jasmine.Matchers<{} | null> {
5 | return expect(elementFromFixture(fixture, domQuery));
at ScriptTransformer._transformAndBuildScript (../../node_modules/jest-runtime/build/script_transformer.js:403:17)
at Object.<anonymous> (../../libs/common/src/test/expect.ts:2:1)
at Object.<anonymous> (../../libs/common/src/test/index.ts:1:1)
Thanks for your help
Nevermind, obviously it's ./jest.config.json … 🙄
However, the problem is still there even when adding that config 🤔
I had to remove the <rootDir> from ours:
const esModules = ['@agm', 'ngx-bootstrap'].join('|');
// ...
module.exports = {
//...
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
// ...
};
Yes, that confirms what I just discovered while debugging Jest. The <rootDir> is resolved to the lib/app directory being tested, not the workspace root...
`/absolute/path/to/project/libs/libname/node_modules//(?!lodash-es/.*)
I've been debugging this for the last hour. lodash-es is definitely being passed to transformSource in jest-runtime/build/script_transformer.js, however the transformedSource that is returned by that function still contains non-ES5 statements.
I finally fixed the issue by adding "allowJs": true to the compilerOptions of each lib/app's tsconfig.spec.json (or alternatively to the root tsconfig.json). Of course in addition to setting transformIgnorePatterns as @llwt suggested. Without that option the TypeScript compiler just skipped the lodash files.
One other option is to pull in babel-jest and tell it to transpile those js files.
From the jest-preset-angular docs:
Transpile js files through
babel-jestSome vendors publish their sources without transpiling. You need to say jest to transpile such files manually since
typescript(and thusts-jestused by this preset) do not transpile them.
- Install
babel-preset-envand add.babelrc(or modify existing if needed) with that contents:{ "presets": ["env"] }
- Update Jest configuration (by default TypeScript process untranspiled JS files which is source of the problem):
{ "jest": { "transform": { "^.+\\.(ts|html)$": "<rootDir>/node_modules/jest-preset-angular/preprocessor.js", "^.+\\.js$": "babel-jest" }, } }
We took that and tweaked it to only pass the js files needed through:
const esModules = ['@agm', 'ngx-bootstrap', 'lodash-es'].join('|');
module.exports = {
// ...
transform: {
[`(${esModules}).+\\.js$`]: 'babel-jest',
'^.+\\.(ts|js|html)$': 'jest-preset-angular/preprocessor.js',
// ...
},
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
// ...
};
I have the similar problem when trying to debug jest tests in VS Code:
FAIL apps/el/admin/src/app/app.component.spec.ts
● 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:
• 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:
<project_path>\apps\el\admin\src\app\app.component.html:2
<div style="text-align:center">
^
SyntaxError: Unexpected token <
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at apps/el/admin/src/app/app.component.ts:26:15
at Object.<anonymous> (apps/el/admin/src/app/app.component.ts:30:2)
It is a nrwl workspace with one app and one lib, no code changes.
Debugger works, the breakpoint is hit. But got the error from above.
npm run test works - all tests are green.
{
"type": "node",
"request": "launch",
"name": "Jest All",
"program": "${workspaceFolder}\\node_modules\\jest\\bin\\jest",
"args": ["--runInBand", "--config=${workspaceFolder}\\jest.config.js"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
Any idea what might be wrong? Thank you.
@skorunka have a look at https://github.com/nrwl/nx/blob/master/packages/builders/src/jest/jest.builder.ts
When you run your tests via npm run test, the globals config is set by Nx' Jest builder. You need to somehow also provide these globals in order to debug your tests with VS Code. I added that config to temporarily to my Jest config while debugging, but that's certainly not the nicest option...
@luchsamapparat Hi, could you please share your modified jest config file you use for debugging? Thanks.
I have added __TRANSFORM_HTML__: true to globals in ./jest.config.js file, like
globals: {
'ts-jest': {
tsConfigFile: './tsconfig.json',
},
__TRANSFORM_HTML__: true,
},
and now there is no problem with HTML. But the easy test for checking that the components can be created fails. It works from command line.
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginInlineComponent } from './login-inline.component';
describe('FooterComponent', () => {
let component: LoginInlineComponent;
let fixture: ComponentFixture<LoginInlineComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, ReactiveFormsModule],
declarations: [LoginInlineComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginInlineComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
The breakpoint is hit, but the component is undefined

Command line works es expected:

Any idea what I'm still missing in here? This drives me crazy. I love jest, but making it work/debug in Angular + VS Code is painful.
After some debugging, I can actually see that there is an exception when executing:
fixture = TestBed.createComponent(LoginInlineComponent);
It goes in queue_runner.js:

Solved this without allowJs, the only 1 file which changed it was jest.config.js (local lib file, not in global jest.config.js) by adding transformIgnorePatterns lijke below
module.exports = {
name: 'contact',
preset: '../../jest.config.js',
coverageDirectory: '../../coverage/libs/contact',
transformIgnorePatterns: ['../../node_modules/(?!${ng2-tel-input})']
};
Where ng2-tel-input was the problematic module, getting it for the following environment: Jest 23.6.0, @nrwl/builders 7.5.1, @nrwl/nx 7.5.1, @nrwl/schematics 7.5.1. jest-preset-angular 6.0.1.
Solved this without
allowJs, the only 1 file which changed it was jest.config.js (local lib file, not in global jest.config.js) by adding transformIgnorePatterns lijke belowmodule.exports = { name: 'contact', preset: '../../jest.config.js', coverageDirectory: '../../coverage/libs/contact', transformIgnorePatterns: ['../../node_modules/(?!${ng2-tel-input})'] };Where ng2-tel-input was the problematic module, getting it for the following environment: Jest 23.6.0, @nrwl/builders 7.5.1, @nrwl/nx 7.5.1, @nrwl/schematics 7.5.1. jest-preset-angular 6.0.1.
Update: apologizes for the mistake, you have to include allowJsas well. The reason why I got it working is I didn't clean cache. Before testing remember to do so.
@llwt Where can I find the jest-preset-angular/preprocessor.js? It's not available in [email protected]
@llwt Where can I find the
jest-preset-angular/preprocessor.js? It's not available in [email protected]
8.0.0 no longer has preprocessor.js in source . It is now delegated fully to ts-jest. Jest-preset-angular only applies custom ast transformers to ts-jest to alter the compiled output.
Still same issue with anagular, jest-babel does not work and I actually do not want to meess both of them just because of this lodash-es stuff...
wtf
the only thing that worked for me was to add this to the main jest.config.js
moduleNameMapper: {
"^lodash-es$": "lodash"
}
make sure you have lodash in you devDependencies
Solved this without
allowJs, the only 1 file which changed it was jest.config.js (local lib file, not in global jest.config.js) by adding transformIgnorePatterns lijke belowmodule.exports = { name: 'contact', preset: '../../jest.config.js', coverageDirectory: '../../coverage/libs/contact', transformIgnorePatterns: ['../../node_modules/(?!${ng2-tel-input})'] };Where ng2-tel-input was the problematic module, getting it for the following environment: Jest 23.6.0, @nrwl/builders 7.5.1, @nrwl/nx 7.5.1, @nrwl/schematics 7.5.1. jest-preset-angular 6.0.1.
Hi @danieldanielecki thank you so much for your answer. I'm wondering how did you find out which module was the problematic module? Thanks~
Solved this without
allowJs, the only 1 file which changed it was jest.config.js (local lib file, not in global jest.config.js) by adding transformIgnorePatterns lijke belowmodule.exports = { name: 'contact', preset: '../../jest.config.js', coverageDirectory: '../../coverage/libs/contact', transformIgnorePatterns: ['../../node_modules/(?!${ng2-tel-input})'] };Where ng2-tel-input was the problematic module, getting it for the following environment: Jest 23.6.0, @nrwl/builders 7.5.1, @nrwl/nx 7.5.1, @nrwl/schematics 7.5.1. jest-preset-angular 6.0.1.
Hi @danieldanielecki thank you so much for your answer. I'm wondering how did you find out which module was the problematic module? Thanks~
Sorry, but don't remember now... For sure it was one of those which caused errors on Server-Side Rendering (SSR)/Angular Universal.
I had to remove the
<rootDir>from ours:const esModules = ['@agm', 'ngx-bootstrap'].join('|'); // ... module.exports = { //... transformIgnorePatterns: [`/node_modules/(?!${esModules})`], // ... };
I am using deepdash in place of loadash added below in jest.preset.js
transform: {
'^.+\.(ts|js|html)$': 'babel-jest',
},
transformIgnorePatterns: [
"/node_modules/(?!deepdash-es/.*)"
],
and created a new file babel.config.json and added
{
"presets": ["@babel/preset-env"]
}
and inside individual lib jest.config.js added
transformIgnorePatterns: ['../../node_modules/(?!${deepdash-es})'],
transform: {
"^.+\.jsx?$": "babel-jest"
},
moduleNameMapper: {
"^deepdash-es$": "deepdash"
},
in tsconfig.spec.json added "allowJs": true,
nothing is working, still the issue persists, could you please help on this.
This is what worked for me. We were having issues consuming imask and countup.js libs and used the configs mentioned here: https://github.com/thymikee/jest-preset-angular#transpile-js-files-through-babel-jest
Thanks @llwt 🙂
One other option is to pull in
babel-jestand tell it to transpile those js files.From the jest-preset-angular docs:
Transpile js files through
babel-jestSome vendors publish their sources without transpiling. You need to say jest to transpile such files manually since
typescript(and thusts-jestused by this preset) do not transpile them.
- Install
babel-preset-envand add.babelrc(or modify existing if needed) with that contents:{ "presets": ["env"] }
- Update Jest configuration (by default TypeScript process untranspiled JS files which is source of the problem):
{ "jest": { "transform": { "^.+\\.(ts|html)$": "<rootDir>/node_modules/jest-preset-angular/preprocessor.js", "^.+\\.js$": "babel-jest" }, } }We took that and tweaked it to only pass the js files needed through:
const esModules = ['@agm', 'ngx-bootstrap', 'lodash-es'].join('|'); module.exports = { // ... transform: { [`(${esModules}).+\\.js$`]: 'babel-jest', '^.+\\.(ts|js|html)$': 'jest-preset-angular/preprocessor.js', // ... }, transformIgnorePatterns: [`/node_modules/(?!${esModules})`], // ... };
Most helpful comment
One other option is to pull in
babel-jestand tell it to transpile those js files.From the jest-preset-angular docs:
We took that and tweaked it to only pass the js files needed through: