vitest/docs/guide/workspace.md
2024-10-08 13:50:33 +02:00

6.1 KiB

title
Workspace | Guide

Workspace

::: tip Sample Project

GitHub - Play Online

:::

Vitest provides built-in support for monorepos through a workspace configuration file. You can create a workspace to define your project's setups.

Defining a Workspace

A workspace must include a vitest.workspace or vitest.projects file in its root directory (located in the same folder as your root configuration file, if applicable). Vitest supports ts, js, and json extensions for this file.

::: tip NAMING Please note that this feature is named workspace, not workspaces (without an "s" at the end). :::

Workspace configuration file must have a default export with a list of files or glob patterns referencing your projects. For example, if you have a folder named packages that contains your projects, you can define a workspace with this config file:

:::code-group

export default [
  'packages/*'
]

:::

Vitest will treat every folder in packages as a separate project even if it doesn't have a config file inside. Since Vitest 2.1, if this glob pattern matches any file it will be considered a Vitest config even if it doesn't have a vitest in its name.

::: warning Vitest does not treat the root vitest.config file as a workspace project unless it is explicitly specified in the workspace configuration. Consequently, the root configuration will only influence global options such as reporters and coverage. :::

You can also reference projects with their config files:

:::code-group

export default [
  'packages/*/vitest.config.{e2e,unit}.ts'
]

:::

This pattern will only include projects with a vitest.config file that contains e2e or unit before the extension.

You can also define projects using inline configuration. The workspace file supports both syntaxes simultaneously.

:::code-group

import { defineWorkspace } from 'vitest/config'

// defineWorkspace provides a nice type hinting DX
export default defineWorkspace([
  // matches every folder and file inside the `packages` folder
  'packages/*',
  {
    // add "extends" to merge two configs together
    extends: './vite.config.js',
    test: {
      include: ['tests/**/*.{browser}.test.{ts,js}'],
      // it is recommended to define a name when using inline configs
      name: 'happy-dom',
      environment: 'happy-dom',
    }
  },
  {
    test: {
      include: ['tests/**/*.{node}.test.{ts,js}'],
      name: 'node',
      environment: 'node',
    }
  }
])

:::

::: warning All projects must have unique names; otherwise, Vitest will throw an error. If a name is not provided in the inline configuration, Vitest will assign a number. For project configurations defined with glob syntax, Vitest will default to using the "name" property in the nearest package.json file or the folder name if no such file exists. :::

If you do not use inline configurations, you can create a small JSON file in your root directory:

:::code-group

[
  "packages/*"
]

:::

Workspace projects do not support all configuration properties. For better type safety, use the defineProject method instead of defineConfig within project configuration files:

:::code-group

// @errors: 2769
import { defineProject } from 'vitest/config'

export default defineProject({
  test: {
    environment: 'jsdom',
    // "reporters" is not supported in a project config,
    // so it will show an error
    reporters: ['json']
  }
})

:::

Running tests

To run tests inside the workspace, define a script in your root package.json:

{
  "scripts": {
    "test": "vitest"
  }
}

Now tests can be run using your package manager:

::: code-group

npm run test
yarn test
pnpm run test
bun test

:::

If you need to run tests only inside a single project, use the --project CLI option:

::: code-group

npm run test --project e2e
yarn test --project e2e
pnpm run test --project e2e
bun test --project e2e

:::

::: tip CLI option --project can be used multiple times to filter out several projects:

::: code-group

npm run test --project e2e --project unit
yarn test --project e2e --project unit
pnpm run test --project e2e --project unit
bun test --project e2e --project unit

:::

Configuration

None of the configuration options are inherited from the root-level config file. You can create a shared config file and merge it with the project config yourself:

::: code-group

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

export default mergeConfig(
  configShared,
  defineProject({
    test: {
      environment: 'jsdom',
    }
  })
)

:::

At the defineWorkspace level, you can use the extends option to inherit from your root-level configuration. All options will be merged.

::: code-group

import { defineWorkspace } from 'vitest/config'

export default defineWorkspace([
  {
    extends: './vitest.config.ts',
    test: {
      name: 'unit',
      include: ['**/*.unit.test.ts'],
    },
  },
  {
    extends: './vitest.config.ts',
    test: {
      name: 'integration',
      include: ['**/*.integration.test.ts'],
    },
  },
])

:::

Some of the configuration options are not allowed in a project config. Most notably:

  • coverage: coverage is done for the whole workspace
  • reporters: only root-level reporters can be supported
  • resolveSnapshotPath: only root-level resolver is respected
  • all other options that don't affect test runners

::: tip All configuration options that are not supported inside a project configuration are marked with a sign in the "Config" guide. :::