Closed luchsamapparat closed 5 years ago
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-jest
Some vendors publish their sources without transpiling. You need to say jest to transpile such files manually since
typescript
(and thusts-jest
used by this preset) do not transpile them.
- Install
babel-preset-env
and 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 allowJs
as 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 jest-preset-angular@8.0.0
@llwt Where can I find the
jest-preset-angular/preprocessor.js
? It's not available in jest-preset-angular@8.0.0
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-jest
and tell it to transpile those js files.From the jest-preset-angular docs:
Transpile js files through
babel-jest
Some vendors publish their sources without transpiling. You need to say jest to transpile such files manually since
typescript
(and thusts-jest
used by this preset) do not transpile them.
- Install
babel-preset-env
and 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})`], // ... };
Keywords: monorepo jest typescript create-react-app
Works: cd packages/somePackage && yarn jest --no-cache --coverage
Fails: yarn jest --no-cache --coverage packages/somePackage
Error:
Details:
/Users/…/development/work/monorepo-root/node_modules/babel-preset-react-app/node_modules/@babel/runtime/helpers/esm/slicedToArray.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import arrayWithHoles from "@babel/runtime/helpers/esm/arrayWithHoles";
^^^^^^
SyntaxError: Cannot use import statement outside a module
Workaround: in: jest.config.js
transformIgnorePatterns: [
`[/\\\\]node_modules[/\\\\](?!${[
'babel-preset-react-app',
'@babel',
].join('|')})`,
],
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
Actually this one is better
'^lodash-es/(.*)$': '<rootDir>/node_modules/lodash/$1',
Because mapping to lodash
will resolve in LodashWrapper object instead of the function itself
for next release of nx(11.5.2) you can do this to fix the issue. Install babel-jest and @babel/preset-env
create babel.config,js in the root of the workspace and add this module.exports = { presets: ['@babel/preset-env'] };
then in your jest,config.js add this
transformIgnorePatterns: [/node_modules/?!lodash-es
],
transform: {
'^.+\.(ts|html)$': 'ts-jest',
'^.+\.js$': 'babel-jest'
}
I was not able to get this solution to work.
'^lodash-es/(.*)$': '<rootDir>/node_modules/lodash/$1',
Instead I wrote it like this and it worked:
moduleNameMapper: {
'^lodash-es/(.*)$': 'lodash/$1',
},
For anyone that is still running into this issue in the context of a monorepo (yarn workspace in my case), make sure that you are not hoisting the package that needs to be transpiled.
The solution that worked for me:
babel.config.js
in the package root (not the workspace root):
module.exports = {
presets: [['@babel/preset-env']],
}
Jest config:
const esModules = ['ipld-hashmap'].join('|') // can add other packages here
module.exports = {
...
transform: {
'^.+\\.ts$': 'ts-jest',
"^.+\\.js?$": "babel-jest"
},
transformIgnorePatterns: [`<rootDir>/node_modules/(?!${esModules})`],
...
}
Root package.json
"workspaces": {
"packages": ["packages/*"],
"nohoist": ["**/ipld-hashmap", "**/ipld-hashmap/**"]
}
Any one of those four things (nohoist, transform, transformIgnorePatterns, and babel config) missing & it won't work.
I had this issue with Swiper and was able to get it to work by using the following in the app's jest.config.js
file:
transformIgnorePatterns: ['node_modules/(?!(.*\\.mjs$|swiper|ssr-window|dom7))'],
modulePaths: ['<rootDir>/../../node_modules/swiper/angular/'],
Swiper depends on ssr-window
and dom7
which is why I had to add these modules to the transformIgnorePatterns
as well.
Note that modulePaths
need to be absolute, therefore the usage of <rootDir>
.
I had this issue with react-merge-refs while using @swc/jest
and setting transformIgnorePatterns wasn't helping.
The problem? If you're setting this up for an error coming from a .mjs
file, you probably need to change your pattern under transform
in your jest config, since its recommended pattern does not match .mjs
files. Depending on what you have in your options on your @swc/jest
transformer entry, it might make sense to add a new transformer entry, like this:
transform: {
...
"node_modules\\/.+\\.(js)|(mjs)$": "@swc/jest",
...
}
This is in addition to the transformIgnorePatterns.
In case it helps anyone - in my case, using a monorepo with babel-jest
, I needed to add:
transform: {
'\\.[tj]sx?$': ['babel-jest', { rootMode: 'upward' }]``
}
without the rootMode
option, babel-jest was giving syntax errors when importing other libraries in the monorepo.
asztal solution works for me with Nx 15.x, Angular 15.x and Jest 28.x
This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.
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 settransformIgnorePatterns
to inlude the path tolodash-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:
Thanks for your help