Skip to content

Commit fef1237

Browse files
wan9chiclaude
andcommitted
test(cache): real-vite integration fixtures + playground
Adds the real-vite e2e coverage: `vite_build_cache` exercises runner-aware cache behaviour through `vite build` against the companion vite PR (NODE_ENV-change invalidation, `envPrefix`-driven tracked-env set, `dist/` write restoration on cache hit), and `vite_dev_disable_cache` verifies `disableCache()` short-circuits the dev server's run from the cache. Wires the rest of the consumer-side bits needed for vite (consumed via the `github:` spec for vite-task-client) to install cleanly: - Adds `vite: catalog:` to `packages/tools/package.json` so `pnpm install` materialises `packages/tools/node_modules/.bin/vite` for the harness's `link_tools_packages(stage, ["vite"])` symlink setup. - Pins root `packageManager` to `pnpm@10.33.4` matching the vite PR's pnpm, removing a per-install version switch that produced an outer-vs-inner lockfile-settings mismatch when vite consumed vite-task as a git dep. - Drops the root `prepare: husky` so pnpm's git-dep flow doesn't invoke `pnpm pack`, which had been producing a lockfile `resolution` entry without the `path:` field — pnpm then extracted the *entire* vite-task monorepo into `node_modules/@voidzero-dev/vite-task-client/` instead of the subpath. - Pins the vite catalog entry to a commit-specific `pkg.pr.new` URL so future bumps require updating this line. - Sets `blockExoticSubdeps: false` so pnpm 11 doesn't reject the transitive `github:` spec. Refreshes the playground to use the published vite + the runner- aware tools. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d79b8ff commit fef1237

28 files changed

Lines changed: 1445 additions & 24 deletions
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>vp-run-vite-cache</title>
5+
</head>
6+
<body>
7+
<script type="module" src="/src/main.js"></script>
8+
</body>
9+
</html>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "vite-build-cache-fixture",
3+
"private": true,
4+
"type": "module"
5+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
[[e2e]]
2+
name = "vite_build_caches_and_restores_outputs"
3+
comment = """
4+
`vt run --cache build` must produce a cache hit on the second run without any manual input/output configuration. Vite reports `ignoreInput(outDir)` + `ignoreInput/Output(cacheDir)` via `@voidzero-dev/vite-task-client`, so fspy-detected reads of `dist/` and writes to `node_modules/.vite/` don't poison the cache.
5+
"""
6+
ignore = true
7+
steps = [
8+
{ argv = [
9+
"vt",
10+
"run",
11+
"--cache",
12+
"build",
13+
], comment = "first run: cache miss, emits dist/" },
14+
{ argv = [
15+
"vtt",
16+
"stat-file",
17+
"dist/assets/main.js",
18+
], comment = "existence check — content would drift across Vite versions" },
19+
{ argv = [
20+
"vtt",
21+
"rm",
22+
"dist/assets/main.js",
23+
], comment = "remove the artefact so the cache-hit restore is observable" },
24+
{ argv = [
25+
"vt",
26+
"run",
27+
"--cache",
28+
"build",
29+
], comment = "cache hit: outputs restored without manual config" },
30+
{ argv = [
31+
"vtt",
32+
"stat-file",
33+
"dist/assets/main.js",
34+
], comment = "restored from the cache archive" },
35+
]
36+
37+
[[e2e]]
38+
name = "vite_prefix_env_change_invalidates_cache"
39+
comment = """
40+
`VITE_MODE` is picked up by Vite's patched `loadEnv`, which asks the runner for every `VITE_*` env via `getEnvs(pattern, { tracked: true })`. Flipping its value between runs must invalidate the cache AND change the build output — Vite's `define` plugin substitutes `import.meta.env.VITE_MODE` at build time, so dead-code elimination leaves only the branch matching the value.
41+
"""
42+
ignore = true
43+
steps = [
44+
{ argv = [
45+
"vt",
46+
"run",
47+
"--cache",
48+
"build",
49+
], envs = [
50+
[
51+
"VITE_MODE",
52+
"production",
53+
],
54+
], comment = "first run: production build" },
55+
{ argv = [
56+
"vtt",
57+
"grep-file",
58+
"dist/assets/main.js",
59+
"BUILD_MODE_PROD",
60+
], comment = "production build: PROD marker survived DCE" },
61+
{ argv = [
62+
"vtt",
63+
"grep-file",
64+
"dist/assets/main.js",
65+
"BUILD_MODE_DEV",
66+
], comment = "dev branch is gone" },
67+
{ argv = [
68+
"vt",
69+
"run",
70+
"--cache",
71+
"build",
72+
], envs = [
73+
[
74+
"VITE_MODE",
75+
"production",
76+
],
77+
], comment = "cache hit: VITE_MODE unchanged" },
78+
{ argv = [
79+
"vt",
80+
"run",
81+
"--cache",
82+
"build",
83+
], envs = [
84+
[
85+
"VITE_MODE",
86+
"development",
87+
],
88+
], comment = "cache miss: tracked env glob `VITE_*` — VITE_MODE value changed" },
89+
{ argv = [
90+
"vtt",
91+
"grep-file",
92+
"dist/assets/main.js",
93+
"BUILD_MODE_PROD",
94+
], comment = "PROD marker gone after the dev rebuild" },
95+
{ argv = [
96+
"vtt",
97+
"grep-file",
98+
"dist/assets/main.js",
99+
"BUILD_MODE_DEV",
100+
], comment = "DEV marker now in the bundle" },
101+
]
102+
103+
[[e2e]]
104+
name = "vite_node_env_change_invalidates_cache"
105+
comment = """
106+
`NODE_ENV` enters the build's cache fingerprint via Vite's `getEnv('NODE_ENV')` call in `resolveConfig`. Same value → cache hit; different value → cache miss with `tracked env 'NODE_ENV' changed`.
107+
"""
108+
ignore = true
109+
steps = [
110+
{ argv = [
111+
"vt",
112+
"run",
113+
"--cache",
114+
"build",
115+
], envs = [
116+
[
117+
"NODE_ENV",
118+
"production",
119+
],
120+
], comment = "first run: NODE_ENV=production" },
121+
{ argv = [
122+
"vt",
123+
"run",
124+
"--cache",
125+
"build",
126+
], envs = [
127+
[
128+
"NODE_ENV",
129+
"production",
130+
],
131+
], comment = "cache hit: NODE_ENV unchanged" },
132+
{ argv = [
133+
"vt",
134+
"run",
135+
"--cache",
136+
"build",
137+
], envs = [
138+
[
139+
"NODE_ENV",
140+
"development",
141+
],
142+
], comment = "cache miss: tracked env 'NODE_ENV' changed" },
143+
]
144+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# vite_build_caches_and_restores_outputs
2+
3+
`vt run --cache build` must produce a cache hit on the second run without any manual input/output configuration. Vite reports `ignoreInput(outDir)` + `ignoreInput/Output(cacheDir)` via `@voidzero-dev/vite-task-client`, so fspy-detected reads of `dist/` and writes to `node_modules/.vite/` don't poison the cache.
4+
5+
## `vt run --cache build`
6+
7+
first run: cache miss, emits dist/
8+
9+
```
10+
$ vite build
11+
```
12+
13+
## `vtt stat-file dist/assets/main.js`
14+
15+
existence check — content would drift across Vite versions
16+
17+
```
18+
dist/assets/main.js: exists
19+
```
20+
21+
## `vtt rm dist/assets/main.js`
22+
23+
remove the artefact so the cache-hit restore is observable
24+
25+
```
26+
```
27+
28+
## `vt run --cache build`
29+
30+
cache hit: outputs restored without manual config
31+
32+
```
33+
$ vite build ◉ cache hit, replaying
34+
35+
---
36+
vt run: cache hit.
37+
```
38+
39+
## `vtt stat-file dist/assets/main.js`
40+
41+
restored from the cache archive
42+
43+
```
44+
dist/assets/main.js: exists
45+
```
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# vite_node_env_change_invalidates_cache
2+
3+
`NODE_ENV` enters the build's cache fingerprint via Vite's `getEnv('NODE_ENV')` call in `resolveConfig`. Same value → cache hit; different value → cache miss with `tracked env 'NODE_ENV' changed`.
4+
5+
## `NODE_ENV=production vt run --cache build`
6+
7+
first run: NODE_ENV=production
8+
9+
```
10+
$ vite build
11+
```
12+
13+
## `NODE_ENV=production vt run --cache build`
14+
15+
cache hit: NODE_ENV unchanged
16+
17+
```
18+
$ vite build ◉ cache hit, replaying
19+
20+
---
21+
vt run: cache hit.
22+
```
23+
24+
## `NODE_ENV=development vt run --cache build`
25+
26+
cache miss: tracked env 'NODE_ENV' changed
27+
28+
```
29+
$ vite build ○ cache miss: tracked env 'NODE_ENV' changed, executing
30+
```
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# vite_prefix_env_change_invalidates_cache
2+
3+
`VITE_MODE` is picked up by Vite's patched `loadEnv`, which asks the runner for every `VITE_*` env via `getEnvs(pattern, { tracked: true })`. Flipping its value between runs must invalidate the cache AND change the build output — Vite's `define` plugin substitutes `import.meta.env.VITE_MODE` at build time, so dead-code elimination leaves only the branch matching the value.
4+
5+
## `VITE_MODE=production vt run --cache build`
6+
7+
first run: production build
8+
9+
```
10+
$ vite build
11+
```
12+
13+
## `vtt grep-file dist/assets/main.js BUILD_MODE_PROD`
14+
15+
production build: PROD marker survived DCE
16+
17+
```
18+
dist/assets/main.js: found "BUILD_MODE_PROD"
19+
```
20+
21+
## `vtt grep-file dist/assets/main.js BUILD_MODE_DEV`
22+
23+
dev branch is gone
24+
25+
```
26+
dist/assets/main.js: missing "BUILD_MODE_DEV"
27+
```
28+
29+
## `VITE_MODE=production vt run --cache build`
30+
31+
cache hit: VITE_MODE unchanged
32+
33+
```
34+
$ vite build ◉ cache hit, replaying
35+
36+
---
37+
vt run: cache hit.
38+
```
39+
40+
## `VITE_MODE=development vt run --cache build`
41+
42+
cache miss: tracked env glob `VITE_*` — VITE_MODE value changed
43+
44+
```
45+
$ vite build ○ cache miss: tracked env glob 'VITE_*' changed, executing
46+
```
47+
48+
## `vtt grep-file dist/assets/main.js BUILD_MODE_PROD`
49+
50+
PROD marker gone after the dev rebuild
51+
52+
```
53+
dist/assets/main.js: missing "BUILD_MODE_PROD"
54+
```
55+
56+
## `vtt grep-file dist/assets/main.js BUILD_MODE_DEV`
57+
58+
DEV marker now in the bundle
59+
60+
```
61+
dist/assets/main.js: found "BUILD_MODE_DEV"
62+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// `import.meta.env.VITE_MODE` is replaced at build time from the value vite
2+
// picks up for keys matching `envPrefix` (`VITE_` by default). The markers
3+
// let the e2e test assert that flipping VITE_MODE actually changed what was
4+
// built and that glob-tracking invalidates the cache.
5+
if (import.meta.env.VITE_MODE === 'production') {
6+
document.body.append('BUILD_MODE_PROD');
7+
} else {
8+
document.body.append('BUILD_MODE_DEV');
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"tasks": {
3+
"build": {
4+
"command": "vite build",
5+
// No `"env": [...]` — vite's patched `loadEnv` asks the runner for
6+
// every `VITE_*` env via `getEnvs`, so the glob + match-set are
7+
// fingerprinted automatically.
8+
"cache": true
9+
}
10+
}
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from 'vite';
2+
3+
export default defineConfig({
4+
logLevel: 'silent',
5+
build: {
6+
rollupOptions: {
7+
output: {
8+
// Stable filenames make cache behaviour deterministic across runs.
9+
entryFileNames: 'assets/main.js',
10+
chunkFileNames: 'assets/chunk.js',
11+
assetFileNames: 'assets/[name][extname]',
12+
},
13+
},
14+
},
15+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Programmatic Vite dev server bring-up: middleware mode skips the HTTP
2+
// listen entirely (Windows runners refuse the 127.0.0.1 bind with
3+
// `listen UNKNOWN`), but `_createServer` still calls `disableCache()`
4+
// via `@voidzero-dev/vite-task-client` on its first line — so even
5+
// though this process exits 0 the runner is told not to store the run
6+
// and the next invocation must miss.
7+
import { createServer } from 'vite';
8+
9+
const server = await createServer({
10+
configFile: false,
11+
logLevel: 'silent',
12+
server: { middlewareMode: true },
13+
});
14+
await server.close();

0 commit comments

Comments
 (0)