Skip to content

Commit 6cd75f4

Browse files
committed
fix(cache): add Package-scoped negative globs to prevent cache miss in monorepos
In monorepos, each package has its own node_modules/. When vp build/test/pack run, Vite creates .vite-temp/ config files and dist/ outputs that are both read and written during execution. The existing !node_modules/.vite-temp/** glob at Workspace scope only matched the workspace root, not package-level paths, causing perpetual cache misses due to read-write overlap detection. - Build: add Package-scoped !node_modules/.vite-temp/** and !dist/** - Test: add Package-scoped !node_modules/.vite-temp/** and !node_modules/.vite/**/results.json - Pack: add Package-scoped !node_modules/.vite-temp/** and !dist/**
1 parent 512eca0 commit 6cd75f4

File tree

8 files changed

+65
-17
lines changed

8 files changed

+65
-17
lines changed

packages/cli/binding/src/cli.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,7 @@ impl SubcommandResolver {
332332
cache_config: UserCacheConfig::with_config(EnabledCacheConfig {
333333
env: Some(Box::new([Str::from("VITE_*")])),
334334
untracked_env: None,
335-
input: Some(vec![
336-
UserInputEntry::Auto(AutoInput { auto: true }),
337-
UserInputEntry::GlobWithBase(GlobWithBase {
338-
pattern: Str::from("!node_modules/.vite-temp/**"),
339-
base: InputBase::Workspace,
340-
}),
341-
]),
335+
input: Some(build_pack_cache_inputs()),
342336
}),
343337
envs: merge_resolved_envs_with_version(envs, resolved.envs),
344338
})
@@ -366,7 +360,14 @@ impl SubcommandResolver {
366360
cache_config: UserCacheConfig::with_config(EnabledCacheConfig {
367361
env: None,
368362
untracked_env: None,
369-
input: None,
363+
input: Some(vec![
364+
UserInputEntry::Auto(AutoInput { auto: true }),
365+
exclude_glob("!node_modules/.vite-temp/**", InputBase::Package),
366+
exclude_glob(
367+
"!node_modules/.vite/vitest/**/results.json",
368+
InputBase::Package,
369+
),
370+
]),
370371
}),
371372
envs: merge_resolved_envs_with_version(envs, resolved.envs),
372373
})
@@ -390,13 +391,7 @@ impl SubcommandResolver {
390391
cache_config: UserCacheConfig::with_config(EnabledCacheConfig {
391392
env: None,
392393
untracked_env: None,
393-
input: Some(vec![
394-
UserInputEntry::Auto(AutoInput { auto: true }),
395-
UserInputEntry::GlobWithBase(GlobWithBase {
396-
pattern: Str::from("!node_modules/.vite-temp/**"),
397-
base: InputBase::Workspace,
398-
}),
399-
]),
394+
input: Some(build_pack_cache_inputs()),
400395
}),
401396
envs: merge_resolved_envs(envs, resolved.envs),
402397
})
@@ -504,6 +499,24 @@ impl SubcommandResolver {
504499

505500
/// Merge resolved environment variables from JS resolver into existing envs.
506501
/// Does not override existing entries.
502+
/// Create a negative glob entry to exclude a pattern from cache fingerprinting.
503+
fn exclude_glob(pattern: &str, base: InputBase) -> UserInputEntry {
504+
UserInputEntry::GlobWithBase(GlobWithBase { pattern: Str::from(pattern), base })
505+
}
506+
507+
/// Common cache input entries for build/pack commands.
508+
/// Excludes .vite-temp config files and dist output files that are both read and written.
509+
/// TODO: The hardcoded `!dist/**` exclusion is a temporary workaround. It will be replaced
510+
/// by a runner-aware approach that automatically excludes task output directories.
511+
fn build_pack_cache_inputs() -> Vec<UserInputEntry> {
512+
vec![
513+
UserInputEntry::Auto(AutoInput { auto: true }),
514+
exclude_glob("!node_modules/.vite-temp/**", InputBase::Workspace),
515+
exclude_glob("!node_modules/.vite-temp/**", InputBase::Package),
516+
exclude_glob("!dist/**", InputBase::Package),
517+
]
518+
}
519+
507520
fn merge_resolved_envs(
508521
envs: &Arc<FxHashMap<Arc<OsStr>, Arc<OsStr>>>,
509522
resolved_envs: Vec<(String, String)>,

packages/cli/snap-tests/build-vite-env/snap.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,3 @@ dist/assets/index-BnIqjoTZ.js <variable> kB │ gzip: <variable> kB
3535

3636
✓ built in <variable>ms
3737

38-
---
39-
vp run: build-vite-env-test#build not cached because it modified its input. (Run `vp run --last-details` for full details)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "cache-monorepo-missing",
3+
"private": true,
4+
"workspaces": [
5+
"packages/*"
6+
],
7+
"scripts": {
8+
"ready": "vp run -r build"
9+
},
10+
"packageManager": "pnpm@10.32.1"
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "lib",
3+
"private": true,
4+
"scripts": {
5+
"build": "vp pack"
6+
}
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function add(a: number, b: number): number {
2+
return a + b;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { defineConfig } from 'vite-plus';
2+
3+
export default defineConfig({});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
> vp run --cache ready # first run
2+
> vp run --cache ready 2>&1 | grep -E 'cache hit|modified' # second run should all hit cache
3+
~/packages/lib$ vp pack ◉ cache hit, replaying
4+
vp run: cache hit, <variable>ms saved.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"commands": [
3+
{
4+
"command": "vp run --cache ready # first run",
5+
"ignoreOutput": true
6+
},
7+
"vp run --cache ready 2>&1 | grep -E 'cache hit|modified' # second run should all hit cache"
8+
]
9+
}

0 commit comments

Comments
 (0)