From 040f51ad3a30ea77e49f1037082ca1a050aad619 Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Sun, 28 Jan 2024 23:58:46 -0700 Subject: [PATCH 1/6] Use ternary on vite configuration building --- packages/remix-dev/vite/plugin.ts | 86 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index b684b453d24..be22a3fe57d 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -938,48 +938,50 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => { ], }, base: viteUserConfig.base, - ...(viteCommand === "build" && { - build: { - cssMinify: viteUserConfig.build?.cssMinify ?? true, - ...(!viteConfigEnv.isSsrBuild - ? { - manifest: true, - outDir: getClientBuildDirectory(ctx.remixConfig), - rollupOptions: { - preserveEntrySignatures: "exports-only", - input: [ - ctx.entryClientFilePath, - ...Object.values(ctx.remixConfig.routes).map( - (route) => - `${path.resolve( - ctx.remixConfig.appDirectory, - route.file - )}${CLIENT_ROUTE_QUERY_STRING}` - ), - ], - }, - } - : { - // We move SSR-only assets to client assets. Note that the - // SSR build can also emit code-split JS files (e.g. by - // dynamic import) under the same assets directory - // regardless of "ssrEmitAssets" option, so we also need to - // keep these JS files have to be kept as-is. - ssrEmitAssets: true, - copyPublicDir: false, // Assets in the public directory are only used by the client - manifest: true, // We need the manifest to detect SSR-only assets - outDir: getServerBuildDirectory(ctx), - rollupOptions: { - preserveEntrySignatures: "exports-only", - input: serverBuildId, - output: { - entryFileNames: ctx.remixConfig.serverBuildFile, - format: ctx.remixConfig.serverModuleFormat, - }, - }, - }), - }, - }), + ...(viteCommand === "build" + ? { + build: { + cssMinify: viteUserConfig.build?.cssMinify ?? true, + ...(!viteConfigEnv.isSsrBuild + ? { + manifest: true, + outDir: getClientBuildDirectory(ctx.remixConfig), + rollupOptions: { + preserveEntrySignatures: "exports-only", + input: [ + ctx.entryClientFilePath, + ...Object.values(ctx.remixConfig.routes).map( + (route) => + `${path.resolve( + ctx.remixConfig.appDirectory, + route.file + )}${CLIENT_ROUTE_QUERY_STRING}` + ), + ], + }, + } + : { + // We move SSR-only assets to client assets. Note that the + // SSR build can also emit code-split JS files (e.g. by + // dynamic import) under the same assets directory + // regardless of "ssrEmitAssets" option, so we also need to + // keep these JS files have to be kept as-is. + ssrEmitAssets: true, + copyPublicDir: false, // Assets in the public directory are only used by the client + manifest: true, // We need the manifest to detect SSR-only assets + outDir: getServerBuildDirectory(ctx), + rollupOptions: { + preserveEntrySignatures: "exports-only", + input: serverBuildId, + output: { + entryFileNames: ctx.remixConfig.serverBuildFile, + format: ctx.remixConfig.serverModuleFormat, + }, + }, + }), + }, + } + : undefined), }; }, async configResolved(resolvedViteConfig) { From 604c48d4624d840db04a7a107030adb93cc27267 Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Mon, 29 Jan 2024 00:00:23 -0700 Subject: [PATCH 2/6] Adjust vite config when runnning "vite preview" in case of unstable_ssr Set appType: "spa" Ensure outDir gets passed through --- packages/remix-dev/vite/plugin.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index be22a3fe57d..defadd62f22 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -897,7 +897,12 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => { return { __remixPluginContext: ctx, - appType: "custom", + appType: + viteCommand === "serve" && + viteConfigEnv.mode === "production" && + ctx.remixConfig.unstable_ssr === false + ? "spa" + : "custom", optimizeDeps: { include: [ // Pre-bundle React dependencies to avoid React duplicates, @@ -981,6 +986,14 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => { }), }, } + : viteCommand === "serve" && ctx.remixConfig.unstable_ssr === false + ? { + base: ctx.remixConfig.publicPath, + build: { + manifest: true, + outDir: getClientBuildDirectory(ctx.remixConfig), + }, + } : undefined), }; }, From 78e38f4d46aa843b89d09751631b560ea159873c Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Mon, 29 Jan 2024 00:12:59 -0700 Subject: [PATCH 3/6] Update spa template README.md to mention that server needs to support SPA mode --- templates/spa/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/spa/README.md b/templates/spa/README.md index e5e8d9b223a..cd17f67abf3 100644 --- a/templates/spa/README.md +++ b/templates/spa/README.md @@ -22,16 +22,16 @@ npm run dev ## Production -When you are ready yo build a production version of your app, `npm run build` will generate your assets and an `index.html` for the SPA. +When you are ready to build a production version of your app, `npm run build` will generate your assets and an `index.html` for the SPA. ```shellscript npm run build ``` -You can serve this from any server of your choosing, for a simple example, you could use [http-server](https://www.npmjs.com/package/http-server): +You can serve this from any server of your choosing. The server should support SPA fallback. For a simple example, you could use [sirv-cli](https://www.npmjs.com/package/sirv-cli): ```shellscript -npx http-server build/client/ +npx sirv-cli build/client/ --single --ignores "^/assets/" ``` [remix-vite-docs]: https://remix.run/docs/en/main/future/vite From 18228143d6987b56d0285cea48386c453737af2f Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Mon, 29 Jan 2024 00:14:40 -0700 Subject: [PATCH 4/6] Update spa template package.json script to use vite preview --- templates/spa/README.md | 6 ++++++ templates/spa/package.json | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/spa/README.md b/templates/spa/README.md index cd17f67abf3..700cb47d074 100644 --- a/templates/spa/README.md +++ b/templates/spa/README.md @@ -28,6 +28,12 @@ When you are ready to build a production version of your app, `npm run build` wi npm run build ``` +Preview build locally with [vite preview](https://vitejs.dev/guide/cli#vite-preview) to serve all routes via the single `index.html` file. Do not use this as a production server as it's not designed for it: + +```shellscript +npm run preview +``` + You can serve this from any server of your choosing. The server should support SPA fallback. For a simple example, you could use [sirv-cli](https://www.npmjs.com/package/sirv-cli): ```shellscript diff --git a/templates/spa/package.json b/templates/spa/package.json index 66c5be09320..b45ba399a00 100644 --- a/templates/spa/package.json +++ b/templates/spa/package.json @@ -6,13 +6,12 @@ "build": "remix vite:build", "dev": "remix vite:dev", "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .", - "start": "http-server build/client/", + "preview": "vite preview", "typecheck": "tsc" }, "dependencies": { "@remix-run/node": "*", "@remix-run/react": "*", - "http-server": "^14.1.1", "react": "^18.2.0", "react-dom": "^18.2.0" }, From 31e043038ae2be7ffb713c9f9a9e490a755a93c9 Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Mon, 29 Jan 2024 00:22:33 -0700 Subject: [PATCH 5/6] Add changeset --- .changeset/tender-pens-tan.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/tender-pens-tan.md diff --git a/.changeset/tender-pens-tan.md b/.changeset/tender-pens-tan.md new file mode 100644 index 00000000000..f143f4bba81 --- /dev/null +++ b/.changeset/tender-pens-tan.md @@ -0,0 +1,8 @@ +--- +"@remix-run/dev": patch +--- + +vite: Enable use of `vite preview` to preview built SPA sites + +In the SPA template, `start` script (`npm run start`) has been renamed to `preview` (`npm run preview`). +In the SPA template, `npm run preview` uses `vite preview` for serving built SPA sites. From 4a757cc92b1d9bad911b9f071bc9b835a0d2e3b2 Mon Sep 17 00:00:00 2001 From: Nathan Brown <nathan@nkbrown.us> Date: Tue, 30 Jan 2024 10:41:30 -0700 Subject: [PATCH 6/6] Clarify what "SPA fallback" is in the README.md --- templates/spa/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/spa/README.md b/templates/spa/README.md index 700cb47d074..d60efb5b0c3 100644 --- a/templates/spa/README.md +++ b/templates/spa/README.md @@ -34,7 +34,9 @@ Preview build locally with [vite preview](https://vitejs.dev/guide/cli#vite-prev npm run preview ``` -You can serve this from any server of your choosing. The server should support SPA fallback. For a simple example, you could use [sirv-cli](https://www.npmjs.com/package/sirv-cli): +You can serve this from any server of your choosing. The server should be configured to serve multiple paths from a single root `/index.html` file (commonly called "SPA fallback"). Other steps may be required if the host doesn't directly support this functionality. + +For a simple example, you could use [sirv-cli](https://www.npmjs.com/package/sirv-cli): ```shellscript npx sirv-cli build/client/ --single --ignores "^/assets/"