Skip to content

Commit 5796ca9

Browse files
authored
Inject HMR code in Worker entry file (#10001)
* Inject HMR code into Worker entry file * Add changeset * Add test * Skip HMR test for builds * Update changeset
1 parent 189fe23 commit 5796ca9

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

.changeset/orange-donkeys-check.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@cloudflare/vite-plugin": minor
3+
---
4+
5+
We now automatically inject the following HMR code into your Worker entry file:
6+
7+
```ts
8+
if (import.meta.hot) {
9+
import.meta.hot.accept();
10+
}
11+
```
12+
13+
This prevents file changes from invalidating the full module graph and improves HMR performance in development.

packages/vite-plugin-cloudflare/playground/worker/__tests__/worker.spec.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
import { expect, test } from "vitest";
2-
import { getTextResponse, serverLogs, viteTestUrl } from "../../__test-utils__";
1+
import * as fs from "node:fs";
2+
import * as path from "node:path";
3+
import { expect, test, vi } from "vitest";
4+
import {
5+
getTextResponse,
6+
isBuild,
7+
rootDir,
8+
serverLogs,
9+
viteTestUrl,
10+
} from "../../__test-utils__";
311

412
test("basic hello-world functionality", async () => {
513
expect(await getTextResponse()).toEqual("Hello World!");
@@ -20,3 +28,16 @@ test("receives the original host as the `X-Forwarded-Host` header", async () =>
2028
test("does not cause unhandled rejection", async () => {
2129
expect(serverLogs.errors.join()).not.toContain("__unhandled rejection__");
2230
});
31+
32+
test.runIf(!isBuild)(
33+
"updates using HMR code in Worker entry file",
34+
async () => {
35+
const workerEntryPath = path.join(rootDir, "src", "index.ts");
36+
const originalContent = fs.readFileSync(workerEntryPath, "utf-8");
37+
fs.writeFileSync(workerEntryPath, originalContent);
38+
39+
await vi.waitFor(() => {
40+
expect(serverLogs.info.join()).toContain("[vite] hot updated");
41+
});
42+
}
43+
);

packages/vite-plugin-cloudflare/src/index.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,6 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
167167
},
168168
};
169169
},
170-
buildStart() {
171-
// This resets the value when the dev server restarts
172-
workersConfigsWarningShown = false;
173-
},
174170
configResolved(config) {
175171
resolvedViteConfig = config;
176172

@@ -181,6 +177,34 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
181177
);
182178
}
183179
},
180+
buildStart() {
181+
// This resets the value when the dev server restarts
182+
workersConfigsWarningShown = false;
183+
},
184+
async transform(code, id) {
185+
const workerConfig = getWorkerConfig(this.environment.name);
186+
187+
if (!workerConfig) {
188+
return;
189+
}
190+
191+
const resolvedWorkerEntry = await this.resolve(workerConfig.main);
192+
193+
if (id === resolvedWorkerEntry?.id) {
194+
const modified = new MagicString(code);
195+
const hmrCode = `
196+
if (import.meta.hot) {
197+
import.meta.hot.accept();
198+
}
199+
`;
200+
modified.append(hmrCode);
201+
202+
return {
203+
code: modified.toString(),
204+
map: modified.generateMap({ hires: "boundary", source: id }),
205+
};
206+
}
207+
},
184208
generateBundle(_, bundle) {
185209
assertIsNotPreview(resolvedPluginConfig);
186210

0 commit comments

Comments
 (0)