Skip to content

Commit 4edcd12

Browse files
committed
Revert "docs(ipc): switch vite-proposal to internal-plugin approach"
This reverts commit 16a3e78.
1 parent 665eb74 commit 4edcd12

1 file changed

Lines changed: 32 additions & 41 deletions

File tree

docs/runner-task-ipc/vite-proposal.md

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,7 @@ Vite Task needs the Vite process to communicate two things:
4343

4444
## Cases && Proposed Changes
4545

46-
The proposal has three pieces:
47-
48-
1. Add `@voidzero-dev/vite-task-client` as a dependency.
49-
2. Ship an internal plugin (`vite-task-plugin`) inside Vite that calls the client at the right points. The plugin is gated by the same env var Vite Task sets, so it's fully inert when Vite runs outside Vite Task.
50-
3. Add non-public plugin hooks where existing ones aren't enough. The hooks are designed in a generic shape (any plugin could use them) with no stability guarantee for now, ready to be promoted to public hooks later if they prove stable.
46+
We want to add a small dependency `@voidzero-dev/vite-task-client` to Vite that lets it talk to Vite Task at runtime. Vite calls into the client at the relevant code paths to declare "ignore this path as an input/output" or "fetch these envs from Vite Task". The calls **are no-ops when Vite runs outside Vite Task**.
5147

5248
### 1. Reading envs according to `envPrefix`
5349

@@ -64,7 +60,10 @@ This task config duplicates `envPrefix`. The two configs currently have to be ma
6460

6561
**Proposed Changes**:
6662

67-
`configResolved` fires after `loadEnv` has already read envs by prefix, so this case needs a new internal hook. We add `loadEnvPrefixed`, which fires inside `loadEnv` before the prefix-read loop:
63+
Add a call to `vite-task-client`'s `fetchEnvs` **before reading the envs matching `envPrefix`**. If Vite is running outside Vite Task, this calls is a no-op. If Vite is running inside Vite Task, it does two things:
64+
65+
- It tells Vite Task which envs are relevant to the build, so they **become part of the cache fingerprint**.
66+
- It **populates `process.env`** with those envs, so Vite can see them.
6867

6968
```diff
7069
--- a/packages/vite/src/node/env.ts
@@ -73,17 +72,11 @@ This task config duplicates `envPrefix`. The two configs currently have to be ma
7372
const parsed = Object.fromEntries(...);
7473
for (const [key, value] of Object.entries(parsed))
7574
if (prefixes.some(p => key.startsWith(p))) env[key] = value;
76-
+ // New non-public hook. Fires synchronously so plugins can inject
77-
+ // prefix-matched envs into process.env before the loop below reads it.
78-
+ await callPluginHook('loadEnvPrefixed', prefixes);
75+
+ for (const prefix of prefixes) fetchEnvs(`${prefix}*`, { tracked: true });
7976
for (const key in process.env)
8077
if (prefixes.some(p => key.startsWith(p))) env[key] = process.env[key];
8178
```
8279

83-
`vite-task-plugin` handles `loadEnvPrefixed` by calling `fetchEnvs(`${prefix}\*`, { tracked: true })` for each prefix. When Vite runs inside Vite Task this populates `process.env` with the matching values (so the loop below reads them) and tells Vite Task which envs to fingerprint. When Vite runs outside Vite Task the call is a no-op.
84-
85-
The hook is generic in shape: any plugin could use it to inject envs by prefix during `loadEnv`. It stays non-public until the shape settles, then can be promoted to a public hook.
86-
8780
### 2. Pre-bundling deps in `cacheDir`
8881

8982
Vite's dep optimizer reads metadata from and writes pre-bundled deps into [`cacheDir`](https://vite.dev/config/shared-options#cachedir) (default `node_modules/.vite/`).
@@ -102,7 +95,19 @@ And `cacheDir` is user-configurable, so the path in this config has to match wha
10295

10396
**Proposed Changes**:
10497

105-
`vite-task-plugin` handles this in the existing `configResolved` hook (no new Vite hook needed). By the time the dep optimizer reads or writes inside `config.cacheDir`, Vite Task already knows to ignore the directory.
98+
Add two calls **right after resolving `depsCacheDir`**. If Vite is running outside Vite Task, these calls are no-ops. If Vite is running inside Vite Task, they do two things:
99+
100+
- They tell Vite Task to **not treat reads in this directory as inputs**.
101+
- They tell Vite Task to **not treat writes in this directory as outputs**.
102+
103+
```diff
104+
--- a/packages/vite/src/node/optimizer/index.ts
105+
+++ b/packages/vite/src/node/optimizer/index.ts
106+
@@ loadCachedDepOptimizationMetadata(environment, force) {
107+
const depsCacheDir = getDepsCacheDir(environment);
108+
+ ignoreInput(depsCacheDir);
109+
+ ignoreOutput(depsCacheDir);
110+
```
106111

107112
### 3. Cleaning `outDir` before writing the bundle
108113

@@ -112,7 +117,16 @@ Before writing the bundle, Vite calls [`emptyDir(outDir)`](https://github.com/vi
112117

113118
**Proposed Changes**:
114119

115-
Same as case 2: `vite-task-plugin` calls `ignoreInput(config.build.outDir)` in `configResolved`. The bundle write is still tracked as an output, which is correct. No new Vite hook needed.
120+
Add a call **before `emptyDir`**. If Vite is running outside Vite Task, this call is a no-op. If Vite is running inside Vite Task, it tells Vite Task to **not treat reads in this directory as inputs**.
121+
122+
```diff
123+
--- a/packages/vite/src/node/plugins/prepareOutDir.ts
124+
+++ b/packages/vite/src/node/plugins/prepareOutDir.ts
125+
@@ prepareOutDir(outDirs, emptyOutDir, environment) {
126+
for (const outDir of outDirs) {
127+
+ ignoreInput(outDir);
128+
if (emptyOutDir !== false && fs.existsSync(outDir)) emptyDir(outDir, ...);
129+
```
116130

117131
### 4. Globbing files in `import.meta.glob`
118132

@@ -139,30 +153,6 @@ When called inside Vite Task, Vite Task does the globbing itself and returns the
139153
).filter(...).sort()
140154
```
141155

142-
### The plugin
143-
144-
```ts
145-
// vite/src/node/plugins/viteTaskPlugin.ts
146-
import { fetchEnvs, ignoreInput, ignoreOutput } from '@voidzero-dev/vite-task-client';
147-
148-
export const viteTaskPlugin = {
149-
name: 'vite:task',
150-
151-
configResolved(config) {
152-
// Cases 2 and 3.
153-
ignoreInput(config.cacheDir);
154-
ignoreOutput(config.cacheDir);
155-
ignoreInput(config.build.outDir);
156-
},
157-
158-
// New non-public hook (case 1).
159-
loadEnvPrefixed(prefixes) {
160-
for (const prefix of prefixes) fetchEnvs(`${prefix}*`, { tracked: true });
161-
},
162-
};
163-
```
164-
165-
The plugin is added to Vite's built-in plugin list and only activates when Vite Task spawns Vite (gated by the same env var that the wrapper uses to find `node_client`).
166156

167157
## Details of `@voidzero-dev/vite-task-client` package
168158

@@ -230,5 +220,6 @@ Two examples of what could come next:
230220
- **Logic locality.** Each call belongs next to the Vite code that owns its path; patching from outside puts them somewhere else.
231221
- Users with a self-installed Vite (not the Vite+ bundled one) would get no benefit.
232222

233-
- **Ship the plugin and any new hooks as public Vite API from day one.**
234-
- Vite would commit to long-term API stability for hooks (like `loadEnvPrefixed`) before their shape has settled. Internal-with-no-stability lets us iterate first; promotion to public can happen later if a hook proves stable.
223+
- **Implement this in a Vite plugin**
224+
- The plugin doesn't have the enough hooks to cover all cases (fetch envs for `envPrefix`).
225+
- Enhancing the plugin API to cover all cases would be a much bigger impact on Vite.

0 commit comments

Comments
 (0)