Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e31ddef
refactor!: separate config resolution from the server creation (#10554)
sheremet-va Jul 7, 2026
06a3ac9
feat: add toggable `injectCjsGlobals` option (#10709)
sheremet-va Jul 8, 2026
494f678
perf: make the Node compile cache opt-in, persist worker caches on te…
sheremet-va Jul 9, 2026
591f4db
perf(browser): stop serving framework sourcemaps in headless runs (#1…
sheremet-va Jul 14, 2026
813b6be
docs: add latitude to sponsors (#10771)
sheremet-va Jul 14, 2026
614cdaa
feat: promote fsModuleCache to a top-level option (#10734)
sheremet-va Jul 20, 2026
d3cf098
docs: update latitude logo (#10802)
sheremet-va Jul 20, 2026
6f468ba
docs: fix styling of logos (#10806)
sheremet-va Jul 21, 2026
7eeb95c
feat(benchmark): add pluggable benchmark provider API (#10799)
GuillaumeLagrange Jul 22, 2026
b417e1f
fix(browser): mock window.print to avoid hanging (fix #7375) (#10798)
aaravjaichand Jul 23, 2026
05d82ab
feat(cli): support -p shorthand for --project (#10826)
sheremet-va Jul 24, 2026
dee42cd
refactor: deduplicate run-level option propagation and document the r…
sheremet-va Jul 24, 2026
3987c94
feat!: inline projects extend the root config by default (#10750)
sheremet-va Jul 27, 2026
22d6e3f
fix(deps): update all non-major dependencies (#9958)
renovate[bot] Jul 28, 2026
ad3a423
chore: add Knip checks (#10847)
sheremet-va Jul 28, 2026
7b67107
chore(deps): update shiki monorepo to v4 (#10625)
renovate[bot] Jul 28, 2026
0098755
feat!: enable mocking Temporal without fake timers (#10757)
fabon-f Jul 29, 2026
eecf58f
feat(types)!: add better promise support in expects and matchers (#8266)
samchungy Jul 29, 2026
af8ee5a
feat!: support nested projects (#10846)
sheremet-va Jul 30, 2026
4b5a646
docs(en): merging all conflicts
docschina-bot Aug 1, 2026
814b631
docs(cn): dissolve the conflict
NoiseFan Aug 2, 2026
637c76e
chore: update dependencies
NoiseFan Aug 2, 2026
41c2534
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 2, 2026
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
28 changes: 20 additions & 8 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ export default ({ mode }: { mode: string }) => {
text: 'globals',
link: '/config/globals',
},
{
text: 'injectCjsGlobals',
link: '/config/injectcjsglobals',
},
{
text: 'environment',
link: '/config/environment',
Expand Down Expand Up @@ -482,6 +486,14 @@ export default ({ mode }: { mode: string }) => {
text: 'cache',
link: '/config/cache',
},
{
text: 'fsModuleCache',
link: '/config/fsmodulecache',
},
{
text: 'fsModuleCachePath',
link: '/config/fsmodulecachepath',
},
{
text: 'sequence',
link: '/config/sequence',
Expand Down Expand Up @@ -634,18 +646,10 @@ export default ({ mode }: { mode: string }) => {
text: 'browser.headless',
link: '/config/browser/headless',
},
{
text: 'browser.isolate',
link: '/config/browser/isolate',
},
{
text: 'browser.testerHtmlPath',
link: '/config/browser/testerhtmlpath',
},
{
text: 'browser.api',
link: '/config/browser/api',
},
{
text: 'browser.provider',
link: '/config/browser/provider',
Expand Down Expand Up @@ -674,6 +678,10 @@ export default ({ mode }: { mode: string }) => {
text: 'browser.screenshotFailures',
link: '/config/browser/screenshotfailures',
},
{
text: 'browser.dependencySourcemaps',
link: '/config/browser/dependencysourcemaps',
},
{
text: 'browser.orchestratorScripts',
link: '/config/browser/orchestratorscripts',
Expand Down Expand Up @@ -1092,6 +1100,10 @@ export default ({ mode }: { mode: string }) => {
text: '自定义运行池',
link: '/guide/advanced/pool',
},
{
text: 'Benchmark Provider',
link: '/guide/advanced/benchmark-provider',
},
],
},
// Migration — one-time transitional content: cross-version
Expand Down
3 changes: 1 addition & 2 deletions .vitepress/scripts/cli-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const skipConfig = new Set([
'project',
'ui',
'browser.name',
'browser.fileParallelism',
'clearCache',
'tagsFilter',
'listTags',
Expand Down Expand Up @@ -86,7 +85,7 @@ const template = options.map((option) => {
const cli = option.cli
const [page, ...hash] = (title.startsWith('browser.') ? title.slice(8) : title).toLowerCase().split('.')
const config = skipConfig.has(title) ? '' : `[${title}](${title.includes('browser.') ? '/config/browser/' : '/config/'}${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''})`
// eslint-disable-next-line e18e/prefer-static-regex

return `### ${title}\n\n- **CLI:** ${cli}\n${config ? `- **Config:** ${config}\n` : ''}\n${option.description.replace(/https:\/\/vitest\.dev\//g, '/')}\n`
}).join('\n')

Expand Down
6 changes: 5 additions & 1 deletion .vitepress/sponsors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ export const sponsors: SponsorTier[] = [
tier: '铂金赞助商',
size: 'big',
items: [

{
name: 'Bolt',
url: 'https://bolt.new',
img: '/bolt.svg',
},
{
name: 'Latitude',
url: 'https://latitude.so/',
img: '/latitude.svg',
},
],
},
{
Expand Down
2 changes: 1 addition & 1 deletion api/advanced/artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The `TestArtifactBase` interface is the base for all test artifacts.
Extend this interface when creating custom test artifacts. Vitest automatically manages the `attachments` array and injects the `location` property to indicate where the artifact was created in your test code.

::: danger
When running with [`api.allowWrite`](/config/api#api-allowwrite) or [`browser.api.allowWrite`](/config/browser/api#api-allowwrite) disabled, Vitest empties the `attachments` array on every artifact before reporting it.
When running with [`api.allowWrite`](/config/api#api-allowwrite) disabled, Vitest empties the `attachments` array on every artifact before reporting it.

If your custom artifact narrows the `attachments` type (e.g. to a tuple), include `| []` in the union so the type reflects what actually happens at runtime.
:::
Expand Down
15 changes: 8 additions & 7 deletions api/advanced/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,15 @@ vitest.config.project.push('my-project-name')
:::

::: tip 引用当前配置
若想在使用我们自己的配置时仍保留用户的原有配置,可以通过设置 extends 属性实现。这样,除了 extends 指定的内容外,其他配置项都会与我们配置合并
内联配置默认继承根配置。如果想改为继承特定的配置文件,请将 `extends` 属性设为该文件的路径。其他所有属性都会与用户定义的配置合并

项目的 `configFile` 可以在 Vite 的配置中访问:`project.vite.config.configFile`。

请注意,这也将继承 `name` - Vitest 不允许多个项目使用相同的名称,因此这将引发错误。请确保我们指定了不同的名称。我们可以通过 `project.name` 属性访问当前名称,并且所有使用的名称都可以在 `vitest.projects` 数组中找到。
请注意,`name` 永远不会被继承,因为 Vitest 不允许多个项目使用相同的名称。请确保每个项目都有唯一的名称。可以通过 `project.name` 属性访问当前名称,所有已使用的名称都可以在 `vitest.projects` 数组中找到。
:::

### experimental_defineCacheKeyGenerator <Version type="experimental">4.0.11</Version> <Experimental /> {#definecachekeygenerator}

### defineCacheKeyGenerator <Version>5.0.0</Version> {#definecachekeygenerator}

```ts
interface CacheKeyIdGeneratorContext {
Expand All @@ -133,7 +134,7 @@ interface CacheKeyIdGeneratorContext {
sourceCode: string
}

function experimental_defineCacheKeyGenerator(
function defineCacheKeyGenerator(
callback: (context: CacheKeyIdGeneratorContext) => string | undefined | null | false
): void
```
Expand All @@ -142,7 +143,7 @@ function experimental_defineCacheKeyGenerator(

如果你的插件支持通过不同的参数选项注册,建议通过这种方式,确保 Vitest 生成正确的哈希值。

仅当定义了 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) 时才会调用此方法。
仅当定义了 [`fsModuleCache`](/config/fsmodulecache) 时才会调用此方法。

```ts
interface PluginOptions {
Expand All @@ -159,8 +160,8 @@ export function plugin(options: PluginOptions) {
options.replacePropertyValue
)
},
configureVitest({ experimental_defineCacheKeyGenerator }) {
experimental_defineCacheKeyGenerator(() => {
configureVitest({ defineCacheKeyGenerator }) {
defineCacheKeyGenerator(() => {
// 由于这些选项会影响转换结果,
// 将它们组合成一个唯一字符串并返回
return options.replacePropertyKey + options.replacePropertyValue
Expand Down
2 changes: 1 addition & 1 deletion api/advanced/vitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ function experimental_parseSpecifications(
function experimental_clearCache(): Promise<void>
```

删除所有 Vitest 缓存,包括 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache)。
删除所有 Vitest 缓存,包括 [`fsModuleCache`](/config/fsmodulecache)。

## experimental_getSourceModuleDiagnostic <Version type="experimental">4.0.15</Version> <Experimental /> {#getsourcemodulediagnostic}

Expand Down
6 changes: 3 additions & 3 deletions api/browser/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ outline: deep
::: tip
出于安全原因,内置的文件命令遵循 Vite 的 [`server.fs`](https://cn.G/config/server-options.html#server-fs-allow) 限制。

`writeFile` 和 `removeFile` 还需要通过 [`browser.api.allowWrite`](/config/browser/api) 和 [`api.allowWrite`](/config/api#api-allowwrite) 获得写入权限。
`writeFile` 和 `removeFile` 还需要通过 [`api.allowWrite`](/config/api#api-allowwrite) 获得写入权限。
:::

```ts
Expand Down Expand Up @@ -60,7 +60,7 @@ expect(input).toHaveValue('a')
::: warning
CDP session 仅适用于 `playwright` provider,并且仅在使用 `chromium` 浏览器时有效。有关详细信息,请参阅 playwright 的 [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession) 文档。

CDP 是一个特权调试 API。仅当通过 [`browser.api.allowWrite`](/config/browser/api#api-allowwrite)、[`browser.api.allowExec`](/config/browser/api#api-allowexec)、[`api.allowWrite`](/config/api#api-allowwrite) 和 [`api.allowExec`](/config/api#api-allowexec) 启用浏览器 API 写入和执行操作时,该 API 才可用
CDP 是一种特权调试 API。仅当通过 [`api.allowWrite`](/config/api#api-allowwrite), and [`api.allowExec`](/config/api#api-allowexec) 启用浏览器 API 的写入及执行操作时,才可使用 CDP
:::

## 自定义命令 {#custom-commands}
Expand Down Expand Up @@ -132,7 +132,7 @@ Custom commands run in the Vitest Node process and are callable from browser tes

Vitest's built-in file commands validate paths against Vite's [`server.fs`](https://vite.dev/config/server-options#server-fs-allow) restrictions and separately check whether writes are allowed. Custom commands do not automatically inherit these protections. If a custom command accepts browser-provided input and uses it to read, write, delete, execute, or expose local resources, validate that input before using it.

For file reads or fixture loading, use `isFileLoadingAllowed` from `vitest/node` or an explicit allowlist. For writes and deletes, also require an explicit mutation policy, such as [`browser.api.allowWrite`](/config/browser/api#api-allowwrite), [`api.allowWrite`](/config/api#api-allowwrite), and a command-specific allowed directory. For commands that execute code, shell commands, or project scripts, also check [`browser.api.allowExec`](/config/browser/api#api-allowexec) and [`api.allowExec`](/config/api#api-allowexec).
For file reads or fixture loading, use `isFileLoadingAllowed` from `vitest/node` or an explicit allowlist. For writes and deletes, also require an explicit mutation policy, such as [`api.allowWrite`](/config/api#api-allowwrite), and a command-specific allowed directory. For commands that execute code, shell commands, or project scripts, also check [`api.allowExec`](/config/api#api-allowexec).

For example, if you create your own file-writing command instead of using Vitest's built-in `writeFile`, apply the same checks:

Expand Down
2 changes: 1 addition & 1 deletion api/browser/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ await expect.element(button).toBeVisible() // 查询元素失败 ❌
::: warning
CDP 会话仅适用于 `playwright` provider,并且仅在使用 `chromium` 浏览器时有效。有关详细信息,请参阅 playwright 的 [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession)文档。

CDP 是一个特权调试 API。仅当通过 [`browser.api.allowWrite`](/config/browser/api#api-allowwrite)、[`browser.api.allowExec`](/config/browser/api#api-allowexec)、[`api.allowWrite`](/config/api#api-allowwrite) 和 [`api.allowExec`](/config/api#api-allowexec) 启用浏览器 API 写入和执行操作时,该 API 才可用
CDP 是一种特权调试 API。仅当通过 [`api.allowWrite`](/config/api#api-allowwrite), and [`api.allowExec`](/config/api#api-allowexec) 启用浏览器 API 的写入及执行操作时,才可使用 CDP
:::

```ts
Expand Down
31 changes: 17 additions & 14 deletions api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ type Awaitable<T> = T | PromiseLike<T>
`expect` 用于创建断言。在此上下文中,`断言` 是可以被调用来验证一个语句的函数。Vitest 默认提供 `chai` 断言,同时也提供基于 chai 构建的兼容 `Jest` 的断言。自 Vitest 4.1 起,在进行 spy/mock 测试时,Vitest 还额外提供了 Chai 风格断言(如 [`expect(spy).to.have.been.called()`](#called)),与 Jest 风格断言(如 `expect(spy).toHaveBeenCalled()`)并存。与 `Jest` 不同,Vitest 支持将一条消息作为第二个参数传入,如果断言失败,错误信息将等于该消息。

```ts
export interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining {
<T>(actual: T, message?: string): Assertion<T>
export interface ExpectStatic
extends Chai.ExpectStatic,
Matchers<any>,
AsymmetricMatchersContaining {
<T>(actual: T, message?: string): Assertion<void, T>
extend: (expects: MatchersObject) => void
anything: () => any
any: (constructor: unknown) => any
Expand Down Expand Up @@ -2238,12 +2241,11 @@ import { expect, test } from 'vitest'

test('custom matchers', () => {
expect.extend({
toBeFoo: (received, expected) => {
if (received !== 'foo') {
return {
message: () => `expected ${received} to be foo`,
pass: false,
}
toBeFoo(received) {
const { isNot } = this
return {
message: () => `expected ${received} is${isNot ? ' not' : ''} foo`,
pass: received === 'foo',
}
},
})
Expand All @@ -2259,19 +2261,20 @@ test('custom matchers', () => {

这个函数与 Jest 的 `expect.extend` 兼容,因此任何使用它来创建自定义匹配器的库都可以与 Vitest 一起使用。

如果正在使用 TypeScript,自从 Vitest 0.31.0 版本以来,我们可以在环境声明文件(例如:`vitest.d.ts`)中使用下面的代码扩展默认的 `Assertion` 接口:
如果正在使用 TypeScript,我们可以在环境声明文件(例如:`vitest.d.ts`)中使用下面的代码扩展默认的 `Matchers` 接口:

```ts
interface CustomMatchers<R = unknown> {
toBeFoo: () => R
}
import 'vitest'

declare module 'vitest' {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
interface Matchers<R, T> {
toBeFoo: () => R
}
}
```

`R` is the assertion return type, and `T` is the type of the received value.

::: warning
不要忘记在 `tsconfig.json` 中包含环境声明文件。
:::
Expand Down
2 changes: 1 addition & 1 deletion api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ await vi.runOnlyPendingTimersAsync()
function setSystemTime(date: string | number | Date): Vitest
```

如果启用了伪计时器,此方法将模拟用户更改系统时钟(将影响与日期相关的 API,如 `hrtime` 、`performance.now` 或 `new Date()` ),但不会触发任何计时器。如果未启用假定时器,该方法将仅模拟 `Date.*` 调用。
如果启用了伪计时器,此方法将模拟用户更改系统时钟(将影响与日期相关的 API,如 `hrtime` 、`performance.now` 或 `new Date()` ),但不会触发任何计时器。如果未启用假定时器,该方法将仅模拟 `Date.*` 和 `Temporal.Now.*` 调用。

适用于需要测试依赖当前日期的场景,例如代码中的 [Luxon](https://github.com/moment/luxon/) 库调用。

Expand Down
3 changes: 1 addition & 2 deletions blog/vitest-3-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Vitest 现在有一个 `Matchers` 类型,你可以扩展它来在一个地方

例如,要拥有一个类型安全的 `toBeFoo` 匹配器,你可以这样写:

```ts twoslash
```ts
import { expect } from 'vitest'

interface CustomMatchers<R = unknown> {
Expand All @@ -252,7 +252,6 @@ declare module 'vitest' {

expect.extend({
toBeFoo(actual, arg) {
// ^?
// 具体实现...
return {
pass: true,
Expand Down
8 changes: 6 additions & 2 deletions config/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ outline: deep
- **默认值:** `false`
- **命令行终端:** `--api`, `--api.port`, `--api.host`, `--api.strictPort`

监听端口并提供 API 服务,用于 [UI 模式](/guide/ui) 或 [浏览器服务](/guide/browser/)。设为 `true` 时,默认端口为 `51204`。
监听端口并提供 API 服务,用于 [UI 模式](/guide/ui) 或 [浏览器服务](/guide/browser/)。设为 `true` 时,默认端口为 `51204`,如果在浏览器模式下运行,则为 `63315`

## api.allowWrite <Version>4.1.0</Version> {#api-allowwrite}

Expand All @@ -18,6 +18,10 @@ outline: deep

Vitest 服务器可以通过 API 保存测试文件或快照文件。这意味着任何能连接到 API 的人都可以在你的机器上运行任意代码。

<!-- TODO: translation -->

In Browser Mode Vitest saves [annotation attachments](/guide/test-annotations), [artifacts](/api/advanced/artifacts) and [snapshots](/guide/snapshot) by receiving a WebSocket connection from the browser. This allows anyone who can connect to the API write any arbitrary code on your machine within the root of your project (configured by [`fs.allow`](https://vite.dev/config/server-options#server-fs-allow)). This option also gates privileged browser APIs that can write files indirectly, such as raw Chrome DevTools Protocol access through [`cdp()`](/api/browser/context#cdp).

::: danger 安全警告
Vitest 默认不会将 API 暴露到互联网,仅在 `localhost` 上监听。但如果 `host` 被手动暴露到网络,任何连接到它的人都可以在你的机器上运行任意代码,除非将 `api.allowWrite` 和 `api.allowExec` 设置为`false`。

Expand All @@ -29,4 +33,4 @@ Vitest 默认不会将 API 暴露到互联网,仅在 `localhost` 上监听。
- **类型:** `boolean`
- **默认值:** `true` 表示未暴露在公共网络中,`false` 则表示已暴露

允许通过 API 运行任何测试文件。详细安全建议请参阅 [`api.allowWrite`](#api-allowwrite)。
允许通过 API 运行任何测试文件。 This applies to the interactive elements (and the server code behind them) in the [UI](/guide/ui) that can run the code. This option also gates privileged browser APIs that can execute code indirectly, such as raw Chrome DevTools Protocol access through [`cdp()`](/api/browser/context#cdp).
9 changes: 8 additions & 1 deletion config/benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,18 @@ Enables the benchmark project. When set, Vitest creates a dedicated benchmark pr

Include the `samples` array of per-iteration timings on every benchmark result. Disabled by default to reduce memory usage; enable when a custom reporter or API consumer needs the raw samples.

## benchmark.provider

- **Type:** `string`
- **Default:** `undefined` (uses the built-in provider)

The benchmark provider that executes registered benchmarks and returns their results. Set this to a module path whose default export implements `BenchmarkProvider`. Relative paths are resolved from the project root.

See the [Custom Benchmark Provider](/guide/advanced/benchmark-provider) guide for setup instructions and the provider API.

## benchmark.suppressExportGetterWarnings

- **Type:** `boolean`
- **Default:** `false`

Suppress the warning printed when a benchmark accesses module export getters too many times. Vitest tracks getter access during benchmark runs because Vite's module runner wraps every export in a getter, and excessive access can dominate the measurement (see [Module Runner Overhead](/guide/benchmarking#module-runner-overhead)). Enable this when you've intentionally accepted the overhead, or when the warning is noisy for benchmarks where the getter cost is negligible.

Loading
Loading