vitest-dev / vscode

VS Code extension for Vitest
https://vitest.dev/vscode
MIT License
743 stars 83 forks source link

Not working properly in monorepo #110

Closed yukinami closed 7 months ago

yukinami commented 1 year ago

Describe the bug Not working properly in monorepo projects. By not working propertyly means vite could not resolve path alias becasue vitest was executed in the wrong user dir which is the root dir (which should be the package/xxx dir where vite.config exists ).

To Reproduce Run test in monorepo with resolve.alias defined in vite.config of sub package.

Expected behavior Working properly in monorepo.

Screenshots image image

Environment

(Paste info.txt content generated by the example project)

Additional context

adrienbaron commented 1 year ago

Hi! I've had the same issue and I fixed it by creating a VSCode Workspace file. Once you have one the extension seems to pick up it needs to use the workspace root your test is in πŸ‘

yukinami commented 1 year ago

Hi! I've had the same issue and I fixed it by creating a VSCode Workspace file. Once you have one the extension seems to pick up it needs to use the workspace root your test is in πŸ‘

You mean using Multi-root workspaces? Can you show me an example?

adrienbaron commented 1 year ago

Hi! I've had the same issue and I fixed it by creating a VSCode Workspace file. Once you have one the extension seems to pick up it needs to use the workspace root your test is in πŸ‘

You mean using Multi-root workspaces? Can you show me an example?

The project I've used that in is closed source (it's at my workplace), but it's literally just creating the file like indicated in the doc and setting one of the root path to be the folder where Vitest is installed in your repo πŸ˜‰

dohooo commented 1 year ago

Same here.


Re: https://github.com/vitest-dev/vscode/issues/81#issuecomment-1366272133

cefn commented 1 year ago

I also experience this problem, arising from running in the wrong folder.

On the plus side, https://github.com/kwai-explore/vscode-vitest-runner just works, although it doesn't have integration with the test explorer. The way the other one works correctly - first cd to the directory containing the target file.

Running from the right folder means that tooling benefits from the test-specific tsconfig.json I have at packages/packageName/test/tsconfig.json in my monorepo and the vitest.config.ts I have at packageName/vitest.config.ts which references the tsconfig. Both are ignored if you run from the top level folder of the monorepo.

cefn commented 1 year ago

Worse, however, and really must be fixed, is the poor behaviour when the vitest process fails (owing to a poorly selected working directory).

The UI simply swallows errors and sits there indefinitely with spinners rather than finalising the task with an error case.

image

Behind the scenes in the Output => Vitest terminal you can see the failures which are not properly handled by vitest-dev such as the following, because it's not loading the tsconfig.json from the parent directory and vitest.conf.ts that brings in the correct vitest globals...

 FAIL  packages/public-api/test/index.test.ts [ packages/public-api/test/index.test.ts ]
ReferenceError: describe is not defined

...

Test Files  1 failed (1)
      Tests  no tests
   Start at  12:30:15
   Duration  11.64s (transform 3.88s, setup 0ms, collect 0ms, tests 0ms)
 FAIL  Tests failed. Watching for file changes...
       press h to show help, press q to quit

Also this meaningful error content is completely missing from the inline-notified error if you configure the extension to create test error popups.

image

cefn commented 1 year ago

A workaround is to edit the vitest command to include an explicit root. For me, adding the following to the workspace meant that at least one of the packages in the monorepo could show interactive test results correctly.

    "vitest.commandLine": "npx vitest --root packages/packageName/test"

In terms of the vitest-dev extension, if running from the proper root can't be configured as default behaviour, perhaps the basedir of the file being run could be passed as a variable, meaning users could inline this logic to the vitest.commandLine as required.

This would lead to something like the following, which would mean more than one package in a monorepo could have passing tests at one time...

    "vitest.commandLine": "npx vitest --root ${baseDir}"
kasperstorgaard commented 1 year ago

Hi! I've had the same issue and I fixed it by creating a VSCode Workspace file. Once you have one the extension seems to pick up it needs to use the workspace root your test is in πŸ‘

@adrienbaron I have tried to fix this through various ways, but cannot get vscode to auto detect the workspace and find the vite.config.ts file. Can you share an example of you structure and vscode settings / workspace files?

sean-sbl-uk commented 1 year ago

Hi! I've had the same issue and I fixed it by creating a VSCode Workspace file. Once you have one the extension seems to pick up it needs to use the workspace root your test is in πŸ‘

You mean using Multi-root workspaces? Can you show me an example?

The project I've used that in is closed source (it's at my workplace), but it's literally just creating the file like indicated in the doc and setting one of the root path to be the folder where Vitest is installed in your repo πŸ˜‰

Can you please provide a more detailed answer for those of us who are still struggling. Like kasperstorgaard above asked, maybe an example or screenshot would be very helpful.

tomdavidson commented 1 year ago

VS Code's multi-root workspace may work for some but for many of our shared/mono repo set ups, we have one VS Code root, one .vscode/* one .git/* etc.

Rather than a multi-root issue this seems more of cwd concern.

tomdavidson commented 1 year ago

Just messing around but here's a start: "vitest.commandLine": "pnpm --if-present -r test --" pnpm has some create filtering options to employ too.

sfedorov-at-wiley commented 1 year ago

Can confirm all of the above We started using Nx and found out that extension does not recognise /libs/ui/vite.config.ts or /apps/front/vite.config.ts There is no vite.config.ts in the root of repository For every test in the repo extension printed "test results not found" When we tried to define command in settings.json as npx vitest -- all of the tests ended up in infinite loop

Hope this feedback helps

ButuzGOL commented 1 year ago

This workaround works for subfolders

"vitest.commandLine": "npx vitest --root packages/packageName"

Check logs in vitest in output it more informative

Only problem i am facing now it skips env variables

mrcaidev commented 1 year ago

This works for me, using Vitest Workspace:

import { defineWorkspace } from "vitest/config";

export default defineWorkspace(["packages/*", "apps/*"]);

And nothing else.

Plus, I install vitest only in monorepo root.

cjroebuck commented 1 year ago

I believe vitest 0.30+ introduced the concept of vitest workspaces

@mrcaidev’s comment above is using the vitest.workspace.ts file as described in the vitest workspace docs.

After upgrading to vitest 0.30.1 and adding the workspace file to my root dir, the vscode extension started running tests in my packages/* folder correctly. πŸ˜„

itsjavi commented 1 year ago

I believe vitest 0.30+ introduced the concept of vitest workspaces

@mrcaidev’s comment above is using the vitest.workspace.ts file as described in the vitest workspace docs.

After upgrading to vitest 0.30.1 and adding the workspace file to my root dir, the vscode extension started running tests in my packages/* folder correctly. πŸ˜„

can you please share your setup? I did that and it's still stuck.

I have vitest installed in the root package.json with pnpm, and a vitest.workspace.ts:

import { defineWorkspace } from 'vitest/config'

export default defineWorkspace(['packages/*'])

what's your command for vitest.commandLine ?

mrcaidev commented 1 year ago

what's your command for vitest.commandLine ?

I did not set vitest.commandLine myself so I guess the default would work.

guzart commented 1 year ago

I did not set vitest.commandLine myself so I guess the default would work.

Same here. I added the workspaces config file in the root of the monorepo project:

// vitest.workspace.ts
export default ["packages/*"];

Then I made sure I was able to run vitest in watch mode successfully from one of the projects e.g. packages/project-a/. And finally I think the VSCode vitest extension had a conflict with another of my VSCode test related extensions, because it all started working after I disabled other VSCode test explorer extensions.

jrson83 commented 1 year ago

Please provide a working example on how to setup vitest workspaces in a monorepo, with packages including other compilers then vite. After 5 hours I still can't get it to work.

koistya commented 1 year ago

I have a few repositories for experimenting with Vitest in a monorepo setup:

https://github.com/koistya/vitest-workspaces β€” bare minimum Vitest config https://github.com/kriasoft/react-starter-kit β€” front-end monorepo https://github.com/kriasoft/relay-starter-kit β€” full-stack monorepo

β”œβ”€β”€ app/vite.config.ts β€” React front-end (app) β”œβ”€β”€ edge/vite.config.ts β€” Cloudflare Workers (edge) β”œβ”€β”€ vitest.config.ts β€” Root-level Vite config └── vitest.workspaces.ts β€” Vitest workspaces

daniel-johnsson commented 1 year ago

I got it to work using the vs code workspace workaround. You can define your workspace using a file in the root with the name yourmainfolder.code-workspace and in that folder you can add a custom vitest.commandLine to each folder:

{
  "folders": [
    {
      "path": "apps/webapp",
      "vitest.commandLine": "yarn vitest --root apps/webapp"
    },
    {
      "path": "packages/integrations",
      "vitest.commandLine": "yarn vitest --root packages/integrations"
    }
  ]
}
vikingair commented 1 year ago

The vitest.workspace.ts works somewhat, but not really well. After adding it, VSCode is able to run the tests, but

  1. It runs all tests of every package regardless where I triggered it in the UI
  2. In case of an error it still mentions. But the test name is unique.

    Test result not found. 
    
    If you set `vitest.commandLine` please check: 
    
       Did you set `vitest.commandLine` to `run` mode? (This extension requires `watch` mode to get the results from Vitest api)
    
       Does it have the ability to append extra arguments? (For example it should be `yarn test --` rather than `yarn test`)
    
    Are there tests with the same name?
    
    Can you run vitest successfully on this file? Does it need custom option to run?
  3. In some cases I get a TS error for otherwise succeeding tests and no actual TS errors:
    TypeError: Cannot read properties of undefined (reading 'item')
  4. It is also creating a dist directory with some version file (but this is tolerable)
steven87vt commented 1 year ago

In nx mono-repository I was able to get this working finally using the vitest.workspace.ts method, and nothing more then the default command line options:

Notes:

  1. Use the project workspace settings to limit tests in the vitest ui. Jest tests should be excluded, or by exclusive include.
  2. Use vitest.workspace.ts to isolate vitest enabled packages using the config file glob, seems to be needed for vitest to work at the command line.
  3. Don't try to run vitest --run in mode via project settings, rather leave it in watch as the vitest plugin needs this to report success/failure cases.
  4. I have come to avoid using the import { configDefaults } from 'vitest/config' package object values. I prefer a global config I can override in specific packages (e.g. vitest.shared.ts defines majority of test configurations)
  5. Remove test definition from vite.config.ts
  6. Don't forget to absorb your, hopefully, already working vite.config.ts that should define viteTsConfigPaths({ root: '../../../' }) plugin
  7. Some errors that happen before the test starts can cause the result not found problem. Remember to check the vscode > outputs > vitest log. The last issue I had like this was a missing or broken alias path.
// <root>/vitest.workspace.ts
import { defineWorkspace } from 'vitest/config'

export default defineWorkspace([
  'packages/**/vitest.config.{e2e,unit}.ts',
  'packages/**/vitest.config.ts'
])
// <root>/vitest.shared.ts

import { UserConfig } from 'vitest'
import { defaultExclude } from 'vitest/config'

const config: UserConfig = {
  globals: true,
  environment: 'node',
  cache: {
    dir: '../../../node_modules/.vitest'
  },
  include: ['test/**/*.test.ts'],
  exclude: defaultExclude
}

export default config
// <root>/packages/features/some-vue-feature/vitest.config.ts

import configShared from '../../../vitest.shared'
import { defineConfig, mergeConfig } from 'vitest/config'

import viteConfig from './vite.config'
import path from 'path'
import { UserConfig } from 'vitest'

const config: UserConfig = {
  ...configShared,
  environment: 'jsdom',
  setupFiles: ['test/unit/test-setup.ts'],
  alias: {
    '@/store': path.resolve(__dirname, 'test/unit/__mocks__/store.ts'),
    '@ezwebproductions/lib-core': path.resolve(__dirname, '../../lib/core/src/index.ts')
  }
}

export default mergeConfig(
  viteConfig({ mode: 'test', command: 'build' }),
  defineConfig({
    test: config
  })
)
// <root>/packages/lib/core/vitest.config.ts

import { mergeConfig, defineConfig } from 'vitest/config'
import configShared from '../../../vitest.shared'
import viteConfig from './vite.config'

export default mergeConfig(
  viteConfig({ command: 'build', mode: 'test' }),
  defineConfig({ test: configShared })
)

// project.code-workspace
{
    "vitest.enable": true,
    "vitest.commandLine": "npx vitest",
    "vitest.exclude": [
      "**/node_modules/**",
      "**/dist/**",
      "**/cypress/**",
      "**/.{idea,git,cache,output,temp}/**",
      "packages/commonjs-only-systems/**/*.test.ts"
    ],
    "vitest.include": [
      "packages/limit/your/use/case/for/ui/tests/here/**/*.test.ts",
      "packages/features/**/*.test.ts",
      "packages/lib/idb/**/*.test.ts",
      "packages/lib/core/**/*.test.ts"
    ]
}
divmgl commented 11 months ago

@steven87vt this was massively helpful. By far one of the most helpful comments I've seen on GitHub. Thanks a million for this!

ffMathy commented 7 months ago

This has now been properly fixed by merging #231 and #241!

Enjoy. Monorepo support should be a lot easier now, and a new NX example has been added as well. I think we can close this.