Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
47f758c
perf(experimental): add file system cache
sheremet-va Nov 13, 2025
5748d96
chore: fix cache key
sheremet-va Nov 14, 2025
d026fbe
refactor: use a class for easier management
sheremet-va Nov 14, 2025
e556995
chore: early cache check
sheremet-va Nov 14, 2025
87cf020
chore: move fs to project
sheremet-va Nov 14, 2025
eb86964
chore: rename file
sheremet-va Nov 14, 2025
bcd9193
perf: don't read multiple times, respect project-level cacheFs
sheremet-va Nov 14, 2025
2d845ea
chore: enable caching via the experimental flag
sheremet-va Nov 14, 2025
f9fb30d
chore: inherit fsModuleCache
sheremet-va Nov 14, 2025
6060ce9
chore: cleanup
sheremet-va Nov 14, 2025
d44708c
feat: add --clearCache
sheremet-va Nov 14, 2025
bd0ef35
chore: cleanup
sheremet-va Nov 14, 2025
45f16c8
docs: add section about the public method
sheremet-va Nov 14, 2025
365e1cb
Merge branch 'main' of github.com:vitest-dev/vitest into perf/add-fs-…
sheremet-va Nov 17, 2025
96e2003
fix: return traces to fetchModule
sheremet-va Nov 17, 2025
cea30f8
perf: use hash function instead
sheremet-va Nov 17, 2025
7e58c0a
docs: fix links
sheremet-va Nov 17, 2025
9af8f8c
test: validate the option is inherited
sheremet-va Nov 17, 2025
3b61a13
fix: don't read virtual file, read tmp in server runner
sheremet-va Nov 17, 2025
6b69f28
cI: add a step to ci
sheremet-va Nov 17, 2025
5a38b08
feat: add fsModuleCachePath
sheremet-va Nov 17, 2025
d345717
ci: run ci:cache
sheremet-va Nov 17, 2025
c771a4f
feat(cache): support watch mode
sheremet-va Nov 17, 2025
5dd1423
chore: just use strings
sheremet-va Nov 17, 2025
270d9c6
perf: keep the id in memory
sheremet-va Nov 17, 2025
c473ecb
chore: run cached tests also on windows
sheremet-va Nov 18, 2025
5e3bdc4
fix: check coverage transform
sheremet-va Nov 18, 2025
1983f44
feat: add fsModuleCacheKeyGenerator
sheremet-va Nov 18, 2025
eefd22b
fix: remove sourceMap.mappings
sheremet-va Nov 18, 2025
4d1a0a5
chore: add debug
sheremet-va Nov 18, 2025
53c481d
chore: keep mappings information
sheremet-va Nov 18, 2025
961ed42
chore: remove test-dts-config
sheremet-va Nov 18, 2025
5162485
chore: ignore all dts tests
sheremet-va Nov 18, 2025
a7cc69f
chore: ignore ui tests
sheremet-va Nov 18, 2025
f10869e
feat: introduce `defineCacheKeyGenerator`
sheremet-va Nov 18, 2025
fcbed42
docs: update versions and links
sheremet-va Nov 18, 2025
a3577d0
docs: cleanup
sheremet-va Nov 18, 2025
310a64d
chore: update debug messages
sheremet-va Nov 18, 2025
dbde0ce
refactor: rename fsCache to fsModuelCache
sheremet-va Nov 19, 2025
c4b210b
refactor: cache environment configs
sheremet-va Nov 19, 2025
570da82
refactor: provide context to defineCacheKeyGenerator
sheremet-va Nov 19, 2025
8ff2cd9
chore: cleanup
sheremet-va Nov 19, 2025
217a123
fix: nuke cache if lockfile changes
sheremet-va Nov 19, 2025
1547588
test: add defineCacheKey test
sheremet-va Nov 19, 2025
d4a5450
chore: lockfile
sheremet-va Nov 19, 2025
d870c04
chore: cleanup
sheremet-va Nov 19, 2025
b7ed675
test: specify cache path to avoid clearing global cache
sheremet-va Nov 19, 2025
dc20427
chore: hash config file dependencies
sheremet-va Nov 19, 2025
f3f126a
chore: cleanup
sheremet-va Nov 19, 2025
4c41971
chore: fix log
sheremet-va Nov 19, 2025
7f014ad
Merge branch 'main' of github.com:vitest-dev/vitest into perf/add-fs-…
sheremet-va Nov 19, 2025
be56ac9
Merge branch 'main' of github.com:vitest-dev/vitest into perf/add-fs-…
sheremet-va Nov 19, 2025
aba901a
feat: allow bailing out of caching in the generator
sheremet-va Nov 20, 2025
16ffcbc
test: add more tests
sheremet-va Nov 20, 2025
0bba4cf
docs: add known issues section
sheremet-va Nov 20, 2025
ff5cce4
chore: remove log
sheremet-va Nov 20, 2025
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
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,42 @@ jobs:
path: test/ui/test-results/
retention-days: 30

test-cached:
needs: changed
name: 'Cache&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}'
if: needs.changed.outputs.should_skip != 'true'
runs-on: ${{ matrix.os }}

timeout-minutes: 30

strategy:
matrix:
node_version: [24]
os:
- macos-latest
- windows-latest
fail-fast: false

steps:
- uses: actions/checkout@v5

- uses: ./.github/actions/setup-and-cache
with:
node-version: ${{ matrix.node_version }}

- uses: browser-actions/setup-chrome@b94431e051d1c52dcbe9a7092a4f10f827795416 # v2.1.0

- name: Install
run: pnpm i

- uses: ./.github/actions/setup-playwright

- name: Build
run: pnpm run build

- name: Test
run: pnpm run test:ci:cache

test-browser:
needs: changed
name: 'Browsers: node-${{ matrix.node_version }}, ${{ matrix.os }}'
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/scripts/cli-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const skipConfig = new Set([
'ui',
'browser.name',
'browser.fileParallelism',
'clearCache',
])

function resolveOptions(options: CLIOptions<any>, parentName?: string) {
Expand Down
44 changes: 44 additions & 0 deletions docs/api/advanced/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,47 @@ The project's `configFile` can be accessed in Vite's config: `project.vite.confi

Note that this will also inherit the `name` - Vitest doesn't allow multiple projects with the same name, so this will throw an error. Make sure you specified a different name. You can access the current name via the `project.name` property and all used names are available in the `vitest.projects` array.
:::

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

```ts
function experimental_defineCacheKeyGenerator(
callback: (
environment: DevEnvironment,
id: string,
sourceCode: string,
) => string | undefined | null
): void
```

Define a generator that will be applied before hashing the cache key.

Use this to make sure Vitest generates correct hash. It is a good idea to define this function if your plugin can be registered with different options.

This is called only if [`experimental.fsModuleCache`](/config/experimental#fsmodulecache) is defined.

```ts
interface PluginOptions {
replacePropertyKey: string
replacePropertyValue: string
}

export function plugin(options: PluginOptions) {
return {
name: 'plugin-that-replaces-property',
transform(code) {
return code.replace(
options.replacePropertyKey,
options.replacePropertyValue
)
},
configureVitest({ experimental_defineCacheKeyGenerator }) {
experimental_defineCacheKeyGenerator(() => {
// since these options affect the transform result,
// return them together as a unique string
return options.replacePropertyKey + options.replacePropertyValue
})
}
}
}
```
8 changes: 8 additions & 0 deletions docs/api/advanced/vitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,3 +607,11 @@ function experimental_parseSpecifications(
```

This method will [collect tests](#parsespecification) from an array of specifications. By default, Vitest will run only `os.availableParallelism()` number of specifications at a time to reduce the potential performance degradation. You can specify a different number in a second argument.

## experimental_clearCache <Version type="experimental">4.0.11</Version> <Badge type="warning">experimental</Badge> {#clearcache}

```ts
function experimental_clearCache(): Promise<void>
```

Deletes all Vitest caches, including [`experimental.fsModuleCache`](/config/experimental#fsmodulecache).
26 changes: 25 additions & 1 deletion docs/config/experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,31 @@ outline: deep

# experimental

## openTelemetry <Version type="experimental">4.0.10</Version>
## experimental.fsModuleCache <Version type="experimental">4.0.11</Version> {#experimental-fsmodulecache}

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

Enabling this option allows Vitest to keep cached modules on the file system, making tests run faster between reruns.

You can delete the old cache by running [`vitest --clearCache`](/guide/cli#clearcache).

::: warning BROWSER SUPPORT
At the moment, this option does not affect [the browser](/guide/browser/).
:::

::: danger ADVANCED
If you are a plugin author, consider defining a [cache key generator](/api/advanced/plugin#definecachekeygenerator) if your plugin can be registered with different options that affect the transform result.
:::

## experimental.fsModuleCachePath <Version type="experimental">4.0.11</Version> {#experimental-fsmodulecachepath}

- **Type:** `string`
- **Default:** `join(tmpdir(), 'vitest')`

Directory where the file system cache is located.

## experimental.openTelemetry <Version type="experimental">4.0.11</Version> {#experimental-opentelemetry}

- **Type:**

Expand Down
22 changes: 0 additions & 22 deletions docs/config/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,25 +71,3 @@ If a `RegExp` is provided, it is matched against the full file path.
When a dependency is a valid ESM package, try to guess the cjs version based on the path. This might be helpful, if a dependency has the wrong ESM file.

This might potentially cause some misalignment if a package has different logic in ESM and CJS mode.

## debug

### dump

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

The folder where Vitest stores the contents of inlined test files that can be inspected manually.

If set to `true`, Vitest dumps the files inside the `.vitest-dump` folder relative to the root of the project.

You can also use `VITEST_DEBUG_DUMP` env variable to enable this conditionally.

### load

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

Read files from the dump instead of transforming them. If dump is disabled, this does nothing.

You can also use `VITEST_DEBUG_LOAD_DUMP` env variable to enable this conditionally.
13 changes: 13 additions & 0 deletions docs/guide/cli-generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -798,3 +798,16 @@ Use `bundle` to bundle the config with esbuild or `runner` (experimental) to pro
- **CLI:** `--standalone`

Start Vitest without running tests. Tests will be running only on change. This option is ignored when CLI file filters are passed. (default: `false`)

### clearCache

- **CLI:** `--clearCache`

Delete all Vitest caches, including `experimental.fsModuleCache`, without running any tests. This will reduce the performance in the subsequent test run.

### experimental.fsModuleCache

- **CLI:** `--experimental.fsModuleCache`
- **Config:** [experimental.fsModuleCache](/config/experimental#experimental-fsmodulecache)

Enable caching of modules on the file system between reruns.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"release": "tsx scripts/release.ts",
"test": "pnpm --filter test-core test:threads",
"test:ci": "CI=true pnpm -r --reporter-hide-prefix --stream --sequential --filter '@vitest/test-*' --filter !test-browser run test",
"test:ci:cache": "CI=true pnpm -r --reporter-hide-prefix --stream --sequential --filter '@vitest/test-*' --filter !test-browser --filter !test-dts-config --filter !test-dts-fixture --filter !test-dts-playwright --filter !test-ui run test --experimental.fsModuleCache",
"test:examples": "CI=true pnpm -r --reporter-hide-prefix --stream --filter '@vitest/example-*' run test",
"test:ecosystem-ci": "ECOSYSTEM_CI=true pnpm test:ci",
"typebuild": "tsx ./scripts/explain-types.ts",
Expand Down
15 changes: 13 additions & 2 deletions packages/coverage-istanbul/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,26 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider<ResolvedCover
})
}

onFileTransform(sourceCode: string, id: string, pluginCtx: any): { code: string; map: any } | undefined {
requiresTransform(id: string): boolean {
// Istanbul/babel cannot instrument CSS - e.g. Vue imports end up here.
// File extension itself is .vue, but it contains CSS.
// e.g. "Example.vue?vue&type=style&index=0&scoped=f7f04e08&lang.css"
if (isCSSRequest(id)) {
return
return false
}

if (!this.isIncluded(removeQueryParameters(id))) {
return false
}

return true
}

onFileTransform(sourceCode: string, id: string, pluginCtx: Vite.Rollup.TransformPluginContext): { code: string; map: any } | undefined {
// Istanbul/babel cannot instrument CSS - e.g. Vue imports end up here.
// File extension itself is .vue, but it contains CSS.
// e.g. "Example.vue?vue&type=style&index=0&scoped=f7f04e08&lang.css"
if (!this.requiresTransform(id)) {
return
}

Expand Down
Loading
Loading