Skip to content

Commit

Permalink
fix(remix-dev/vite): remove Vite wrapper functions (#8120)
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish authored Nov 26, 2023
1 parent a704b26 commit 497eea8
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 59 deletions.
47 changes: 47 additions & 0 deletions .changeset/hungry-buckets-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
"@remix-run/dev": patch
---

Remove `unstable_createViteServer` and `unstable_loadViteServerBuild` which were only minimal wrappers around Vite's `createServer` and `ssrLoadModule` functions when using a custom server.

**This is a breaking change for projects using the unstable Vite plugin with a custom server.**

Instead, we now provide `unstable_viteServerBuildModuleId` so that custom servers interact with Vite directly rather than via Remix APIs, for example:

```diff
-import {
- unstable_createViteServer,
- unstable_loadViteServerBuild,
-} from "@remix-run/dev";
+import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
```

Creating the Vite server in middleware mode:

```diff
const vite =
process.env.NODE_ENV === "production"
? undefined
- : await unstable_createViteServer();
+ : await import("vite").then(({ createServer }) =>
+ createServer({
+ server: {
+ middlewareMode: true,
+ },
+ })
+ );
```

Loading the Vite server build in the request handler:

```diff
app.all(
"*",
createRequestHandler({
build: vite
- ? () => unstable_loadViteServerBuild(vite)
+ ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
: await import("./build/server/index.js"),
})
);
```
31 changes: 17 additions & 14 deletions docs/future/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,29 +163,23 @@ You'll also need to update to the new build output paths, which are `build/serve

#### Migrating from a custom server

If you were using a custom server in development, you'll 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.

You'll also need to edit your custom server to use Vite's `connect` middleware.
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.

Remix exposes APIs for exactly this purpose:
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`.

```ts
import {
unstable_createViteServer, // provides middleware for handling asset requests
unstable_loadViteServerBuild, // handles initial render requests
} from "@remix-run/dev";
import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
```

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-4,11-14,18-21,29,36-38]
import {
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "@remix-run/dev";
import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";
import express from "express";
Expand All @@ -195,7 +189,13 @@ installGlobals();
const vite =
process.env.NODE_ENV === "production"
? undefined
: await unstable_createViteServer();
: await import("vite").then(({ createServer }) =>
createServer({
server: {
middlewareMode: true,
},
})
);

const app = express();

Expand All @@ -218,7 +218,10 @@ app.all(
"*",
createRequestHandler({
build: vite
? () => unstable_loadViteServerBuild(vite)
? () =>
vite.ssrLoadModule(
unstable_viteServerBuildModuleId
)
: await import("./build/server/index.js"),
})
);
Expand Down
19 changes: 10 additions & 9 deletions integration/helpers/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ export const EXPRESS_SERVER = (args: {
loadContext?: Record<string, unknown>;
}) =>
String.raw`
import {
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "@remix-run/dev";
import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";
import express from "express";
Expand All @@ -48,25 +45,29 @@ export const EXPRESS_SERVER = (args: {
let vite =
process.env.NODE_ENV === "production"
? undefined
: await unstable_createViteServer();
: await import("vite").then(({ createServer }) =>
createServer({
server: { middlewareMode: true },
})
);
const app = express();
if (vite) {
app.use(vite.middlewares);
} else {
app.use(
"/build",
express.static("public/build", { immutable: true, maxAge: "1y" })
"/assets",
express.static("build/client/assets", { immutable: true, maxAge: "1y" })
);
}
app.use(express.static("public", { maxAge: "1h" }));
app.use(express.static("build/client", { maxAge: "1h" }));
app.all(
"*",
createRequestHandler({
build: vite
? () => unstable_loadViteServerBuild(vite)
? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
: await import("./build/index.js"),
getLoadContext: () => (${JSON.stringify(args.loadContext ?? {})}),
})
Expand Down
6 changes: 1 addition & 5 deletions packages/remix-dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,4 @@ export * as cli from "./cli/index";

export type { Manifest as AssetsManifest } from "./manifest";
export { getDependenciesToBundle } from "./dependencies";
export {
unstable_vitePlugin,
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "./vite";
export { unstable_vitePlugin, unstable_viteServerBuildModuleId } from "./vite";
19 changes: 4 additions & 15 deletions packages/remix-dev/vite/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
// This file allows us to dynamically require the plugin so non-Vite consumers
// don't need to have Vite installed as a peer dependency. Only types should
// be imported at the top level.
import type { ViteDevServer } from "vite";

import type { RemixVitePlugin } from "./plugin";
import { id } from "./vmod";
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);
};

export const unstable_createViteServer = async () => {
let vite = await import("vite");
return vite.createServer({
server: {
middlewareMode: true,
},
});
};

export const unstable_loadViteServerBuild = async (vite: ViteDevServer) => {
return vite.ssrLoadModule(id("server-entry"));
};
// 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;
2 changes: 1 addition & 1 deletion packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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 { removeExports } from "./remove-exports";
import { replaceImportSpecifier } from "./replace-import-specifier";

Expand Down Expand Up @@ -88,7 +89,6 @@ type ResolvedRemixVitePluginConfig = Pick<
| "serverModuleFormat"
>;

let serverEntryId = VirtualModule.id("server-entry");
let serverManifestId = VirtualModule.id("server-manifest");
let browserManifestId = VirtualModule.id("browser-manifest");
let remixReactProxyId = VirtualModule.id("remix-react-proxy");
Expand Down
5 changes: 5 additions & 0 deletions packages/remix-dev/vite/server-entry-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// 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");
9 changes: 0 additions & 9 deletions templates/unstable-vite-express/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@ npm run start

## Customize

Remix exposes APIs for integrating Vite with a custom server:

```ts
import {
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "@remix-run/dev";
```

In this template, we'll use Express but remember that these APIs can be used with _any_ Node-compatible server setup that supports standard middleware.

[remix-vite-docs]: https://remix.run/docs/en/main/future/vite
15 changes: 9 additions & 6 deletions templates/unstable-vite-express/server.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "@remix-run/dev";
import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";
import express from "express";
Expand All @@ -11,7 +8,13 @@ installGlobals();
const vite =
process.env.NODE_ENV === "production"
? undefined
: await unstable_createViteServer();
: await import("vite").then(({ createServer }) =>
createServer({
server: {
middlewareMode: true,
},
})
);

const app = express();

Expand All @@ -31,7 +34,7 @@ app.all(
"*",
createRequestHandler({
build: vite
? () => unstable_loadViteServerBuild(vite)
? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
: await import("./build/server/index.js"),
})
);
Expand Down

0 comments on commit 497eea8

Please sign in to comment.