Skip to content

Commit 88387e3

Browse files
committed
test(e2e): verify real Vite env cache tracking
Motivation: The smaller IPC fixture proves runner env tracking in isolation, but reviewers also need confidence that the real Vite integration exercises getEnv for NODE_ENV and getEnvs for VITE_* prefixes. Scope: Add a minimal Vite build fixture and a local vtt grep-file helper used only to assert that changing VITE_MODE changes the emitted bundle. This PR does not introduce production APIs, playground changes, or output tracking behavior. Verification: - cargo test -p vite_task_bin --test e2e_snapshots vite_node_env_change_invalidates_cache -- --ignored - cargo test -p vite_task_bin --test e2e_snapshots vite_prefix_env_change_invalidates_cache -- --ignored
1 parent 3f5f6b4 commit 88387e3

10 files changed

Lines changed: 280 additions & 1 deletion

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pub fn run(args: &[String]) {
2+
let [path, pattern] = args else {
3+
eprintln!("Usage: vtt grep-file <path> <pattern>");
4+
std::process::exit(2);
5+
};
6+
match std::fs::read_to_string(path) {
7+
Ok(content) => {
8+
if content.contains(pattern.as_str()) {
9+
println!("{path}: found {pattern:?}");
10+
} else {
11+
println!("{path}: missing {pattern:?}");
12+
}
13+
}
14+
Err(_) => println!("{path}: not found"),
15+
}
16+
}

crates/vite_task_bin/src/vtt/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod check_tty;
1111
mod cp;
1212
mod exit;
1313
mod exit_on_ctrlc;
14+
mod grep_file;
1415
mod list_dir;
1516
mod mkdir;
1617
mod pipe_stdin;
@@ -30,7 +31,7 @@ fn main() {
3031
if args.len() < 2 {
3132
eprintln!("Usage: vtt <subcommand> [args...]");
3233
eprintln!(
33-
"Subcommands: barrier, check-tty, cp, exit, exit-on-ctrlc, list-dir, mkdir, pipe-stdin, print, print-color, print-cwd, print-env, print-file, read-stdin, replace-file-content, rm, touch-file, write-file"
34+
"Subcommands: barrier, check-tty, cp, exit, exit-on-ctrlc, grep-file, list-dir, mkdir, pipe-stdin, print, print-color, print-cwd, print-env, print-file, read-stdin, replace-file-content, rm, touch-file, write-file"
3435
);
3536
std::process::exit(1);
3637
}
@@ -44,6 +45,10 @@ fn main() {
4445
"cp" => cp::run(&args[2..]),
4546
"exit" => exit::run(&args[2..]),
4647
"exit-on-ctrlc" => exit_on_ctrlc::run(),
48+
"grep-file" => {
49+
grep_file::run(&args[2..]);
50+
Ok(())
51+
}
4752
"list-dir" => list_dir::run(&args[2..]),
4853
"mkdir" => mkdir::run(&args[2..]),
4954
"pipe-stdin" => pipe_stdin::run(&args[2..]),
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: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
[[e2e]]
2+
name = "vite_prefix_env_change_invalidates_cache"
3+
comment = """
4+
`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.
5+
"""
6+
ignore = true
7+
steps = [
8+
{ argv = [
9+
"vt",
10+
"run",
11+
"--cache",
12+
"build",
13+
], envs = [
14+
[
15+
"VITE_MODE",
16+
"production",
17+
],
18+
], comment = "first run: production build" },
19+
{ argv = [
20+
"vtt",
21+
"grep-file",
22+
"dist/assets/main.js",
23+
"BUILD_MODE_PROD",
24+
], comment = "production build: PROD marker survived DCE" },
25+
{ argv = [
26+
"vtt",
27+
"grep-file",
28+
"dist/assets/main.js",
29+
"BUILD_MODE_DEV",
30+
], comment = "dev branch is gone" },
31+
{ argv = [
32+
"vt",
33+
"run",
34+
"--cache",
35+
"build",
36+
], envs = [
37+
[
38+
"VITE_MODE",
39+
"production",
40+
],
41+
], comment = "cache hit: VITE_MODE unchanged" },
42+
{ argv = [
43+
"vt",
44+
"run",
45+
"--cache",
46+
"build",
47+
], envs = [
48+
[
49+
"VITE_MODE",
50+
"development",
51+
],
52+
], comment = "cache miss: envs changed — VITE_MODE value changed" },
53+
{ argv = [
54+
"vtt",
55+
"grep-file",
56+
"dist/assets/main.js",
57+
"BUILD_MODE_PROD",
58+
], comment = "PROD marker gone after the dev rebuild" },
59+
{ argv = [
60+
"vtt",
61+
"grep-file",
62+
"dist/assets/main.js",
63+
"BUILD_MODE_DEV",
64+
], comment = "DEV marker now in the bundle" },
65+
]
66+
67+
[[e2e]]
68+
name = "vite_node_env_change_invalidates_cache"
69+
comment = """
70+
`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 `envs changed`.
71+
"""
72+
ignore = true
73+
steps = [
74+
{ argv = [
75+
"vt",
76+
"run",
77+
"--cache",
78+
"build",
79+
], envs = [
80+
[
81+
"NODE_ENV",
82+
"production",
83+
],
84+
], comment = "first run: NODE_ENV=production" },
85+
{ argv = [
86+
"vt",
87+
"run",
88+
"--cache",
89+
"build",
90+
], envs = [
91+
[
92+
"NODE_ENV",
93+
"production",
94+
],
95+
], comment = "cache hit: NODE_ENV unchanged" },
96+
{ argv = [
97+
"vt",
98+
"run",
99+
"--cache",
100+
"build",
101+
], envs = [
102+
[
103+
"NODE_ENV",
104+
"development",
105+
],
106+
], comment = "cache miss: envs changed (NODE_ENV changed)" },
107+
]
108+
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 `envs 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: envs changed (NODE_ENV changed)
27+
28+
```
29+
$ vite build ○ cache miss: 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: envs changed — VITE_MODE value changed
43+
44+
```
45+
$ vite build ○ cache miss: env 'VITE_MODE' 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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
//
9+
// TODO(env-track): A later PR in this stack removes these manual
10+
// exclusions once output tracking stops Vite's own writes from becoming
11+
// inferred inputs.
12+
//
13+
// Excluding Vite's build output and config-timestamp temp files from
14+
// auto input inference keeps this env-focused fixture cacheable without
15+
// turning reads of files Vite just wrote into inferred inputs.
16+
"input": ["!dist/**", "!node_modules/.vite-temp/**", { "auto": true }],
17+
"cache": true
18+
}
19+
}
20+
}
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+
});

0 commit comments

Comments
 (0)