-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathserver.js
105 lines (82 loc) · 2.9 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import url from "node:url";
import fs from "node:fs";
import fastify from "fastify";
import {
createRequestHandler,
staticFilePlugin,
getEarlyHintLinks,
} from "@mcansh/remix-fastify";
import { installGlobals, broadcastDevReady } from "@remix-run/node";
import sourceMapSupport from "source-map-support";
import { fastifyEarlyHints } from "@fastify/early-hints";
sourceMapSupport.install();
installGlobals();
let BUILD_PATH = "./build/index.mjs";
/** @typedef {import('@remix-run/node').ServerBuild} ServerBuild */
let initialBuild = await import(BUILD_PATH);
let app = fastify();
let noopContentParser = (_request, payload, done) => {
done(null, payload);
};
app.addContentTypeParser("application/json", noopContentParser);
app.addContentTypeParser("*", noopContentParser);
await app.register(fastifyEarlyHints, { warn: true });
// match with remix.config
app.register(staticFilePlugin, {
assetsBuildDirectory: "public/build",
publicPath: "/build/",
});
app.all("*", async (request, reply) => {
if (process.env.NODE_ENV === "development") {
let devHandler = await createDevRequestHandler(initialBuild);
return devHandler(request, reply);
}
let links = getEarlyHintLinks(request, initialBuild);
await reply.writeEarlyHintsLinks(links);
return createRequestHandler({
build: initialBuild,
mode: initialBuild.mode,
})(request, reply);
});
let port = process.env.PORT ? Number(process.env.PORT) || 3000 : 3000;
let address = await app.listen({ port, host: "0.0.0.0" });
console.log(`✅ app ready: ${address}`);
if (process.env.NODE_ENV === "development") {
broadcastDevReady(initialBuild);
}
/**
* @param {ServerBuild} initialBuild
* @param {import('@mcansh/remix-fastify').GetLoadContextFunction} [getLoadContext]
* @returns {import('@remix-run/express').RequestHandler}
*/
async function createDevRequestHandler(initialBuild, getLoadContext) {
let build = initialBuild;
async function handleServerUpdate() {
// 1. re-import the server build
build = await reimportServer();
// 2. tell Remix that this app server is now up-to-date and ready
broadcastDevReady(build);
}
let chokidar = await import("chokidar");
chokidar
.watch(BUILD_PATH, { ignoreInitial: true })
.on("add", handleServerUpdate)
.on("change", handleServerUpdate);
return async (request, reply) => {
let links = getEarlyHintLinks(request, build);
await reply.writeEarlyHintsLinks(links);
return createRequestHandler({
build: await build,
getLoadContext,
mode: "development",
})(request, reply);
};
}
/** @returns {Promise<ServerBuild>} */
async function reimportServer() {
let stat = fs.statSync(BUILD_PATH);
// convert build path to URL for Windows compatibility with dynamic `import`
let BUILD_URL = url.pathToFileURL(BUILD_PATH).href;
// use a timestamp query parameter to bust the import cache
return import(BUILD_URL + "?t=" + stat.mtimeMs);
}