Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
47ea29e
docs: add CI task cache guide
wan9chi Jun 29, 2026
cf3521d
docs: clarify tool-reported caching
wan9chi Jun 29, 2026
f064d97
docs: add tool-reported caching guide
wan9chi Jun 30, 2026
d4cdbed
docs: remove redundant setup-vp cache flag
wan9chi Jun 30, 2026
d079abd
docs: unify automatic tracking guidance
wan9chi Jun 30, 2026
7d00536
docs: simplify task cache wording
wan9chi Jun 30, 2026
dc1a1c8
docs: refine automatic tracking wording
wan9chi Jun 30, 2026
d96cdc7
docs: remove redundant tracking link
wan9chi Jun 30, 2026
4f48e8a
docs: pair input and output tracking guidance
wan9chi Jun 30, 2026
740721c
docs: simplify automatic tracking wording
wan9chi Jun 30, 2026
5032d40
docs: clarify automatic tracking cache behavior
wan9chi Jun 30, 2026
b4231bb
docs: add file tracking limitations
wan9chi Jun 30, 2026
be55b53
docs: mention env read tracking limit
wan9chi Jun 30, 2026
6fa8d5a
docs: clarify automatic tracking limits
wan9chi Jun 30, 2026
a26deb3
docs: clarify cooperative tracking support
wan9chi Jun 30, 2026
9282234
docs: clarify vp build cooperative tracking
wan9chi Jun 30, 2026
5762ee6
docs: clarify vp build manual tracking needs
wan9chi Jun 30, 2026
f7281d7
docs: show simple vp build tracking config
wan9chi Jun 30, 2026
55acbcd
docs: refine automatic tracking limitations
wan9chi Jun 30, 2026
305473a
docs: simplify vp build tracking note
wan9chi Jun 30, 2026
89ec54e
docs: clarify input and output overrides
wan9chi Jun 30, 2026
04420e6
docs: rework cooperative tracking section
wan9chi Jun 30, 2026
e12c785
docs: refine cooperative tracking guidance
wan9chi Jun 30, 2026
924850e
docs: refine vp build task wording
wan9chi Jun 30, 2026
7094f86
docs: remove cache miss section from tracking guide
wan9chi Jun 30, 2026
1b7c0bf
docs: simplify manual tracking config table
wan9chi Jun 30, 2026
e52e259
docs: add file tracking disable case
wan9chi Jun 30, 2026
493941d
docs: format automatic tracking records
wan9chi Jun 30, 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
8 changes: 8 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ const taskRunnerGuideItems = [
text: 'Task Caching',
link: '/guide/cache',
},
{
text: 'Automatic Tracking',
link: '/guide/automatic-tracking',
},
{
text: 'GitHub Actions Cache',
link: '/guide/github-actions-cache',
},
{
text: 'Running Binaries',
link: '/guide/vpx',
Expand Down
71 changes: 59 additions & 12 deletions docs/config/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ Commands joined with `&&` (or supplied as an array) are automatically split into

### `dependsOn`

- **Type:** `string[]`
- **Type:** `Array<string | { task: string, from: DependsOnFrom }>`
- **Default:** `[]`

`DependsOnFrom` accepts `"dependencies"`, `"devDependencies"`, `"peerDependencies"`, or an array of those values.

Tasks that must complete successfully before this one starts.

```ts [vite.config.ts]
Expand All @@ -140,6 +142,19 @@ Dependencies can reference tasks in other packages using the `package#task` form
dependsOn: ['@my/core#build', '@my/utils#lint'];
```

Use the object form `{ task: string, from: DependsOnFrom }` to reference tasks from all dependencies:

```ts [vite.config.ts]
tasks: {
test: {
command: 'vp test',
dependsOn: [{ task: 'build', from: ['dependencies', 'devDependencies'] }],
},
}
```

For the example above, Vite Task reads the declaring package's direct `dependencies` and `devDependencies`, and runs `build` task in each dependency if it defines one. Packages without `build` are skipped.

See [Task Dependencies](/guide/run#task-dependencies) for details on how explicit and topological dependencies interact.

### `cache`
Expand Down Expand Up @@ -168,17 +183,19 @@ Environment variables included in the cache fingerprint. When any listed variabl
```ts [vite.config.ts]
tasks: {
build: {
command: 'vp build',
command: 'node build.mjs',
env: ['NODE_ENV'],
},
}
```

Wildcard patterns are supported: `VITE_*` matches all variables starting with `VITE_`.
Wildcard patterns and `!` exclusion patterns are supported: `VITE_*` matches all variables starting with `VITE_`, and `!VITE_SECRET` excludes the `VITE_SECRET` variable from the match.

For `vp build`, Vite reports Vite environment variables through [automatic tracking](/guide/automatic-tracking#cooperative-tracking). Do not add `VITE_*` or `NODE_ENV` here for a standard Vite build unless your project has extra build behavior Vite cannot report.

```bash
$ NODE_ENV=development vp run build # first run
$ NODE_ENV=production vp run build # cache miss: variable changed
$ NODE_ENV=production vp run build # cache miss: env 'NODE_ENV' changed
```

### `untrackedEnv`
Expand All @@ -191,13 +208,17 @@ Environment variables passed to the task process but **not** included in the cac
```ts [vite.config.ts]
tasks: {
build: {
command: 'vp build',
command: 'node build.mjs',
untrackedEnv: ['CI', 'GITHUB_ACTIONS'],
},
}
```

A set of common environment variables are automatically passed through to all tasks:
`untrackedEnv` accepts the same wildcard and `!` exclusion patterns as [`env`](#env).

Do not put a variable in `untrackedEnv` if its value changes the task result. If a cache-reporting tool covers the variable through [automatic tracking](/guide/automatic-tracking#cooperative-tracking), leave it out of both `env` and `untrackedEnv`.

Vite Task passes a set of common environment variables to all tasks:

- **System:** `HOME`, `USER`, `PATH`, `SHELL`, `LANG`, `TZ`
- **Node.js:** `NODE_OPTIONS`, `COREPACK_HOME`, `PNPM_HOME`
Expand All @@ -209,7 +230,7 @@ A set of common environment variables are automatically passed through to all ta
- **Type:** `Array<string | { auto: boolean } | { pattern: string, base: "workspace" | "package" }>`
- **Default:** `[{ auto: true }]` (auto-inferred)

Vite Task automatically detects which files are used by a command (see [Automatic File Tracking](/guide/cache#automatic-file-tracking)). The `input` option can be used to explicitly include or exclude certain files.
Vite Task automatically detects which files a command uses. See [Automatic Tracking](/guide/automatic-tracking) for the details and when to add manual config.

**Exclude files** from automatic tracking:

Expand Down Expand Up @@ -270,26 +291,39 @@ String glob patterns are resolved relative to the package directory by default.

### `output`

- **Type:** `Array<string | { pattern: string, base: "workspace" | "package" }>`
- **Default:** `[]` (nothing is archived)
- **Type:** `Array<string | { auto: boolean } | { pattern: string, base: "workspace" | "package" }>`
- **Default:** automatic write tracking

Files Vite Task archives after a successful run and restores on a cache hit.

Files the task produces. They get archived after a successful run and restored on a cache hit, so you don't have to rebuild them. Leave it empty (or omit it) and nothing is archived.
If you omit `output`, Vite Task tracks files that the task writes and restores those files on cache hits. Use explicit output entries when you need to override the tracked files.

```ts [vite.config.ts]
tasks: {
build: {
command: 'vp build',
command: 'node build.mjs',
output: ['dist/**', '!dist/cache/**'],
},
}
```

Use `{ auto: true }` to keep automatic write tracking while adding explicit output globs:

```ts [vite.config.ts]
tasks: {
build: {
command: 'node build.mjs',
output: [{ auto: true }, 'storybook-static/**'],
},
}
```

If a task writes outside its own package, use the object form with `base: "workspace"`:

```ts [vite.config.ts]
tasks: {
build: {
command: 'vp build',
command: 'node build.mjs',
output: [
'dist/**',
{ pattern: 'shared-artifacts/**', base: 'workspace' },
Expand All @@ -298,6 +332,19 @@ tasks: {
}
```

Set `output: []` to disable output restoration for a cached task:

```ts [vite.config.ts]
tasks: {
report: {
command: 'node scripts/report.mjs',
output: [],
},
}
```

Vite Task still replays terminal output for that task on cache hits.

### `cwd`

- **Type:** `string`
Expand Down
152 changes: 152 additions & 0 deletions docs/guide/automatic-tracking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Automatic Tracking

Automatic tracking is how Vite Task learns what to cache for a task without explicit configurations. When you run a cache-enabled task, Vite Task observes the task's execution and records what files were read and written, as well as any metadata reported by the task. On the next run, Vite Task decides whether the cache misses or hits based on the recorded fingerprint.

Use this page when you need to understand why a task hits or misses the cache, or when you need to decide whether to add `input`, `output`, `env`, or `untrackedEnv` config.

## Tracking Tiers

Automatic tracking has two tiers:

| Tier | Applies to | Records |
| -------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| File system tracking | All tasks with cache enabled | <ul><li>Files read by the command</li><li>Missing-file probes</li><li>Directory listings</li><li>Written output files</li></ul> |
| Cooperative tracking | Cache-reporting tools (`vp build` today) | <ul><li>Environment variables reported by the tool</li><li>Tool-managed paths that should not be inputs or outputs, such as `node_modules/.vite-temp`</li></ul> |

Vite Task starts with file system tracking for any command. A cache-reporting tool can add information that only the tool knows while it runs.

## File System Tracking

File system tracking applies to every task to be cached. If you omit [`input`](/config/run#input), Vite Task tracks the files a command reads while it runs:

```ts [vite.config.ts]
import { defineConfig } from 'vite-plus';

export default defineConfig({
run: {
tasks: {
build: {
command: 'tsc',
},
},
},
});
```

For this task, Vite Task records source files, config files, missing files the command checked, and directories the command scanned. A later run misses the cache when one of those tracked inputs changes.

File system tracking also tracks outputs. If you omit [`output`](/config/run#output), Vite Task archives files the command writes after a successful run and restores them on a cache hit.

### Limitations

File system tracking records file access, not every value a process reads. It cannot correctly track environment variable reads, and it cannot always tell which paths are stable inputs, generated outputs, or tool-managed state.

Use [Override Inputs And Outputs](#override-inputs-and-outputs) when automatic file tracking includes files that should not affect the cache, misses files that should, or restores the wrong outputs. Common cases include generated files and directory scans with unrelated files.

Use [`env`](/config/run#env) when an environment variable changes a command's result.

These limitations do not apply to `vp build`: Vite reports [Cooperative Tracking](#cooperative-tracking) metadata automatically, including `VITE_*`, `NODE_ENV`, and tool-managed cache paths that should not become inputs or outputs. A standard `vp build` task does not need manual `input`, `output`, or `env`:

```ts [vite.config.ts]
tasks: {
build: 'vp build',
}
```

### Override Inputs And Outputs

- [`input`](/config/run#input) controls what invalidates the cache.
- [`output`](/config/run#output) controls which files Vite Task restores on a cache hit.

Both options accept the same kinds of entries and can be configured separately. Omit an option to keep automatic tracking for it. Add `{ auto: true }` to keep automatic tracking while adding glob rules. Use string globs to include paths and `!` globs to exclude paths. Use `[]` to replace automatic tracking with an empty list.

```ts [vite.config.ts]
tasks: {
build: {
command: 'node build.mjs',
input: [{ auto: true }, '!dist', '!dist/**'],
output: ['dist/**'],
},
}
```

Use explicit `input` globs only when you can name the command's full, stable input set. This lint task overrides inputs only, so output tracking stays automatic:

```ts [vite.config.ts]
tasks: {
lint: {
command: 'vp lint',
input: ['package.json', 'pnpm-lock.yaml', 'src/**', 'tsconfig*.json'],
},
}
```

Use explicit `output` globs when you want to narrow or extend the files Vite Task restores:

```ts [vite.config.ts]
tasks: {
build: {
command: 'node build.mjs',
input: [{ auto: true }, '!dist', '!dist/**'],
output: ['dist/**'],
},
}
```

Set `input: []` when no files should affect the cache key. Set `output: []` when no files should be restored on a cache hit.

## Cooperative Tracking

File system tracking sees access. It cannot always see intent.

`vp build` knows more about a Vite build than Vite Task can infer from file access. When `vp build` runs with cache enabled, Vite reports that metadata to Vite Task. Vite Task merges the report with file system tracking to build a more accurate cache fingerprint.

For a standard Vite build, you do not need to add these entries yourself:

- `env: ['VITE_*']` or `env: ['NODE_ENV']`
- `output: ['dist/**']`
- input or output rules for temporary paths like `node_modules/.vite-temp`

You only need to define the task with `vp build`:

```ts [vite.config.ts]
import { defineConfig } from 'vite-plus';

export default defineConfig({
run: {
tasks: {
build: 'vp build',
},
},
});
```

Manual config still wins. Add `input`, `output`, or `env` when your project has behavior that Vite cannot know.

Vite+ supports cooperative tracking for `vp build` today. It will extend this support to more first-party tools in the future. Third-party tools can report cache metadata with [`@voidzero-dev/vite-task-client`](https://npmx.dev/package/@voidzero-dev/vite-task-client).

## When To Add Manual Config

Add config when your project has behavior the command or tool cannot know.

| Case | Config |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Exclude an output directory from inputs | `input: [{ auto: true }, '!dist', '!dist/**']` |
| Exclude a temporary generated file from input and output tracking | `input: [{ auto: true }, '!.tmp/config.mjs']`<br>`output: [{ auto: true }, '!.tmp/config.mjs']` |
| Disable file tracking when it changes command behavior | `input: []` |
| Track an env var used by a non-cooperative command | `env: ['NODE_ENV']` |
| Pass an env var without fingerprinting it | `untrackedEnv: ['GITHUB_ACTIONS']` |

For CI builds, keep automatic tracking for `vp build` and add only the extra project facts CI needs:

```ts [vite.config.ts]
tasks: {
'ci-build': {
command: 'vp build',
input: [{ auto: true }, 'pnpm-lock.yaml', '!dist', '!dist/**'],
output: ['dist/**'],
},
}
```

This task keeps file system tracking, lets Vite report build metadata, adds the lockfile to the fingerprint, excludes restored output files from inputs, and restores only `dist/**` on a cache hit.
Loading
Loading