这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 122 additions & 21 deletions docs/repo-docs/guides/tools/vitest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,26 @@ import { Tab, Tabs } from '#/components/tabs';

[Vitest](https://vitest.dev/) is a test runner from the Vite ecosystem. Integrating it with Turborepo will lead to enormous speed-ups.

<CreateTurboCallout />
[The Vitest documentation](https://vitest.dev/guide/workspace) shows how to create a "Vitest Workspace" that runs all tests in the monorepo from one root command, enabling behavior like merged coverage reports out-of-the-box. This feature doesn't follow modern best practices for monorepos, since its designed for compatibility with Jest (whose Workspace feature was built before [package manager Workspaces](/repo/docs/crafting-your-repository/structuring-a-repository)).

## Setting up
Because of this you have two options, each with their own tradeoffs:

Let's say we have a monorepo that looks like this:
- [Leveraging Turborepo for caching](#leveraging-turborepo-for-caching)
- [Using Vitest's Workspace feature](#using-vitests-workspace-feature)

### Leveraging Turborepo for caching

To improve on cache hit rates and only run tests with changes, you can choose to configure tasks per-package, splitting up the Vitest command into separate, cacheable scripts in each package. This speed comes with the tradeoff that you'll need to create merged coverage reports yourself.

<Callout>
For a complete example, run `npx create-turbo@latest --example with-vitest` or
[visit the example's source
code](https://github.com/vercel/turborepo/tree/main/examples/with-vitest).
</Callout>

#### Setting up

Let's say we have a simple [package manager Workspace](/repo/docs/crafting-your-repository/structuring-a-repository) that looks like this:

<Files>
<Folder name="apps" defaultOpen>
Expand All @@ -29,12 +44,15 @@ Let's say we have a monorepo that looks like this:
</Folder>
</Files>

Both `apps/web` and `packages/ui` have their own test suite. Their `package.json` files include a `test` script that runs Vitest:
Both `apps/web` and `packages/ui` have their own test suites, with `vitest` [installed into the packages that use them](/repo/docs/crafting-your-repository/managing-dependencies#install-dependencies-where-theyre-used). Their `package.json` files include a `test` script that runs Vitest:

```json title="./apps/web/package.json"
{
"scripts": {
"test": "vitest"
"test": "vitest run"
},
"devDependencies": {
"vitest": "latest"
}
}
```
Expand All @@ -44,55 +62,66 @@ Inside the root `turbo.json`, create a `test` task:
```json title="./turbo.json"
{
"tasks": {
"test": {}
"test": {
"dependsOn": ["transit"]
},
"transit": {
"dependsOn": ["^transit"]
}
}
}
```

Now, `turbo test` can parallelize and cache all of the test suites from each package, only testing code that has changed.
Now, `turbo run test` can parallelize and cache all of the test suites from each package, only testing code that has changed.

#### Running tests in watch mode

## Running tests in watch mode
When you run your test suite in CI, it logs results and eventually exits upon completion. This means you can [cache it with Turborepo](/repo/docs/crafting-your-repository/caching). But when you run your tests using Vitest's watch mode during development, the process never exits. This makes a watch task more like a [long-running, development task](/repo/docs/crafting-your-repository/developing-applications).

When you run your test suite normally, it completes and outputs to `stdout`. This means you can [cache it](/repo/docs/crafting-your-repository/caching) with Turborepo.
Because of this difference, we recommend specifying **two separate Turborepo tasks**: one for running your tests, and one for running them in watch mode.

But when you run your tests in a watched mode, the process never exits. This makes a watch task more like a [development task](/repo/docs/crafting-your-repository/developing-applications).
<Callout>
This strategy below creates two tasks, one for local development and one for
CI. You could choose to make the `test` task for local development and create
some `test:ci` task instead.
</Callout>

Because of this difference, we recommend specifying **two separate Turborepo tasks**: one for running your tests, and one for running them in watch mode. Inside your each `package.json` file for each workspace:
For example, inside the `package.json` file for each workspace:

```json title="./apps/web/package.json"
{
"scripts": {
"test": "vitest",
"test": "vitest run",
"test:watch": "vitest --watch"
}
}
```

Inside the root `turbo.json`:
And, inside the root `turbo.json`:

```json title="./turbo.json"
{
"tasks": {
"test": {},
"test": {
"dependsOn": ["^test"]
},
"test:watch": {
"cache": false, // [!code highlight]
"persistent": true // [!code highlight]
"cache": false,
"persistent": true
}
}
}
```

You can now either run this task using [global `turbo`](/repo/docs/getting-started/installation#global-installation) as `turbo test:watch` or from a script in your root `package.json`:
You can now run your tasks using [global `turbo`](/repo/docs/getting-started/installation#global-installation) as `turbo run test:watch` or from a script in your root `package.json`:

<Tabs items={["Global turbo", "./package.json"]}>
<Tab value="Global turbo">

```bash title="Terminal"
turbo test
```
turbo run test

```bash title="Terminal"
turbo test:watch
turbo run test:watch
```

</Tab>
Expand All @@ -111,3 +140,75 @@ turbo test:watch
</Tab>

</Tabs>

#### Creating merged coverage reports

[Vitest's Workspace feature](#using-vitests-workspace-feature) creates an out-of-the-box coverage report that merges all of your packages' tests coverage reports. Following the Turborepo strategy, though, you'll have to merge the coverage reports yourself.

<Callout type="info">
The [`with-vitest`
example](https://github.com/vercel/turborepo/tree/main/examples/with-vitest)
shows a complete example that you may adapt for your needs. You can get
started with it quickly using `npx create-turbo@latest --example with-vitest`.
</Callout>

To do this, you'll follow a few general steps:

1. Run `turbo run test` to create the coverage reports.
2. Merge the coverage reports with [`nyc merge`](https://github.com/istanbuljs/nyc?tab=readme-ov-file#what-about-nyc-merge).
3. Create a report using `nyc report`.

Turborepo tasks to accomplish will look like:

```json title="./turbo.json"
{
"tasks": {
"test": {
"dependsOn": ["^test", "@repo/vitest-config#build"],
"outputs": ["coverage.json"]
}
"merge-json-reports": {
"inputs": ["coverage/raw/**"],
"outputs": ["coverage/merged/**"]
},
"report": {
"dependsOn": ["merge-json-reports"],
"inputs": ["coverage/merge"],
"outputs": ["coverage/report/**"]
},
}
}
```

With this in place, run `turbo test && turbo report` to create a merged coverage report.

<Callout type="info">
The [`with-vitest`
example](https://github.com/vercel/turborepo/tree/main/examples/with-vitest)
shows a complete example that you may adapt for your needs. You can get
started with it quickly using `npx create-turbo@latest --example with-vitest`.
</Callout>

### Using Vitest's Workspace feature

The Vitest Workspace feature doesn't follow the same model as a [package manager Workspace](/repo/docs/crafting-your-repository/structuring-a-repository). Instead, it uses a root script that then reaches out into each package in the repository to handle the tests in that repsective package.

In this model, there aren't package boundaries, from a modern JavaScript ecosystem perspective. This means you can't rely on Turborepo's caching, since Turborepo leans on those package boundaries.

Because of this, you'll need to use [Root Tasks](/repo/docs/crafting-your-repository/configuring-tasks#registering-root-tasks) if you want to run the tests using Turborepo. Once you've configured [a Vitest Workspace](https://vitest.dev/guide/workspace), create the Root Tasks for Turborepo:

```json title="./turbo.json"
{
"tasks": {
"//#test": {
"outputs": ["coverage/**"]
},
"//#test:watch": {
"cache": false,
"persistent": true
}
}
}
```

**Notably, the file inputs for a Root Task include all packages by default, so any change in any package will result in a cache miss.** While this does make for a simplified configuration to create merged coverage reports, you'll be missing out on opportunities to cache repeated work.
2 changes: 1 addition & 1 deletion examples/with-vite-react/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `Turborepo` Vite starter

This is an official starter Turborepo.
This is a community-maintained example. If you experience a problem, please submit a pull request with a fix. GitHub Issues will be closed.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated. I just happened to notice it and fixed. This example is not core-maintained.


## Using this example

Expand Down
40 changes: 40 additions & 0 deletions examples/with-vitest/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Dependencies
node_modules
.pnp
.pnp.js

# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Testing
coverage

# Turbo
.turbo

# Vercel
.vercel

# Build Outputs
.next/
out/
build
dist


# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Misc
.DS_Store
*.pem

coverage.json
Empty file added examples/with-vitest/.npmrc
Empty file.
45 changes: 45 additions & 0 deletions examples/with-vitest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Turborepo starter

This Turborepo starter is maintained by the Turborepo core team.

## Using this example

This example is based on the `basic` example (`npx create-turbo@latest`) to demonstrate how to use Vitest and get the most out of Turborepo's caching.

For this reason, the only commands in the root package.json are `turbo run test` and `turbo run view-report`.

`turbo run test`: Runs the test in each package using Turborepo.
`turbo run view-report`: Collects coverage from each package and shows it in a merged report.

### Remote Caching

> [!TIP]
> Vercel Remote Cache is free for all plans. Get started today at [vercel.com](https://vercel.com/signup?/signup?utm_source=remote-cache-sdk&utm_campaign=free_remote_cache).

Turborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.

By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup?utm_source=turborepo-examples), then enter the following commands:

```
cd my-turborepo
npx turbo login
```

This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).

Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo:

```
npx turbo link
```

## Useful Links

Learn more about the power of Turborepo:

- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks)
- [Caching](https://turbo.build/repo/docs/core-concepts/caching)
- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching)
- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering)
- [Configuration Options](https://turbo.build/repo/docs/reference/configuration)
- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference)
36 changes: 36 additions & 0 deletions examples/with-vitest/apps/docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# env files (can opt-in for commiting if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions examples/with-vitest/apps/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
Binary file added examples/with-vitest/apps/docs/app/favicon.ico
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading