Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: no typescript transformation/compilation possible for JavaScript files any more #740

Closed
mkreidenweis opened this issue Sep 20, 2018 · 14 comments · Fixed by #742
Labels
Milestone

Comments

@mkreidenweis
Copy link

Issue :

Hi. I think #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.

Expected behavior :

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.)

Suggested fix:

IMO the problem is here: 6c32a93#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.

@huafu huafu added this to the v23.10.1 milestone Sep 20, 2018
@huafu huafu added the 🐛 Bug label Sep 20, 2018
@huafu
Copy link
Collaborator

huafu commented Sep 20, 2018

Thanks @mkreidenweis this definitely is a bug which IMO get fixed by adding your ||
I'll fix this and include it in next release!

@huafu huafu assigned huafu and unassigned huafu Sep 20, 2018
@alvis
Copy link

alvis commented Sep 20, 2018

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.

@huafu
Copy link
Collaborator

huafu commented Sep 20, 2018

@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

@huafu
Copy link
Collaborator

huafu commented Sep 20, 2018

@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

@alvis
Copy link

alvis commented Sep 21, 2018

@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.

export function createJestPreset(
{ allowJs = false }: CreateJestPresetOptions = {},
from: jest.InitialOptions = defaults,
) {
logger.debug({ allowJs }, 'creating jest presets', allowJs ? 'handling' : 'not handling', 'JavaScript files')
return {
transform: {
...from.transform,
[allowJs ? '^.+\\.[tj]sx?$' : '^.+\\.tsx?$']: 'ts-jest',

However, it's always false as the default because there is no agrument specified in jest-preset.js, i.e.

module.exports = createJestPreset()

@huafu
Copy link
Collaborator

huafu commented Sep 21, 2018

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.

@alvis
Copy link

alvis commented Sep 22, 2018

@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?

@huafu
Copy link
Collaborator

huafu commented Sep 22, 2018

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.

@huafu
Copy link
Collaborator

huafu commented Sep 22, 2018

@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 ;-)

@alvis
Copy link

alvis commented Sep 22, 2018

@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.

ts-jest/src/compiler.ts

Lines 74 to 76 in 25e1c63

if (compilerOptions.allowJs) {
extensions.push('.js')
extensions.push('.jsx')

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

[allowJs ? '^.+\\.[tj]sx?$' : '^.+\\.tsx?$']: 'ts-jest',

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

@huafu
Copy link
Collaborator

huafu commented Sep 22, 2018

@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/

@huafu
Copy link
Collaborator

huafu commented Sep 24, 2018

@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 of
  • ts-jest/presets/js-with-ts which will compile js files with ts-jest
  • ts-jest/presets/js-with-babel which will compile js files with babel-jest

@alvis
Copy link

alvis commented Sep 24, 2018

Ooo! Amazing! Very glad we have a way to get around the issue without creating an extra jest.config.

Thanks so much @huafu

@huafu
Copy link
Collaborator

huafu commented Sep 25, 2018

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants