Hi. I think https://github.com/kulshekhar/ts-jest/pull/724 (v23.10.0) introduced a regression: Running a test of ours fails with a message like this:
ts-jest[jest-transformer] (WARN) Got a unknown file type to compile (file: /home/xxx/yyy/node_modules/lodash-es/_matchesStrictComparable.js). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore.
ts-jest doesn't seem to typescript-compile .js files at all any more.
ts-jest passes .js files through typescript compilation, tests finish without error. (The version we were using before (22.4.4) didn't have the issue.)
IMO the problem is here: https://github.com/kulshekhar/ts-jest/commit/6c32a93fd790646bd74d471352fff403f210c190#diff-969086a2836a7b1045fc24603a3b6cbeR114
Line 114 should actually read
} else if (isTsFile || isJsFile) {
Right now we always run in the else case, even though the condition in line 110 and the comment in line 118 makes me expect that we take the tsCompiler.compile for .js files as well.
Please let me know if you need more info.
Thanks @mkreidenweis this definitely is a bug which IMO get fixed by adding your ||
I'll fix this and include it in next release!
Could you also try if it reads allowJs from tsconfig.json?
I've checked the log via TS_JEST_LOG and it's always false. The config is not honored somehow.
@alvis I'm actually working on this right now, will check and add a test if not. But it should be, so check that you correctly specified the tsConfig option of ts-jest (if it's not the default one)
Update: when using the log file, use --runInBand jest option
@alvis I think your config is wrong somewhere because I've added a E2E test related to this and all is good. Anyway, thanks as now there is a E2E test for that :D
@huafu The reason of my problem is that I use the config in package.json, not jest.config.
With the latest v23.10.1, it works again, but only if I put
"transform": {
"^.+\\.(j|t)sx?$": "ts-jest"
}
into the jest config in my package.json.
I checked with the log, and I find that without the additional transform setting, the resulting jest config would be just
"transform": [
[
"^.+\\.tsx?$",
"<path to my project>/node_modules/ts-jest/dist/index.js"
]
]
The reason for that is the result of create-jest-preset which relies on the allowJs agrument. i.e.
https://github.com/kulshekhar/ts-jest/blob/e2f699cbb13b01d64d8d9b7d192596fc592e296e/src/config/create-jest-preset.ts#L15-L23
However, it's always false as the default because there is no agrument specified in jest-preset.js, i.e.
https://github.com/kulshekhar/ts-jest/blob/e2f699cbb13b01d64d8d9b7d192596fc592e296e/jest-preset.js#L4
Yeah, because by default we leverage js compilation to jest which knows how to handle it. The default preset is for ts-jest to handle typescript files. We cannot make a dynamic preset unless you call the function yourself.
@huafu: Can we look for tsconfig.json and get the allowJs variable in ts-jest/jest-preset.js?
or at least some way to specify it, e.g. in the global object in the jest config in package.json?
Long story short: no
A preset is static. The only way to use the preset with allowJs: true in package.json is to override whatever doesn't match in jest config. Since ts-jest is for typescript, the default is the most common for typescript only projects.
When loading a preset, Jest will require(presetName + '/jest-preset.js') without giving any other info, so there is no way at this point to know from which project it's coming from neither what is in jest config at all.
@alvis that's why it's recommended to use jest.config.js, so that it can be more dynamic than the jest key in package.json. See https://kulshekhar.github.io/ts-jest/user/config/ for more info ;-)
@huafu I think by default we should honor what's stated in tsconfig.json, instead of creating another jest.config.js for the sake of supporting allowJs (an issue of double entrie as we have to state the setting on both tsconfig and jest.config).
In fact, I am wondering if the statements below already controls whether a JS file is allowed to be transpiled or not.
https://github.com/kulshekhar/ts-jest/blob/25e1c63dd3797793b0f46fa52fdee580b46f66ae/src/compiler.ts#L74-L76
I've checked that compilerOptions in fact is the compilerOptions in my tsconfig.json. So it knows the config.
If so, we don't even need to evaluate allowJs in https://github.com/kulshekhar/ts-jest/blob/e2f699cbb13b01d64d8d9b7d192596fc592e296e/src/config/create-jest-preset.ts#L23
and therefore probably we can even take away allowJs in the preset setting altogether. We may simply use the universl match '^.+\\.[tj]sx?$' and control the transpilation flow in compiler.ts
@alvis it's not as easy, when jest loads the preset, NOTHING from ts-jest is loaded yet, just it loads the preset.
Then jest calls getCacheKey(), and there it's too late to change jest config.
It could be possible if jest was calling some kind of transformer.init(jesOptions), but there is no such call badly.
If you want to discuss this more I'm on slack. Also you could look at some quick diagrams I've made which explains how jest works with transformers: https://kulshekhar.github.io/ts-jest/tech/process/
@alvis I found a way of providing multiple preset, will provide a PR later. In your particular case you'll set "preset": "ts-jest/presets/js-with-ts".
There will be 3 presets:
ts-jest/presets/default which the currently existing preset ts-jest will be an alias ofts-jest/presets/js-with-ts which will compile js files with ts-jestts-jest/presets/js-with-babel which will compile js files with babel-jestOoo! Amazing! Very glad we have a way to get around the issue without creating an extra jest.config.
Thanks so much @huafu
@alvis for now you don't have to create a jest.config.js in your case anyway, simply add the transform in package.json jest option as you mentioned first.
Most helpful comment
@alvis I found a way of providing multiple preset, will provide a PR later. In your particular case you'll set
"preset": "ts-jest/presets/js-with-ts".There will be 3 presets:
ts-jest/presets/defaultwhich the currently existing presetts-jestwill be an alias ofts-jest/presets/js-with-tswhich will compile js files with ts-jestts-jest/presets/js-with-babelwhich will compile js files with babel-jest