Skip to content

Commit

Permalink
vite: typesafe server build
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori committed Feb 22, 2024
1 parent dc5cdb7 commit 4106883
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 10 deletions.
6 changes: 2 additions & 4 deletions integration/helpers/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const EXPRESS_SERVER = (args: {
}) =>
String.raw`
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";
import { installGlobals, getServerBuild } from "@remix-run/node";
import express from "express";
installGlobals();
Expand Down Expand Up @@ -71,9 +71,7 @@ export const EXPRESS_SERVER = (args: {
app.all(
"*",
createRequestHandler({
build: viteDevServer
? () => viteDevServer.ssrLoadModule("virtual:remix/server-build")
: await import("./build/index.js"),
build: await getServerBuild("./build/server/index.js", viteDevServer),
getLoadContext: () => (${JSON.stringify(args.loadContext ?? {})}),
})
);
Expand Down
6 changes: 2 additions & 4 deletions integration/vite-basename-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const customServerFile = ({

return String.raw`
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";
import { installGlobals, getServerBuild } from "@remix-run/node";
import express from "express";
installGlobals();
Expand All @@ -115,9 +115,7 @@ const customServerFile = ({
app.all(
"${basename}*",
createRequestHandler({
build: viteDevServer
? () => viteDevServer.ssrLoadModule("virtual:remix/server-build")
: await import("./build/server/index.js"),
build: await getServerBuild("./build/server/index.js", viteDevServer),
})
);
app.get("*", (_req, res) => {
Expand Down
1 change: 1 addition & 0 deletions packages/remix-cloudflare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export {
defer,
broadcastDevReady,
logDevReady,
getServerBuild,
isCookie,
isSession,
json,
Expand Down
1 change: 1 addition & 0 deletions packages/remix-deno/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
broadcastDevReady,
createSession,
defer,
getServerBuild,
isCookie,
isSession,
json,
Expand Down
1 change: 1 addition & 0 deletions packages/remix-node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export {
defer,
broadcastDevReady,
logDevReady,
getServerBuild,
isCookie,
isSession,
json,
Expand Down
15 changes: 15 additions & 0 deletions packages/remix-server-runtime/__tests__/build-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getServerBuild } from "../build";

it("getServerBuild throws when path is relative", async () => {
await expect(() => getServerBuild("./build/server/index.js")).rejects.toThrow(
"Server build path must be absolute, but received relative path: ./build/server/index.js"
);
});

it("getServerBuild throws when build does not exist", async () => {
await expect(() =>
getServerBuild("/this/path/doesnt/exist.js")
).rejects.toThrow(
"Could not import server build from '/this/path/doesnt/exist.js'. Did you forget to run 'remix vite:build' first?"
);
});
33 changes: 33 additions & 0 deletions packages/remix-server-runtime/build.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
import type { ViteDevServer } from "vite";
import path from "pathe";

import type { ActionFunctionArgs, LoaderFunctionArgs } from "./routeModules";
import type { AssetsManifest, EntryContext, FutureConfig } from "./entry";
import type { ServerRouteManifest } from "./routes";
import type { AppLoadContext } from "./data";

export async function getServerBuild(
buildPath: string,
{
viteDevServer,
}: {
viteDevServer?: ViteDevServer;
} = {}
): Promise<ServerBuild | (() => Promise<ServerBuild>)> {
if (viteDevServer) {
return () =>
viteDevServer.ssrLoadModule(
"virtual:remix/server-build"
) as Promise<ServerBuild>;
}

if (!path.isAbsolute(buildPath)) {
throw new Error(
`Server build path must be absolute, but received relative path: ${buildPath}`
);
}

// Convert file path meant for `import` to URL for Windows compatibility
let buildURL = "file:///" + encodeURI(buildPath);
return import(buildURL).catch(() => {
throw Error(
`Could not import server build from '${buildPath}'. Did you forget to run 'remix vite:build' first?`
);
});
}

// NOTE: IF you modify `ServerBuild`, be sure to modify the
// `remix-dev/server-build.ts` file to reflect the new field as well

Expand Down
1 change: 1 addition & 0 deletions packages/remix-server-runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ export type {
UploadHandler,
UploadHandlerPart,
} from "./reexport";
export { getServerBuild } from "./reexport";
10 changes: 8 additions & 2 deletions packages/remix-server-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,25 @@
"@types/cookie": "^0.6.0",
"@web3-storage/multipart-parser": "^1.0.0",
"cookie": "^0.6.0",
"pathe": "^1.1.2",
"set-cookie-parser": "^2.4.8",
"source-map": "^0.7.3"
},
"devDependencies": {
"@types/set-cookie-parser": "^2.4.1",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"vite": "^5.1.0"
},
"peerDependencies": {
"typescript": "^5.1.0"
"typescript": "^5.1.0",
"vite": "^5.1.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
},
"vite": {
"optional": true
}
},
"engines": {
Expand Down
1 change: 1 addition & 0 deletions packages/remix-server-runtime/reexport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type {
ServerBuild,
ServerEntryModule,
} from "./build";
export { getServerBuild } from "./build";

export type { UploadHandlerPart, UploadHandler } from "./formData";
export type {
Expand Down
1 change: 1 addition & 0 deletions packages/remix-server-runtime/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"lib": ["ES2022"],
"target": "ES2022",
"composite": true,
"module": "ESNext",

"moduleResolution": "Bundler",
"allowSyntheticDefaultImports": true,
Expand Down
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10747,6 +10747,11 @@ pathe@^1.0.0, pathe@^1.1.0:
resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.0.tgz#e2e13f6c62b31a3289af4ba19886c230f295ec03"
integrity sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==

pathe@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==

peek-stream@^1.1.0:
version "1.1.3"
resolved "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz"
Expand Down Expand Up @@ -13494,6 +13499,17 @@ vite@5.1.3:
optionalDependencies:
fsevents "~2.3.2"

vite@^5.1.0:
version "5.1.4"
resolved "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz#14e9d3e7a6e488f36284ef13cebe149f060bcfb6"
integrity sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==
dependencies:
esbuild "^0.19.3"
postcss "^8.4.35"
rollup "^4.2.0"
optionalDependencies:
fsevents "~2.3.3"

w3c-xmlserializer@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073"
Expand Down

0 comments on commit 4106883

Please sign in to comment.