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

Vitest workspaces support #664

Open
2 of 4 tasks
ennioVisco opened this issue Dec 19, 2023 · 6 comments · May be fixed by nuxt/nuxt#30510
Open
2 of 4 tasks

Vitest workspaces support #664

ennioVisco opened this issue Dec 19, 2023 · 6 comments · May be fixed by nuxt/nuxt#30510
Labels
enhancement New feature or request good first issue Good for newcomers vitest-environment

Comments

@ennioVisco
Copy link

ennioVisco commented Dec 19, 2023

Describe the feature

When using vitest in a monorepo setting, one is likely to use the vitest workspaces feature: https://vitest.dev/guide/workspace

However, in this setting one would use defineProject instead of defineConfig, to reuse the global vitest instance.

It would be cool to be able to do this also for nuxt apps, in order to run nuxt tests seamlessly along the ones of other packages

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module?

Final checks

@danielroe danielroe added enhancement New feature or request good first issue Good for newcomers vitest-environment and removed pending triage labels Dec 19, 2023
@dosubot dosubot bot added the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label Apr 24, 2024
@dosubot dosubot bot closed this as not planned Won't fix, can't repro, duplicate, stale May 1, 2024
@dosubot dosubot bot removed the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label May 1, 2024
@Mokkapps
Copy link

Mokkapps commented May 1, 2024

We should keep this issue active as Vitest workspaces are a common thing for monorepos.

@danielroe danielroe reopened this May 1, 2024
@ekisu
Copy link

ekisu commented Aug 14, 2024

This would be very useful! Right now we use Vitest workspaces in order to run tests with vastly differing environments (setupFiles, etc), and using defineVitestConfig with some @ts-ignore annotations does the job; but having official support with something like defineVitestProject would be a great addition

@TheDutchCoder
Copy link

This would be very useful! Right now we use Vitest workspaces in order to run tests with vastly differing environments (setupFiles, etc), and using defineVitestConfig with some @ts-ignore annotations does the job; but having official support with something like defineVitestProject would be a great addition

Could you please share how you make it work?
We're currently unable to make it work due to Nuxt auto-imports not being resolved.

@ekisu
Copy link

ekisu commented Dec 19, 2024

@TheDutchCoder Sure! I don't remember all the details, but I'll try sharing what we have. We have a vitest.config.ts file with some coverage configuration (I don't really recall why it's set there, but 🤷):

import { defineConfig } from 'vitest/config'

// https://vitest.dev/config/
export default defineConfig({
  test: {
    coverage: {
      all: false,
      reporter: ['lcov', 'json', 'html', 'text'],
      exclude: ['src/**/*test.ts', '<more excluded stuff>']
    }
  }
})

And a vitest.workspace.mts file (I remember having some issues when using plain .ts files here, not sure why) with the following contents:

import { fileURLToPath, URL } from 'url'
import { defineWorkspace, defineProject, type Plugin } from 'vitest/config'
import { defineVitestConfig as defineNuxtVitestConfig } from '@nuxt/test-utils/config'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export function relativeToProjectRoot (path: string): string {
  return fileURLToPath(new URL(path, import.meta.url))
}

export default defineWorkspace([
  'packages/*',
  defineProject({
    // @ts-ignore
    resolve: {
      alias: {
        '~': relativeToProjectRoot('./src'),
        '@': relativeToProjectRoot('./src'),
        '~~': relativeToProjectRoot('./'),
        '@@': relativeToProjectRoot('./'),
        '#app': relativeToProjectRoot('./node_modules/nuxt/dist/app/index.d.ts'),
        '#app/components/nuxt-link': relativeToProjectRoot('./node_modules/nuxt/dist/app/components/nuxt-link'),
        '#imports': relativeToProjectRoot('./.nuxt/imports.d.ts'),
        '#vue-router': relativeToProjectRoot('./node_modules/vue-router'),
        '#components': relativeToProjectRoot('./.nuxt/components'),
        '#components/*': relativeToProjectRoot('./.nuxt/components/*')
      }
    },
    plugins: [vue(), vueJsx()] as Plugin[],
    test: {
      name: 'happy-dom',
      environment: 'happy-dom',
      globals: true,
      include: ['src/**/*.test.ts'].map(relativeToProjectRoot),
      exclude: ['src/**/*.nuxt.test.ts'].map(relativeToProjectRoot),
      includeSource: ['src/**/*.ts'].map(relativeToProjectRoot),
      setupFiles: [
        'src/global/test/setupTestingLibrary.ts',
        '<some other setup files>'
      ].map(relativeToProjectRoot),
    }
  }),
  // @ts-ignore
  defineNuxtVitestConfig({
    // @ts-ignore
    test: {
      name: 'nuxt',
      environment: 'nuxt',
      include: ['src/**/*.nuxt.test.ts'].map(relativeToProjectRoot),
      setupFiles: [
        'src/global/test/setupTestingLibrary.ts',
        'src/global/test/setupI18nOnNuxtEnvironment.ts',
        '<more setup files>'
      ].map(relativeToProjectRoot),
    }
  })
])

The last setup file on the Nuxt environment (setupI18nOnNuxtEnvironment.ts) worked around some issues we had with Nuxt's i18n not actually translating strings during tests:

import { config } from '@vue/test-utils'
import { beforeAll } from 'vitest'

beforeAll(() => {
  const nuxtApp = useNuxtApp()

  config.global.plugins.push({
    async install (app, ...options) {
      // @ts-ignore
      const i18n = nuxtApp.vueApp.__VUE_I18N__

      await i18n.install(app, ...options)
    }
  })
})

With this configuration, test files named *.test.ts will run under the happy-dom environment (we had a lot of existing tests that needed to run under it), and test files named *.nuxt.test.ts will run under the nuxt environment

@TheDutchCoder
Copy link

@ekisu Thanks, this points me in the right direction it seems!
Some of the stuff starts to work, some not yet, not entirely sure what I'm missing still.
Image

I think some of the auto-imports still don't work. For example, one of the utils functions uses another util function. For example util function foo uses util function bar, and bar can't be resolved.

Our structure is as follows

- vitest.workspace.ts
- /src
--/tests
---/unit (has some setup files)
---/composable
---/component
--/utils (all the util functions that also reference each other in some cases)
---/__tests__ (all the unit tests for utils)
--/composables
---/__tests__
etc

@huang-julien
Copy link
Member

here's a very minimal reproduction which triggers a context conflict with useNuxt: https://github.com/huang-julien/nuxt-vitest-workspace-repro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers vitest-environment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants