Skip to content

Commit

Permalink
Merge branch 'dev' into fix-vite-custom-server-react-refresh-babel-re…
Browse files Browse the repository at this point in the history
…solution
  • Loading branch information
pcattori authored Nov 7, 2023
2 parents 0e96075 + 1ee9093 commit 7f803e0
Show file tree
Hide file tree
Showing 22 changed files with 130 additions and 96 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
5 changes: 5 additions & 0 deletions .changeset/friendly-insects-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/server-runtime": minor
---

Updated `cookie` dependency from `0.4.1` to [`0.5.0`](https://github.com/jshttp/cookie/blob/v0.5.0/HISTORY.md#050--2022-04-11) to inherit support for `Priority` attribute in Chrome
5 changes: 5 additions & 0 deletions .changeset/manifest-modulepreload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/react": patch
---

add missing modulepreload for the manifest
12 changes: 12 additions & 0 deletions .changeset/nasty-waves-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@remix-run/dev": patch
---

fix(vite): Let Vite handle serving files outside of project root via `/@fs`

This fixes errors when using default client entry or server entry in a pnpm project
where those files may be outside of the project root, but within the workspace root.

By default, Vite prevents access to files outside the workspace root
(when using workspaces) or outside of the project root (when not using
workspaces) unless user explicitly opts into it via Vite's `server.fs.allow`.
11 changes: 11 additions & 0 deletions .changeset/ninety-boats-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@remix-run/dev": patch
---

fix(vite): deduplicate `@remix-run/react`

Pre-bundle Remix dependencies to avoid Remix router duplicates.
Our remix-remix-react-proxy plugin does not process default client and
server entry files since those come from within `node_modules`.
That means that before Vite pre-bundles dependencies (e.g. first time dev server is run)
mismatching Remix routers cause `Error: You must render this element inside a <Remix> element`.
5 changes: 5 additions & 0 deletions .changeset/two-boxes-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/dev": patch
---

Fix `FutureConfig` type
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
- gustavopch
- gyx1000
- hadizz
- haines
- hardingmatt
- harmony7
- helderburato
Expand Down
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
5 changes: 1 addition & 4 deletions integration/vite-css-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ test.describe("Vite CSS dev", () => {
port: ${devPort},
strictPort: true,
},
optimizeDeps: {
include: ["react", "react-dom/client", "@remix-run/react"],
},
plugins: [remix()],
});
`,
Expand All @@ -56,8 +53,8 @@ test.describe("Vite CSS dev", () => {
<div id="content">
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
5 changes: 1 addition & 4 deletions integration/vite-dev-express-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ test.beforeAll(async () => {
hmr: {
port: ${hmrPort}
}
},
optimizeDeps: {
include: ["react", "react-dom/client", "@remix-run/react"],
},
plugins: [remix()],
});
Expand Down Expand Up @@ -87,8 +84,8 @@ test.beforeAll(async () => {
<h1>Root</h1>
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
5 changes: 1 addition & 4 deletions integration/vite-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ test.describe("Vite dev", () => {
port: ${devPort},
strictPort: true,
},
optimizeDeps: {
include: ["react", "react-dom/client", "@remix-run/react"],
},
plugins: [remix()],
});
`,
Expand All @@ -54,8 +51,8 @@ test.describe("Vite dev", () => {
<h1>Root</h1>
<Outlet />
</div>
<LiveReload />
<Scripts />
<LiveReload />
</body>
</html>
);
Expand Down
10 changes: 7 additions & 3 deletions packages/remix-dev/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,13 @@ export interface AppConfig {
| string[]
| (() => Promise<string | string[]> | string | string[]);

future?: Partial<FutureConfig> & {
[propName: string]: never;
};
/**
* Enabled future flags
*/
future?: [keyof FutureConfig] extends [never]
? // Partial<FutureConfig> doesn't work when it's empty so just prevent any keys
{ [key: string]: never }
: Partial<FutureConfig>;
}

/**
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;
};
};
52 changes: 34 additions & 18 deletions packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,13 @@ const resolveFileUrl = (
filePath: string
) => {
let relativePath = path.relative(rootDirectory, filePath);
let isWithinRoot =
!relativePath.startsWith("..") && !path.isAbsolute(relativePath);

if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
throw new Error(
`Cannot resolve asset path "${filePath}" outside of root directory "${rootDirectory}".`
);
}
// Vite will prevent serving files outside of the workspace
// unless user explictly opts in with `server.fs.allow`
// https://vitejs.dev/config/server-options.html#server-fs-allow
if (!isWithinRoot) return `/@fs` + filePath;

return `/${normalizePath(relativePath)}`;
};
Expand Down Expand Up @@ -402,6 +403,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 All @@ -425,22 +429,35 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => {
experimental: { hmrPartialAccept: true },
optimizeDeps: {
include: [
// pre-bundle React dependencies to avoid React duplicates,
// even if React dependencies are not direct dependencies
// Pre-bundle React dependencies to avoid React duplicates,
// even if React dependencies are not direct dependencies.
// https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
"react",
`react/jsx-runtime`,
`react/jsx-dev-runtime`,
"react/jsx-runtime",
"react/jsx-dev-runtime",
"react-dom/client",

// Pre-bundle Remix dependencies to avoid Remix router duplicates.
// Our remix-remix-react-proxy plugin does not process default client and
// server entry files since those come from within `node_modules`.
// That means that before Vite pre-bundles dependencies (e.g. first time dev server is run)
// mismatching Remix routers cause `Error: You must render this element inside a <Remix> element`.
"@remix-run/react",
],
},
esbuild: {
jsx: "automatic",
jsxDev: viteCommand !== "build",
},
resolve: {
// https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
dedupe: ["react", "react-dom"],
dedupe: [
// https://react.dev/warnings/invalid-hook-call-warning#duplicate-react
"react",
"react-dom",

// see description for `@remix-run/react` in `optimizeDeps.include`
"@remix-run/react",
],
},
...(viteCommand === "build" && {
base: pluginConfig.publicPath,
Expand Down Expand Up @@ -709,9 +726,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 +881,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 +897,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
5 changes: 5 additions & 0 deletions packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,11 @@ import(${JSON.stringify(manifest.entry.module)});`;

return isHydrated ? null : (
<>
<link
rel="modulepreload"
href={manifest.url}
crossOrigin={props.crossOrigin}
/>
<link
rel="modulepreload"
href={manifest.entry.module}
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;
};
}
14 changes: 14 additions & 0 deletions packages/remix-server-runtime/__tests__/cookies-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ describe("cookies", () => {
expect(setCookie2).toContain("Path=/about");
});

it("supports the Priority attribute", async () => {
let cookie = createCookie("my-cookie");

let setCookie = await cookie.serialize("hello world");
expect(setCookie).not.toContain("Priority");

let cookie2 = createCookie("my-cookie2");

let setCookie2 = await cookie2.serialize("hello world", {
priority: "high",
});
expect(setCookie2).toContain("Priority=High");
});

describe("warnings when providing options you may not want to", () => {
let spy = spyConsole();

Expand Down
4 changes: 2 additions & 2 deletions packages/remix-server-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"module": "dist/esm/index.js",
"dependencies": {
"@remix-run/router": "1.11.0",
"@types/cookie": "^0.4.1",
"@types/cookie": "^0.5.3",
"@web3-storage/multipart-parser": "^1.0.0",
"cookie": "^0.4.1",
"cookie": "^0.5.0",
"set-cookie-parser": "^2.4.8",
"source-map": "^0.7.3"
},
Expand Down
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
Loading

0 comments on commit 7f803e0

Please sign in to comment.