Skip to content

Commit

Permalink
fix(vite): fix HMR preamble race condition (#7919)
Browse files Browse the repository at this point in the history
Co-authored-by: Pedro Cattori <[email protected]>
  • Loading branch information
markdalgleish and pcattori authored Nov 6, 2023
1 parent fe0960a commit 22869fe
Show file tree
Hide file tree
Showing 11 changed files with 28 additions and 52 deletions.
6 changes: 6 additions & 0 deletions .changeset/afraid-suns-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@remix-run/dev": patch
"@remix-run/react": patch
---

Support rendering of `LiveReload` component after `Scripts` in Vite dev
6 changes: 6 additions & 0 deletions .changeset/early-trees-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@remix-run/dev": patch
"@remix-run/react": patch
---

Support optional rendering of `LiveReload` component in Vite dev
38 changes: 0 additions & 38 deletions docs/future/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,43 +127,6 @@ Vite handles imports for all sorts of different file types, sometimes in ways th
+ "include": ["env.d.ts", "**/*.ts", "**/*.tsx"],
```

#### `LiveReload` before `Scripts`

<docs-info>
This is a temporary workaround for a limitation that will be removed in the future.
</docs-info>

For React Fast Refresh to work, it [needs to be initialized before any app code is run][rfr-preamble].
That means it needs to come _before_ your `<Scripts />` element that loads your app code.

We're working on a better API that would eliminate issues with ordering scripts.
But for now, you can work around this limitation by manually moving `<LiveReload />` before `<Scripts />`.
If your app doesn't the `Scripts` component, you can safely ignore this step.

👉 **Ensure `<LiveReload />` comes _before_ `<Scripts />`**

```diff filename=app/root.tsx
export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
+ <LiveReload />
<Scripts />
- <LiveReload />
</body>
</html>
);
}
```

#### Migrating from Remix App Server

If you were using `remix-serve` in development (or `remix dev` without the `-c` flag), you'll need to switch to the new minimal dev server.
Expand Down Expand Up @@ -656,7 +619,6 @@ We're definitely late to the Vite party, but we're excited to be here now!
[solidstart]: https://start.solidjs.com/getting-started/what-is-solidstart
[sveltekit]: https://kit.svelte.dev/
[supported-with-some-deprecations]: #mdx
[rfr-preamble]: https://github.com/facebook/react/issues/16604#issuecomment-528663101
[component-keys]: #component-keys
[issues-vite]: https://github.com/remix-run/remix/labels/vite
[hmr]: ../discussion/hot-module-replacement
Expand Down
2 changes: 1 addition & 1 deletion integration/vite-css-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ test.describe("Vite CSS dev", () => {
<div id="content">
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion integration/vite-dev-express-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ test.beforeAll(async () => {
<h1>Root</h1>
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion integration/vite-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ test.describe("Vite dev", () => {
<h1>Root</h1>
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-dev/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type Manifest = {
};
};
hmr?: {
timestamp: number;
timestamp?: number;
runtime: string;
};
};
16 changes: 9 additions & 7 deletions packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => {
return {
version: String(Math.random()),
url: VirtualModule.url(browserManifestId),
hmr: {
runtime: VirtualModule.url(injectHmrRuntimeId),
},
entry: {
module: resolveFileUrl(pluginConfig, pluginConfig.entryClientFilePath),
imports: [],
Expand Down Expand Up @@ -709,9 +712,9 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => {
'export * from "@remix-run/react";',
'export const LiveReload = process.env.NODE_ENV !== "development" ? () => null : ',
'() => createElement("script", {',
' type: "module",',
" async: true,",
` src: "${VirtualModule.url(injectHmrRuntimeId)}"`,
" dangerouslySetInnerHTML: { ",
" __html: `window.__remixLiveReloadEnabled = true`",
" }",
"});",
].join("\n");
}
Expand Down Expand Up @@ -864,11 +867,10 @@ const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof
let prevRefreshReg;
let prevRefreshSig;
if (import.meta.hot && !inWebWorker) {
if (import.meta.hot && !inWebWorker && window.__remixLiveReloadEnabled) {
if (!window.__vite_plugin_react_preamble_installed__) {
throw new Error(
"@vitejs/plugin-react can't detect preamble. Something is wrong. " +
"See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201"
"Remix Vite plugin can't detect preamble. Something is wrong."
);
}
Expand All @@ -881,7 +883,7 @@ if (import.meta.hot && !inWebWorker) {
}`.replace(/\n+/g, "");

const REACT_REFRESH_FOOTER = `
if (import.meta.hot && !inWebWorker) {
if (import.meta.hot && !inWebWorker && window.__remixLiveReloadEnabled) {
window.$RefreshReg$ = prevRefreshReg;
window.$RefreshSig$ = prevRefreshSig;
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-react/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface AssetsManifest {
url: string;
version: string;
hmr?: {
timestamp: number;
timestamp?: number;
runtime: string;
};
}
2 changes: 1 addition & 1 deletion templates/unstable-vite-express/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default function App() {
<body>
<Outlet />
<ScrollRestoration />
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion templates/unstable-vite/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default function App() {
<body>
<Outlet />
<ScrollRestoration />
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down

0 comments on commit 22869fe

Please sign in to comment.