vue-jest
vue-jest copied to clipboard
Support Nuxt3 Auto-Imports
Nuxt 3 provides auto import for script-setup for composable functions (not only)
Info about: https://www.storyblok.com/mp/nuxt3-best-features
Example: https://codesandbox.io/s/dazzling-butterfly-7eo67
It'd be great to support it, for now it throws errors like ReferenceError: ref is not defined
if you won't import it manually
Is this still an issue? It might be working since many fixes landed in @vue/vue3-jest
.
@lmiller1990 It is. with latest jest
packages and @vue/vue3-jest
I'm still receiving errors like ReferenceError: computed is not defined
if it's not imported in component.
For #1 - does Nuxt auto import ref
, computed
etc? In the post it says
If you're familiar with
What does it refer to when it says "any of the composable functions that Nuxt 3 brings to you"? I thought this means things inside of composables
- not raw Vue reactivity APIs (could be wrong, I haven't used Nuxt 3 much).
I looked at your example #2 link - looks like a regular Nuxt starter? What should I be seeing?
Either way, any form of Nuxt magic is going to be a problem. We might need to sync with the Nuxt team - I don't think Test Utils should attempt to replicate Nuxt, rather, we should find out what they are doing to register things and see if we can hook into it, so we can get any changes they make for free.
Any news on this ??
We need to find out how Nuxt does this and see if they can share the code that auto injects. Vue Jest just converts code to work with Jest; it doesn't know about things like Nuxt auto injections, etc.
Another thing you could try is simply import the functions, in the meantime.
Someone should file an issue in the Nuxt repo and link it to this issue, we need to work with Nuxt team to solve this.
ref
and computed
are not handled by the nuxt auto-importer. They are handled by the vue SFC compiler. These should work and are supported by vue-jest.
https://github.com/vuejs/core/blob/f67bb500b6071bc0e55a89709a495a27da73badd/packages/compiler-sfc/src/compileScript.ts#L216 https://github.com/vuejs/core/blob/f67bb500b6071bc0e55a89709a495a27da73badd/packages/reactivity-transform/src/reactivityTransform.ts
Regarding the Nuxt feature, Auto import is implemented as Nuxt plugin, but that is unrelated to the vue script setup syntactic sugar that is used for computed
and ref
.
See here. https://github.com/nuxt/framework/blob/6d830c7629c516dbb37c252863144f18192b9237/packages/nuxt/src/imports/module.ts#L83
I imagine vitest already supports the ability to load the Nuxt plugins. It is recommended by Nuxt.
https://v3.nuxtjs.org/getting-started/testing/
I think Nuxt should develop a transformer if they intend to support Nuxt plugins with jest. They claim to support jest, but perhaps the support is incomplete.
I think @xxSkyy misidentified the problem. Is @MatthD having the same issue with computed
and ref
?
Recently I've tested Vitest with Nuxt 3 and with some configuration auto-import works great.
@xxSkyy That's really nice to here, can you share some info around "some configuration"? What did you need to do?
Maybe we can do something similar here?
@lmiller1990 sure, overall I've used unplugin-auto-import. Here's my vitest.config.ts
import { defineConfig } from "vitest/config"
import Vue from "@vitejs/plugin-vue"
import AutoImport from "unplugin-auto-import/vite"
export default defineConfig({
plugins: [
Vue(),
AutoImport({
imports: [
"vue",
// could add 'vue-router' or 'vitest', whatever else you need.
],
}),
],
test: {
globals: true,
environment: "jsdom",
deps: {
inline: [/@nuxt\/test-utils-edge/],
},
},
})
This plugin has wide variety of compatible environments so probably there are possibility that you can benefit from it. For sure it doesn't solve everything, like if component uses useNuxtApp
to get some plugin in it it has to be mocked, but I believe overall it's enough, and can be expanded by other deps you have.
Right, I see, it probably just injects the entire Vue API globally. Bit of a hack, shame there isn't a way to access "the guts" of Nuxt and do whatever they do 1:1. Maybe in the future, we can.
For vue-jest, I guess we have a few options.
- Userland hack. I wonder if something like this would work:
beforeEach(() => {
global.computed = vue.computed
})
Eg, inject all the things manually.
If that cannot be made to work, Vue Jest could expose something:
// jest.config.js
export default {
global: {
'vue-jest': {
inject: {
computed: vue.computed
}
}
}
}
Just some ideas, userland work around would be best, since we don't want to re-create functionality here if we can avoid it.
I still think the best solution is to collab with Nuxt, if someone wants to open an issue there to investigate, that would be great. That said, for new projects, Vite is the default, so it seems less likely people want to use Jest with Nuxt 3.
@xxSkyy I'm trying this in a Nuxt3 app and I get
// cypress.config.ts
import { defineConfig } from 'cypress'
import vue from '@vitejs/plugin-vue'
import AutoImport from "unplugin-auto-import/vite"
export default defineConfig({
"component": {
"devServer": {
"framework": "vue",
"bundler": "vite",
"viteConfig": {
"plugins": [vue(), AutoImport()],
test: {
globals: true,
deps: {
inline: ['/@nuxt\/test-utils-edge/']
}
}
}
}
}
})
Yields a TypeError: (0 , vite_1.default) is not a function
error as soon as I add AutoImport()
to the array.
@lmiller1990 it should be possible to load the unplugins and apply the transformers
Is there a list of things we'd need to handle? From what I've gathered
-
$nuxt
global - component auto import*
- composable auto import*
Could not see this specifically in their docs, maybe I need to read more.
@speg I didn't test it with cypress so I'm not sure. Blind guess - maybe update your vite. Here you have my example configured repo with nuxt3 and vitest working https://gitlab.com/xxSkyy/nuxt3-vitest-example
~Is there any news on this? I can add the vue imports using the AutoImport plugin but it would be nice to have a way to also include the components, composables, utils etc.~
Update: nvm you can use the dir
field on the AutoImport options
@gbyesiltas https://github.com/danielroe/nuxt-vitest
@gbyesiltas https://github.com/danielroe/nuxt-vitest
@dsvgl Thanks! It does work, though it runs the whole nuxt environment with the plugins etc. which is a bit concerning for our project where we have our unit tests more isolated
Recently I've tested Vitest with Nuxt 3 and with some configuration auto-import works great.
can you share? Currently started with. Nuxt3, Vitest & Pinia. Keep hitting walls. Mainly with Nuxt things like useRoute
not being found by the test unless we import useRoute
in that component.
@lmiller1990 sure, overall I've used unplugin-auto-import. Here's my
vitest.config.ts
import { defineConfig } from "vitest/config" import Vue from "@vitejs/plugin-vue" import AutoImport from "unplugin-auto-import/vite" export default defineConfig({ plugins: [ Vue(), AutoImport({ imports: [ "vue", // could add 'vue-router' or 'vitest', whatever else you need. ], }), ], test: { globals: true, environment: "jsdom", deps: { inline: [/@nuxt\/test-utils-edge/], }, }, })
This plugin has wide variety of compatible environments so probably there are possibility that you can benefit from it. For sure it doesn't solve everything, like if component uses
useNuxtApp
to get some plugin in it it has to be mocked, but I believe overall it's enough, and can be expanded by other deps you have.
Thank you, your solution helped me, I am still running into a problem with Composables, vitest is angry at them unless explicitly import them into each component under test, any ideas how to solve it?
vitest.config.ts so far:
`import vue from "@vitejs/plugin-vue"; import { defineProject, mergeConfig } from "vitest/config"; import baseConfig from "../vitest.base"; import AutoImport from "unplugin-auto-import/vite";
export default mergeConfig( baseConfig, defineProject({ plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => { return tag.startsWith("v-"); }, }, }, }), AutoImport({ imports: ["vue"], }), ],
server: {
host: "0.0.0.0",
},
test: {
globals: true,
environment: "jsdom",
},
}), );`