From 825a9073873311f1da24aa25cecbaedef70dd062 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Tue, 12 Dec 2023 12:54:56 +1100 Subject: [PATCH] fix(vite): remove virtual server build ID export (#8264) --- .changeset/breezy-walls-scream.md | 27 ++++++++++++++++++++++ docs/future/vite.md | 13 +++-------- integration/helpers/vite.ts | 3 +-- packages/remix-dev/index.ts | 2 +- packages/remix-dev/vite/index.ts | 5 ---- packages/remix-dev/vite/plugin.ts | 10 ++++---- packages/remix-dev/vite/server-entry-id.ts | 5 ---- packages/remix-dev/vite/vmod.ts | 2 +- templates/unstable-vite-express/server.mjs | 3 +-- 9 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 .changeset/breezy-walls-scream.md delete mode 100644 packages/remix-dev/vite/server-entry-id.ts diff --git a/.changeset/breezy-walls-scream.md b/.changeset/breezy-walls-scream.md new file mode 100644 index 00000000000..1b1510d22a1 --- /dev/null +++ b/.changeset/breezy-walls-scream.md @@ -0,0 +1,27 @@ +--- +"@remix-run/dev": patch +--- + +Remove `unstable_viteServerBuildModuleId` in favor of manually referencing virtual module name `"virtual:remix/server-build"`. + +**This is a breaking change for projects using the unstable Vite plugin with a custom server.** + +This change was made to avoid issues where `@remix-run/dev` could be inadvertently required in your server's production dependencies. + +Instead, you should manually write the virtual module name `"virtual:remix/server-build"` when calling `ssrLoadModule` in development. + +```diff +-import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; + +// ... + +app.all( + "*", + createRequestHandler({ + build: vite +- ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId) ++ ? () => vite.ssrLoadModule("virtual:remix/server-build") + : await import("./build/server/index.js"), + }) +); +``` diff --git a/docs/future/vite.md b/docs/future/vite.md index 1fdca23d97d..9364a2fd076 100644 --- a/docs/future/vite.md +++ b/docs/future/vite.md @@ -216,20 +216,15 @@ export default defineConfig({ If you were using a custom server in development, you'll need to edit your custom server to use Vite's `connect` middleware. This will delegate asset requests and initial render requests to Vite during development, letting you benefit from Vite's excellent DX even with a custom server. -You'll also need to update your server code to reference the new build output paths, which are `build/server` for the server build and `build/client` for client assets. - -Remix exposes the server build's module ID so that it can be loaded dynamically in your request handler during development via `vite.ssrLoadModule`. +You can then load the virtual module named `"virtual:remix/server-build"` during development to create a Vite-based request handler. -```ts -import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; -``` +You'll also need to update your server code to reference the new build output paths, which are `build/server` for the server build and `build/client` for client assets. For example, if you were using Express, here's how you could do it. 👉 **Update your `server.mjs` file** ```ts filename=server.mjs lines=[1,8-17,21-24,32,39-44] -import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; import { createRequestHandler } from "@remix-run/express"; import { installGlobals } from "@remix-run/node"; import express from "express"; @@ -269,9 +264,7 @@ app.all( createRequestHandler({ build: vite ? () => - vite.ssrLoadModule( - unstable_viteServerBuildModuleId - ) + vite.ssrLoadModule("virtual:remix/server-build") : await import("./build/server/index.js"), }) ); diff --git a/integration/helpers/vite.ts b/integration/helpers/vite.ts index 225058bd250..87af8450e67 100644 --- a/integration/helpers/vite.ts +++ b/integration/helpers/vite.ts @@ -41,7 +41,6 @@ export const EXPRESS_SERVER = (args: { loadContext?: Record; }) => String.raw` - import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; import { createRequestHandler } from "@remix-run/express"; import { installGlobals } from "@remix-run/node"; import express from "express"; @@ -73,7 +72,7 @@ export const EXPRESS_SERVER = (args: { "*", createRequestHandler({ build: vite - ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId) + ? () => vite.ssrLoadModule("virtual:remix/server-build") : await import("./build/index.js"), getLoadContext: () => (${JSON.stringify(args.loadContext ?? {})}), }) diff --git a/packages/remix-dev/index.ts b/packages/remix-dev/index.ts index d80fc623bdc..4dbdb3faf21 100644 --- a/packages/remix-dev/index.ts +++ b/packages/remix-dev/index.ts @@ -6,4 +6,4 @@ export * as cli from "./cli/index"; export type { Manifest as AssetsManifest } from "./manifest"; export { getDependenciesToBundle } from "./dependencies"; -export { unstable_vitePlugin, unstable_viteServerBuildModuleId } from "./vite"; +export { unstable_vitePlugin } from "./vite"; diff --git a/packages/remix-dev/vite/index.ts b/packages/remix-dev/vite/index.ts index 09bb6226ffb..1bcb08bb692 100644 --- a/packages/remix-dev/vite/index.ts +++ b/packages/remix-dev/vite/index.ts @@ -2,14 +2,9 @@ // don't need to have Vite installed as a peer dependency. Only types should // be imported at the top level. import type { RemixVitePlugin } from "./plugin"; -import { serverEntryId } from "./server-entry-id"; export const unstable_vitePlugin: RemixVitePlugin = (...args) => { // eslint-disable-next-line @typescript-eslint/consistent-type-imports let { remixVitePlugin } = require("./plugin") as typeof import("./plugin"); return remixVitePlugin(...args); }; - -// We rename this export because from a consumer's perspective this is the -// "server build" since they also provide their own server entry -export const unstable_viteServerBuildModuleId = serverEntryId; diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index 04e8debb9a6..df8d1e5758b 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -28,7 +28,6 @@ import invariant from "../invariant"; import { createRequestHandler } from "./node/adapter"; import { getStylesForUrl, isCssModulesFile } from "./styles"; import * as VirtualModule from "./vmod"; -import { serverEntryId } from "./server-entry-id"; import { resolveFileUrl } from "./resolve-file-url"; import { removeExports } from "./remove-exports"; import { replaceImportSpecifier } from "./replace-import-specifier"; @@ -101,6 +100,7 @@ export type ResolvedRemixVitePluginConfig = Pick< | "serverModuleFormat" >; +let serverBuildId = VirtualModule.id("server-build"); let serverManifestId = VirtualModule.id("server-manifest"); let browserManifestId = VirtualModule.id("browser-manifest"); let remixReactProxyId = VirtualModule.id("remix-react-proxy"); @@ -121,7 +121,7 @@ const resolveRelativeRouteFilePath = ( return vite.normalizePath(fullPath); }; -let vmods = [serverEntryId, serverManifestId, browserManifestId]; +let vmods = [serverBuildId, serverManifestId, browserManifestId]; const getHash = (source: BinaryLike, maxLength?: number): string => { let hash = createHash("sha256").update(source).digest("hex"); @@ -629,7 +629,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { rollupOptions: { ...viteUserConfig.build?.rollupOptions, preserveEntrySignatures: "exports-only", - input: serverEntryId, + input: serverBuildId, output: { entryFileNames: path.basename( pluginConfig.serverBuildPath @@ -822,7 +822,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { viteDevServer.middlewares.use(async (req, res, next) => { try { let build = (await viteDevServer.ssrLoadModule( - serverEntryId + serverBuildId )) as ServerBuild; let handle = createRequestHandler(build, { @@ -924,7 +924,7 @@ export const remixVitePlugin: RemixVitePlugin = (options = {}) => { }, async load(id) { switch (id) { - case VirtualModule.resolve(serverEntryId): { + case VirtualModule.resolve(serverBuildId): { return await getServerEntry(); } case VirtualModule.resolve(serverManifestId): { diff --git a/packages/remix-dev/vite/server-entry-id.ts b/packages/remix-dev/vite/server-entry-id.ts deleted file mode 100644 index 6e333c16195..00000000000 --- a/packages/remix-dev/vite/server-entry-id.ts +++ /dev/null @@ -1,5 +0,0 @@ -// This file allows us to export the module ID without forcing non-Vite -// consumers to inadvertently import the Vite plugin and all of its dependencies -import * as VirtualModule from "./vmod"; - -export const serverEntryId = VirtualModule.id("server-entry"); diff --git a/packages/remix-dev/vite/vmod.ts b/packages/remix-dev/vite/vmod.ts index eb32dbb2e89..50050691220 100644 --- a/packages/remix-dev/vite/vmod.ts +++ b/packages/remix-dev/vite/vmod.ts @@ -1,3 +1,3 @@ -export let id = (name: string) => `virtual:${name}`; +export let id = (name: string) => `virtual:remix/${name}`; export let resolve = (id: string) => `\0${id}`; export let url = (id: string) => `/@id/__x00__${id}`; diff --git a/templates/unstable-vite-express/server.mjs b/templates/unstable-vite-express/server.mjs index 10eca9cfe80..704d2f36097 100644 --- a/templates/unstable-vite-express/server.mjs +++ b/templates/unstable-vite-express/server.mjs @@ -1,4 +1,3 @@ -import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; import { createRequestHandler } from "@remix-run/express"; import { installGlobals } from "@remix-run/node"; import express from "express"; @@ -34,7 +33,7 @@ app.all( "*", createRequestHandler({ build: vite - ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId) + ? () => vite.ssrLoadModule("virtual:remix/server-build") : await import("./build/server/index.js"), }) );