Skip to content

Commit b5047d6

Browse files
committed
feature: switch to vite compiler
1 parent 6b56008 commit b5047d6

File tree

6 files changed

+304
-202
lines changed

6 files changed

+304
-202
lines changed

apps/webapp/remix.config.js

Lines changed: 0 additions & 31 deletions
This file was deleted.

apps/webapp/remix.env.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

apps/webapp/server.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import compression from "compression";
2+
import express from "express";
3+
import morgan from "morgan";
4+
5+
const BUILD_PATH = "./build/server/index.js";
6+
const app = express();
7+
const MODE = process.env.NODE_ENV;
8+
const port = process.env.REMIX_APP_PORT || process.env.PORT || 3000;
9+
10+
// Basic middleware setup
11+
if (process.env.DISABLE_COMPRESSION !== "1") {
12+
app.use(compression());
13+
}
14+
15+
app.disable("x-powered-by");
16+
17+
// Security and URL cleanup middleware
18+
app.use((req, res, next) => {
19+
res.set("Strict-Transport-Security", `max-age=${60 * 60 * 24 * 365 * 100}`);
20+
if (req.path.endsWith("/") && req.path.length > 1) {
21+
const query = req.url.slice(req.path.length);
22+
const safepath = req.path.slice(0, -1).replace(/\/+/g, "/");
23+
res.redirect(301, safepath + query);
24+
return;
25+
}
26+
next();
27+
});
28+
29+
// Only configure the app if HTTP server is enabled
30+
if (process.env.HTTP_SERVER_DISABLED !== "true") {
31+
if (MODE === "development") {
32+
async function createViteServer() {
33+
const vite = await import("vite");
34+
const viteServer = await vite.createServer({
35+
server: { middlewareMode: true },
36+
appType: "custom",
37+
});
38+
39+
app.use(viteServer.middlewares);
40+
41+
// Import the app from the server/app.ts file
42+
// The server.ts stuff that imports from the app has been turned into a middleware
43+
// This allows Vite to bundle it and then we import it here
44+
app.use(async (req, res, next) => {
45+
try {
46+
/** @type {import("./server/app.ts")} */
47+
const source = await viteServer.ssrLoadModule("./server/app.ts");
48+
49+
return source.app(req, res, next);
50+
} catch (error) {
51+
if (error instanceof Error) {
52+
viteServer.ssrFixStacktrace(error);
53+
}
54+
next(error);
55+
}
56+
});
57+
}
58+
59+
await createViteServer().catch((err) => {
60+
console.error("Error setting up Vite dev server:", err);
61+
});
62+
} else {
63+
console.log("Starting production server");
64+
app.use("/assets", express.static("build/client/assets", { immutable: true, maxAge: "1y" }));
65+
app.use(express.static("build/client", { maxAge: "1h" }));
66+
67+
// Imports `app` export from './server/app.ts'
68+
app.use(await import(BUILD_PATH).then((mod) => mod.app));
69+
}
70+
71+
if (process.env.DASHBOARD_AND_API_DISABLED === "true") {
72+
app.get("/healthcheck", (_, res) => res.status(200).send("OK"));
73+
}
74+
}
75+
76+
app.use(
77+
morgan("tiny", {
78+
skip: (req) => {
79+
// Vite dev server logs /@fs/ requests and hot reloads for specific files
80+
// Unsure if this is the best way to suppress them from logs
81+
if (req.url.startsWith("/@")) return true;
82+
if (req.url.match(/\.[jt]sx?$/)) return true;
83+
return false;
84+
},
85+
})
86+
);
87+
88+
const server = app.listen(port, async () => {
89+
try {
90+
// Ping the server and send an initial request
91+
// That will trigger the Remix handler and should guarantee that Remix will break immediately if there's an issue
92+
await performHealthcheck(port);
93+
console.log(`✅ server ready: http://localhost:${port} [NODE_ENV: ${MODE}]`);
94+
} catch (error) {
95+
console.error("Server started but healthcheck failed:", error);
96+
process.exit(1);
97+
}
98+
});
99+
100+
// Server cleanup
101+
server.keepAliveTimeout = 65 * 1000;
102+
103+
process.on("SIGTERM", () => {
104+
server.close((err) => {
105+
if (err) {
106+
console.error("Error closing express server:", err);
107+
} else {
108+
console.log("Express server closed gracefully.");
109+
}
110+
});
111+
});
112+
113+
async function performHealthcheck(port, retries = 5, delay = 1000) {
114+
for (let i = 0; i < retries; i++) {
115+
try {
116+
const res = await fetch(`http://localhost:${port}/`);
117+
118+
if (!res.ok) {
119+
throw new Error(`Healthcheck failed with status ${res.status}`);
120+
}
121+
122+
return res.text();
123+
} catch (error) {
124+
if (i === retries - 1) throw error;
125+
await new Promise((resolve) => setTimeout(resolve, delay));
126+
}
127+
}
128+
}

apps/webapp/server.ts

Lines changed: 0 additions & 169 deletions
This file was deleted.

0 commit comments

Comments
 (0)