Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'a';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'b';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const value = 'c';
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "node-compile-cache-outside-workspace-fixture",
"private": true,
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Tiny Node script that turns on the v22 compile cache and imports a
// few sibling modules so the cache directory actually gets some files
// written to it. On a normally-configured machine the cache lives in
// the OS temp directory (outside the workspace), so the runner doesn't
// see those files when it decides whether the run can be cached.
//
// If the spawned process doesn't have LOCALAPPDATA (or TMP/TEMP/
// USERPROFILE) set on Windows, Node ends up putting the cache inside
// the workspace, the same files are both written and read in this one
// run, and the runner refuses to cache it. That's the bug this fixture
// catches.
import { enableCompileCache } from 'node:module';

enableCompileCache();

await import('./a.mjs');
await import('./b.mjs');
await import('./c.mjs');

console.log('done');
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[[e2e]]
name = "node_compile_cache_does_not_poison_workspace"
comment = """
Runs a small Node script that turns on Node's compile cache. The cache should land in the OS temp directory (outside the workspace), so two `vt run --cache build` calls should be a miss then a hit. On Windows, if the spawned task env doesn't have `LOCALAPPDATA`, Node puts the cache inside the workspace instead, the runner sees the same files both written and read, and refuses to cache the run — so the second call becomes another miss with a "not cached because it modified its input" message.
"""
ignore = true
Comment thread
branchseer marked this conversation as resolved.
steps = [
{ argv = [
"vt",
"run",
"--cache",
"build",
], comment = "first run: cache miss" },
{ argv = [
"vt",
"run",
"--cache",
"build",
], comment = "second run: cache hit" },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# node_compile_cache_does_not_poison_workspace

Runs a small Node script that turns on Node's compile cache. The cache should land in the OS temp directory (outside the workspace), so two `vt run --cache build` calls should be a miss then a hit. On Windows, if the spawned task env doesn't have `LOCALAPPDATA`, Node puts the cache inside the workspace instead, the runner sees the same files both written and read, and refuses to cache the run — so the second call becomes another miss with a "not cached because it modified its input" message.

## `vt run --cache build`

first run: cache miss

```
$ node run.mjs
done
```

## `vt run --cache build`

second run: cache hit

```
$ node run.mjs ◉ cache hit, replaying
done

---
vt run: cache hit.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tasks": {
"build": {
"command": "node run.mjs",
"cache": true
}
}
}
24 changes: 24 additions & 0 deletions crates/vite_task_bin/tests/e2e_snapshots/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,30 @@ fn run_case(
// On Windows, ensure common executable extensions are included in PATHEXT for command resolution in subprocesses.
if cfg!(windows) {
cmd.env("PATHEXT", ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC");
// Forward the Windows env vars Node needs to find a real
// temp directory. Without these, Node's compile cache and
// similar helpers fall back to a workspace-relative path
// and break cached runs. Values come from cargo-test's
// own env when present.
for name in [
"TMP",
"TEMP",
"APPDATA",
"LOCALAPPDATA",
"PROGRAMDATA",
"USERPROFILE",
"HOMEDRIVE",
"HOMEPATH",
"WINDIR",
"SYSTEMROOT",
"SYSTEMDRIVE",
"ProgramFiles",
"ProgramFiles(x86)",
] {
if let Some(value) = env::var_os(name) {
cmd.env(name, value);
}
}
}
for (k, v) in step.envs() {
let resolved = resolve_env_placeholder(v.as_str());
Expand Down
5 changes: 5 additions & 0 deletions crates/vite_task_graph/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ pub const DEFAULT_UNTRACKED_ENV: &[&str] = &[
"RUNNER_*",
// Windows specific
"APPDATA",
// Node's compile cache uses LOCALAPPDATA to pick its cache directory
// on Windows. Without it the cache lands inside the workspace and
// breaks every cached task that opts into the compile cache. See
// the `node_compile_cache_outside_workspace` e2e fixture.
"LOCALAPPDATA",
"PROGRAMDATA",
"SYSTEMROOT",
"SYSTEMDRIVE",
Expand Down
Loading