Closed adarean5 closed 4 years ago
/cc @lmiller1990 @JessicaSachs
I'm not sure but it looks like a vue-jest bug.
Hm, vue-jest
, the latest version of test utils and TS definitely do work together, I made a repo that illustrates this here.
I was able to reproduce this following the above steps. I then created a new project and chose not to use babel alongside TS and it worked fine. I think the problem is related to the babel transpilation running after the TS compilation step (maybe the @vue/cli-plugin-typecript-babel-preset
)?
In the past, when I saw this error (but in a different context, not a vue-cli project, but I was using jest), I had to provide the @babel/preset-env
to with babel get everything working. :thinking:
If you just want everything to work @adarean5, you can install the awesome ts-jest
preset and setting your preset to ts-jest
in jest.config.js
. This worked for me.
I wonder if we can just use ts-jest
as the preset
by default in the Jest cli plugin. @sodatea what do you think? The ts-jest
preset seems to work great for both TS and regular JS.
@vue/cli-plugin-babel/preset
do have enabled module transpilation though.
https://github.com/vuejs/vue-cli/blob/f99079cbb053d539a4e4048770a8a4154407298a/packages/%40vue/cli-plugin-unit-jest/index.js#L13-L15 https://github.com/vuejs/vue-cli/blob/f99079cbb053d539a4e4048770a8a4154407298a/packages/%40vue/babel-preset-app/index.js#L221-L227
I don't know how to debug a Jest transformer but it seems vue-jest failed to pick up this babel config.
It does seem that way. Maybe finding the babel config is not working in the latest version of vue-jest
(5.0.0-alpha something). It has not been tested very thoroughly yet, except when using ts-jest
as the preset.
What do you think about using ts-jest
as the default preset (at least for TS users?) This seems to make sense.
I think the bug may reside here https://github.com/vuejs/vue-jest/blob/e0cbca7920e3afca3bd333377a4e463b57631e66/lib/transformers/typescript.js#L29-L45
A babel config was found so no inline options were applied, but the project babel config did not take effect either.
We have both typescript
and typescript-and-babel
presets https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-jest/presets
Babel was required in many circumstances because of the need for modern mode, auto polyfill injection, and JSX, etc.
Hm, I wonder why this wasn't a problem in the past. That part of vue-jest
has not changed. The new SFC compiler, @vue/compiler-sfc
, transforms to import/export
syntax - perhaps the old one, vue-template-compiler
was transforming to require
syntax, so that is why no-one noticed.
I made an issue in vue-jest to also track this: https://github.com/vuejs/vue-jest/issues/258
Interestingly enough digging into the preset we are using, if you commented out babelConfig: true
it solves the problem, so the issue is definitely somewhere in vue-jest relating to babelConfig.
Actually, maybe not: the babelConfig
option is a ts-jest
thing. 🤔
I will continue investigating. Maybe ts-jest
master @ahnpnl has some pointers on exactly the babelConfig: true
option does in ts-jest
?
Hm,
vue-jest
, the latest version of test utils and TS definitely do work together, I made a repo that illustrates this here.I was able to reproduce this following the above steps. I then created a new project and chose not to use babel alongside TS and it worked fine. I think the problem is related to the babel transpilation running after the TS compilation step (maybe the
@vue/cli-plugin-typecript-babel-preset
)?In the past, when I saw this error (but in a different context, not a vue-cli project, but I was using jest), I had to provide the
@babel/preset-env
to with babel get everything working. 🤔If you just want everything to work @adarean5, you can install the awesome
ts-jest
preset and setting your preset tots-jest
injest.config.js
. This worked for me.I wonder if we can just use
ts-jest
as thepreset
by default in the Jest cli plugin. @sodatea what do you think? Thets-jest
preset seems to work great for both TS and regular JS.
Thank you for the reply and for providing a temporary solution. The issue might also be related to https://github.com/vuejs/vue-cli/issues/5712 . I remember getting that same message when running the start command.
a mistake when install @vue/cli-plugin-unit-jest@4.5.0
▶ npm i @vue/cli-plugin-unit-jest@4.5.0
npm ERR! code ETARGET
npm ERR! notarget No matching version found for @vue/cli-plugin-unit-jest@4.5.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/shun/.npm/_logs/2020-07-29T06_19_36_580Z-debug.log
somethine wrong when publish ?
@sodatea
https://github.com/vuejs/vue-cli/blob/d319007ffa702986e68222f8ca07a59bbfc1dbd8/packages/%40vue/cli-plugin-unit-jest/package.json#L3
4.5.0 definitely exists.
@lefreet If you are using the taobao registry mirror, please switch back to the official one. Seems its synchronization with the upstream registry is broken, I can't get the latest version synced back https://developer.aliyun.com/mirror/npm/package/@vue/cli-plugin-unit-jest
OK, finally succeeded… Please try again.
@sodatea all right, thanks.
Interestingly enough digging into the preset we are using, if you commented out
babelConfig: true
it solves the problem, so the issue is definitely somewhere in vue-jest relating to babelConfig.Actually, maybe not: the
babelConfig
option is ats-jest
thing. 🤔I will continue investigating. Maybe
ts-jest
master @ahnpnl has some pointers on exactly thebabelConfig: true
option does ints-jest
?
babelConfig: true
for ts-jest
means:
ts-jest
to invoke babel-jest
after transforming ts
to js
with TypeScript Compiler API so that babel-jest
can start transpiling the output js
from TypeScript Compiler API with Babel config.babel-jest
to automatically find Babel config.You can view documentation about babelConfig
at https://kulshekhar.github.io/ts-jest/user/config/babelConfig . It already contains all explanations.
Thanks, I should have read the docs 🤦
Anyway, I have found a fix. It looks like in Vue 2.x, the SFC tool (vue-template-compiler) would compile to commonjs. Vue 3.x compiler, @vue/compiler-sfc
, does not - it compiles to ES modules. The error in the first post of this issue is actually the compiled template.
The fix is to compile the template using babel. I was using TypeScript's transpileModule
https://github.com/vuejs/vue-jest/blob/e0cbca7920e3afca3bd333377a4e463b57631e66/lib/process.js#L52, see here, which likely is using the tsconfig.json
, which is set to module: esnext
. Instead, I will just use babel to compile the template (the template is entirely generated by @vue/compiler-sfc
, so we don't really care about types here anyway).
I will ping @sodatea when I have fixed this and we can coordinate to include the latest vue-jest for the cli-plugin.
Ok, fixed here: https://github.com/vuejs/vue-jest/pull/260, I also explained how I tested it (basically reproduce this issue, change to my fixed vue-jest, ensure test passes).
Will leave for a day or two so people can review if they want, then release a new version of vue-jest (5.x) this weekend.
I released vue-jest@5.0.0-alpha.2
. This should hopefully fix it. Can you try yarn add vue-jest@5.0.0-alpha.2
@adarean5 and see if this works for you now?
We should update the CLI plugin to use the latest @vue/test-utils
(2.0.0-beta.1) and vue-jest
(5.0.0-alpha.2).
@lmiller1990 Bad news: I did not have this issue previously (as I don't use Babel alongside TS), but I'm now encountering it with vue-jest@5.0.0-alpha.2
Repro:
vue create vue-jest-alpha-2 --inlinePreset '{"useConfigFiles": true,"plugins": {"@vue/cli-plugin-typescript": {"classComponent": false},"@vue/cli-plugin-unit-jest": {}},"vueVersion": "3"}'
cd vue-jest-alpha-2
yarn test:unit
throws:
import { toDisplayString as _toDisplayString, createVNode as _createVNode, createTextVNode as _createTextVNode, createStaticVNode as _createStaticVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue";
^^^^^^
SyntaxError: Cannot use import statement outside a module
Open package.json
and downgrade to vue-jest@5.0.0-alpha.1
and everything is fine.
Ok so it's working with babel-jest but not with ts-jest now? VTU and vue-jest is definitely working in all my projects (non cli) so I guess we have another conflict in the cli-plugin somehow.
Will investigate 👀
Problem is we are not compiling to cjs, but es modules (this import and export) and Jest doesn't know what to do, right?
Should vue-jest
force cjs? I thought jest could figure out es modules via babel-jest
? This is a classic "I don't understand ES modules in node.js environment" error. I guess if you opt out of babel, babel-jest
is not included. But if the preset is then ts-jest
, I wonder why Jest cannot figure it out?
This can likely be fixed either here (jest config to make jest understand es modules) or in vue-jest (compile to cjs modules instead of es modules, since it seems @vue/sfc-compiler
targets es modules). I am not sure where is best. Anyone know the best practice for this? Is there even one (there are so few Jest pre-processors out there, I don't think there is a single way to do it).
Hmmm… It's very complicated.
Previously the tsconfig
returned from ts-jest
was used for compiling the template code.
ts-jest
would enforce commonjs
target if no babelConfig
was found https://github.com/kulshekhar/ts-jest/blob/6bdf3320abea4d004c6863110ce306fd137e2fd8/src/config/config-set.ts#L558-L562
So it worked for TS without babel.
After this change, only babel is used for compilation, because no babel config can be found in the project, the code remains unchanged.
So the correct fix is not to use babel for all projects, but still use TS for compilation, only add babel to the pipeline if babelConfig
is set.
TS + Babel + all the various tooling is so complicated! I think I got it, though. I tested with:
All working. If you opt not to use babel, it won't work. I am not sure this workflow makes any sense, sfc-compiler spits out code using ES modules, which Jest cannot understand.
@sodatea quick review? https://github.com/vuejs/vue-jest/pull/264/files
@cexbrayat if you want to test it out, grab the latest vue-jest repo and do cp -r vue-jest/lib <your_vue_cli_project>/node_modules/vue-jest
and do yarn test:unit --no-cache
(make sure to do --no-cache
).
Can release once we are happy with it. I am sure there is a better way to write a jest transformer but better to get it working so people can try out Vue 3 and testing then optimize from there.
@lmiller1990 I gave it a quick try with the repro I had, and your PR seems to work 🎉
Great, I will leave this for 24h-48h or so, so if anyone else has feedback (maybe Soda) they get a chance and release this weekend.
I released vue-jest
5.0.0-alpha.3. It is also available as vue-jest@next
. This should hopefully resolve this!
@lmiller1990 I confirm that our builds succeed with alpha.3 (TS without babel), thank you 🎉
Now that it seems to have been fixed. I'm closing this issue now.
Version
4.5.0
Reproduction link
https://github.com/adarean5/vue3-ts-jest
Environment info
Steps to reproduce
Run the test:unit script
What is expected?
The starter unit test (/tests/unit/example.spec.ts) should pass with output similar to:
What is actually happening?
Running test:unit produces the following:
This project was created with the following options selected:
I tried creating a new project with the same settings but with either Vue version 2 or JavaScript instead of TypeScript and they both seem to work.
I tried to apply fixes from what seems like a related issue (https://github.com/vuejs/vue-cli/issues/1584) but sadly none of them worked.