diff --git a/crates/vite_task/src/session/execute/spawn.rs b/crates/vite_task/src/session/execute/spawn.rs index 99ebae87..88f67ff8 100644 --- a/crates/vite_task/src/session/execute/spawn.rs +++ b/crates/vite_task/src/session/execute/spawn.rs @@ -211,6 +211,11 @@ pub async fn spawn_with_tracking( return None; } + // Skip Vite temp config files (transient build artifacts) + if relative.as_str().contains("node_modules/.vite-temp/") { + return None; + } + if !resolved_negatives.is_empty() && resolved_negatives.iter().any(|neg| neg.is_match(relative.as_str())) { diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/build.mjs b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/build.mjs new file mode 100644 index 00000000..cef1041d --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/build.mjs @@ -0,0 +1,18 @@ +// Simulates Vite's behavior during build: +// 1. Reads the source file (tracked as input by fspy) +// 2. Writes a temp config to node_modules/.vite-temp/ (also tracked by fspy) +// Without the .vite-temp exclusion, step 2 causes a read-write overlap +// that prevents caching. + +import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; + +// Read source (tracked as input) +const source = readFileSync('src/index.ts', 'utf-8'); + +// Simulate Vite writing temp config (read-write to .vite-temp) +const tempDir = 'node_modules/.vite-temp'; +mkdirSync(tempDir, { recursive: true }); +const tempFile = `${tempDir}/vite.config.ts.timestamp-${Date.now()}.mjs`; +writeFileSync(tempFile, `// compiled config\nexport default {};`); + +console.log(`built: ${source.trim()}`); diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/package.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/package.json new file mode 100644 index 00000000..a72136cd --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/package.json @@ -0,0 +1,4 @@ +{ + "name": "cache-skip-vite-temp", + "private": true +} diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots.toml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots.toml new file mode 100644 index 00000000..d787c894 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots.toml @@ -0,0 +1,18 @@ +# Tests that node_modules/.vite-temp/ is excluded from fspy tracking, +# so tasks writing to .vite-temp (like Vite config compilation) are still cached. +# See: https://github.com/voidzero-dev/vite-plus/issues/1095 + +[[e2e]] +name = "vite-temp read-write does not prevent caching" +steps = [ + "vt run build # first run: cache miss", + "vt run build # second run: should hit cache despite .vite-temp write", +] + +[[e2e]] +name = "source change still causes cache miss" +steps = [ + "vt run build # first run: cache miss", + "replace-file-content src/index.ts world universe # modify real source", + "vt run build # cache miss: source changed", +] diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/source change still causes cache miss.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/source change still causes cache miss.snap new file mode 100644 index 00000000..00dc2fd2 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/source change still causes cache miss.snap @@ -0,0 +1,12 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vt run build # first run: cache miss +$ node build.mjs +built: export const hello = 'world'; +> replace-file-content src/index.ts world universe # modify real source + +> vt run build # cache miss: source changed +$ node build.mjs ○ cache miss: 'src/index.ts' modified, executing +built: export const hello = 'universe'; diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/vite-temp read-write does not prevent caching.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/vite-temp read-write does not prevent caching.snap new file mode 100644 index 00000000..7b8ce5c4 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/snapshots/vite-temp read-write does not prevent caching.snap @@ -0,0 +1,13 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +> vt run build # first run: cache miss +$ node build.mjs +built: export const hello = 'world'; +> vt run build # second run: should hit cache despite .vite-temp write +$ node build.mjs ◉ cache hit, replaying +built: export const hello = 'world'; + +--- +vt run: cache hit, saved. diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/src/index.ts b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/src/index.ts new file mode 100644 index 00000000..35f468bf --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/src/index.ts @@ -0,0 +1 @@ +export const hello = 'world'; diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/vite-task.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/vite-task.json new file mode 100644 index 00000000..5426ee1e --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/cache-skip-vite-temp/vite-task.json @@ -0,0 +1,9 @@ +{ + "cache": true, + "tasks": { + "build": { + "command": "node build.mjs", + "cache": true + } + } +}