feat: integrate with Vite Task for zero-config build caching#22453
Conversation
b4ddf51 to
48ef6c3
Compare
@vitejs/plugin-legacy
vite
commit: |
07daf26 to
96f992f
Compare
| }, | ||
| "//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!", | ||
| "dependencies": { | ||
| "@voidzero-dev/vite-task-client": "github:voidzero-dev/vite-task#1aedd944&path:/packages/vite-task-client", |
There was a problem hiding this comment.
Temporarily pointed to git for easier debug. Will publish to npm after this PR is approved, before it's merged.
| // alongside inline inherited envs. Outside Vite Task this is a no-op (the | ||
| // client cannot connect). | ||
| for (const prefix of prefixes) { | ||
| getEnvs(`${prefix}*`, { tracked: true }) |
There was a problem hiding this comment.
Effect verified in vite_prefix_env_change_invalidates_cache.md.
| // `outDir`. Without this, those reads would be recorded as build inputs | ||
| // and mix with the writes that follow, tripping Vite Task's read-write | ||
| // overlap check. No-op outside Vite Task. | ||
| ignoreInput(outDir) |
There was a problem hiding this comment.
Effect verified in vite_build_caches_and_restores_outputs.md.
| // The dev server is a long-running, interactive process whose outputs | ||
| // (network responses, HMR updates) cannot be replayed from a cache, so | ||
| // tell Vite Task to skip storing this run. No-op outside Vite Task. | ||
| disableCache() |
There was a problem hiding this comment.
Effect verified in vite_dev_disables_cache.md.
| // Vite Task knows it. Vite's build output branches on the value below | ||
| // (`isProduction`), so changing it between runs must invalidate the | ||
| // cache. No-op outside Vite Task. | ||
| getEnv('NODE_ENV') |
There was a problem hiding this comment.
Effect verified in vite_node_env_change_invalidates_cache.md.
| const processEnv = { ...process.env } as DotenvPopulateInput | ||
| expand({ parsed, processEnv }) |
There was a problem hiding this comment.
The env file may reference a env var and I think those are not tracked now. I don't think we have to try to track them now though.
There was a problem hiding this comment.
You're right. Tracking them would require dotenv-expand to report which variables it referenced. Let me look into it outside of this PR.
When Vite runs under Vite Task (`vp run`), report build inputs, outputs, and tracked env vars to Vite Task so that caching of `vite build` works without manual input/output configuration: - `loadEnv`: ask Vite Task for every env matching each prefix, so the glob + match-set enter the build's cache fingerprint. - optimizer: mark the deps cache dir as neither input nor output (the lockfile hash already drives re-optimization). - `prepareOutDir`: ignore `outDir` as an input so `emptyDir`'s reads don't mix with the writes that follow. - `loadConfigFromBundledFile`: ignore `node_modules/.vite-temp` so the transient bundled-config file doesn't poison the cache. All calls go through `@voidzero-dev/vite-task-client`, which is a no-op when Vite is not running inside Vite Task.
`loadConfigFromBundledFile` previously told Vite Task to ignore the entire `node_modules/.vite-temp/` directory, but only when `nodeModulesDir` existed. When it didn't (e.g. configs outside a project with `node_modules`), the temp file was written next to the original config and still showed up as both an input and an output of the build, poisoning the Vite Task cache fingerprint. Move the `ignoreInput`/`ignoreOutput` calls below `tempFileName` and pass the exact path that's about to be written. The call is a no-op outside Vite Task, so this is safe in either case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit dropped `path: /packages/vite-task-client` from the resolution metadata in the lockfile. The URL fragment in the resolution key still encodes the subdir, and pnpm 10.33.2 considers the inner field redundant (it rewrites the lockfile without it on `pnpm install`), but pnpm 10.33.4 — the version used by Vite CI — still needs the field to locate the subdir before deciding whether the package has a `prepare` script to run. Without it, CI fetches the tarball, sees the root `vite-task-monorepo` package's `prepare: husky` script, and aborts with `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED`. Restore the field so the preview-release CI job (and consumers like the vite-task workspace) can install the tarball. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The build output branches on `process.env.NODE_ENV` (`isProduction`
controls default minification, dev-only warnings, esbuild target,
`import.meta.env.PROD/DEV`, etc.), so a different NODE_ENV produces a
different bundle. Add `getEnv('NODE_ENV')` from
`@voidzero-dev/vite-task-client` before the existing
`!!process.env.NODE_ENV` check in `resolveConfig`. The call asks the
runner for the env (populating `process.env` if Vite Task knows the
value and the local environment hasn't already set it) and registers
NODE_ENV as a tracked dependency of the post-run fingerprint, so
flipping NODE_ENV between runs invalidates the cache with `tracked env
'NODE_ENV' changed`.
No-op outside Vite Task.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dev server is a long-running, interactive process whose outputs (network responses served on demand, HMR updates, optimizer state) are not replayable from a cache archive. Call `disableCache()` from `@voidzero-dev/vite-task-client` at the top of `_createServer` so the runner skips storing the run even when the user invokes `vp run --cache dev` or wires a dev task with `cache: true`. Without this, the runner would observe inputs, refuse to store on read/write overlap, or worse attempt to replay a useless archive on the next start. No-op outside Vite Task. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The new commit upstream of `@voidzero-dev/vite-task-client` refactors the `.node` addon so it exports a `load()` factory rather than the addon's operations directly, and updates the JS wrapper to `require(addon).load()`. The shape of the wrapper's public API is unchanged, but the bundled wrapper code that vite ships in `dist/` must move in lockstep with the addon shape the runner hands the process — so this PR's preview-release build needs to be regenerated against the new commit before vite-task can refresh its lockfile to consume it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two reasons the bump can't stay at the abbreviated `1aedd944`: * pnpm 11 (Vite Task's local pin via `mise`, post-`vitejs#383`) refuses to resolve abbreviated GitHub spec SHAs with `[ERROR] Could not resolve 1aedd944 to a commit of …`. Switching to the 40-char form fixes that on both ends. * `137a0003` is the latest commit on the vite-task branch (`runner-aware-tools`) — it bumps the recorded vite-task-client SHA inside `vite-task`'s lockfile and allows `clippy::disallowed_macros` for `napi-derive`'s generated `std::format!`. The wrapper code shipped to vite is identical to `1aedd944`'s, but pointing at the head commit keeps the cross-reference between the two PRs unambiguous. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`Build&Test: node-20, ubuntu-latest` on `0ed26a2ae` timed out twice in `playground/assets/__tests__/relative-base/assets-relative-base.spec.ts` (navigating to `http://localhost:5174/` after `createServer().listen()`) and `playground/fs-serve/__tests__/base/fs-serve-base.spec.ts` (navigating to `http://vite.dev/404`). The previous commit (`8f6364431`) ran the same wrapper code (the SHA bump in `0ed26a2ae` only swaps `1aedd944` → `137a00036d…` and those tree contents at `packages/vite-task-client/` are identical), and node-22, node-24 ubuntu, node-24 macOS, and node-24 Windows all pass. The retry just gives Playwright another shot on that runner. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The preview server is long-running and interactive, like the dev server, so its run should not be stored in the Vite Task cache. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2924189 to
5b54e07
Compare
`@voidzero-dev/vite-task-client`'s `getEnv`/`getEnvs` no longer mutate `process.env`; they return the value(s) instead. Populate `process.env` here: fall back to the returned `NODE_ENV` in `resolveConfig`, and merge prefixed envs into the resolved env map in `loadEnv`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88f2a9c to
614e0d2
Compare
- Adopt the side-effect-free `getEnv`/`getEnvs` shape; the `NODE_ENV`
fetch is now guarded by `process.env.NODE_ENV === undefined` so a
caller-set value is never overwritten.
- Drop the now-default `{ tracked: true }` argument from `getEnvs`.
- Bump vite-task-client to commit c1634234.
- Add the `path:` field to the lockfile `resolution` for the github
tarball; without it pnpm extracts the entire vite-task monorepo
into `node_modules/@voidzero-dev/vite-task-client/`.
- Allowlist `vite-task-monorepo` in `allowBuilds` so pnpm runs its
(now no-op) prepare script during the git-dep flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
614e0d2 to
23ded7b
Compare
Lays the groundwork for publishing `@voidzero-dev/vite-task-client` to npm. JS-side only — `src/index.js` (JSDoc as source of truth), `src/index.d.ts` regenerated from it, and the metadata required to publish. No Rust changes; no runner integration. The package is a thin wrapper with no `dependencies`: under a `vp run` task it loads the runner-provided napi addon at runtime, otherwise every method is a graceful no-op. ## Next steps 1. Publish `@voidzero-dev/vite-task-client@0.1.0` to npm. 2. Update the [Vite PR](vitejs/vite#22453) to depend on the published `@voidzero-dev/vite-task-client`. 3. Merge #410 — the remaining Rust implementation (IPC protocol + transport, napi binding, executor refactor, cache integration, e2e tests). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sapphi-red
left a comment
There was a problem hiding this comment.
LGTM (after the package is pointing to the published one)
Replaces the in-development git+subpath ref with the freshly published npm version (https://www.npmjs.com/package/@voidzero-dev/vite-task-client/v/0.1.0).
@sapphi-red Thank you for your time! The latest commit points |
…-integration # Conflicts: # pnpm-lock.yaml
9198994 to
bdf9921
Compare
Integrates Vite with Vite Task so that
vite buildcan be cached with zero configuration when run undervp run: Vite reports its build inputs, outputs, and tracked env vars through@voidzero-dev/vite-task-client, which is a no-op when Vite runs outside Vite Task.Companion PR on the Vite Task side: voidzero-dev/vite-task#346.
See the proposal for background and design rationale.