Remix Vite Express and Nodemon #9705
-
When you set up a new project using Remix, Vite and Express template, what's the recommended modern best practice for handling the server.js file? Is it something like nodemon or PM2? I assume Vite cannot also watch server.js and do a full restart of the server since Vite is just an Express middleware? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 4 replies
-
You're correct! In Remix with the Vite and Express template, there's no need for a separate process manager like nodemon or PM2 to watch server.js. Here's how Remix handles it with best practices:
As for the server.js file it shouldn't contain complex logic or business logic, its primary role is to configure Remix and set up the Express server. |
Beta Was this translation helpful? Give feedback.
-
You can use a number of options, tsx is a very popular one such as used in the epic-web stack. ts-node is another popular option as seen in xHomu's template here. A less popular option I personally really like is vite-node since it aligns with using vite for the dev server, can share vite config, use vite plugins and supports fast HMR of the server.ts code. Try them all and see which you prefer. // package.json
"scripts": {
"dev": "vite-node --watch ./server.ts"
... One complexity with vite-node is that to support HMR you need to cleanup any resources before they are re-initialized on HMR in the "vite:beforeFullReload" hook, such as releasing server ports. // server.ts
// Vite-Node HMR hooks
if (import.meta.hot) {
// Before we reload the application, ensure that we stop the running servers to release ports.
import.meta.hot.on("vite:beforeFullReload", async () => {
console.info("[HMR] Restarting Server");
await attemptGracefulShutdown();
});
}
const attemptGracefulShutdown = async () => {
if (viteDevServer) {
viteDevServer.close();
}
async function closeServer(server: http.Server) {
return new Promise((resolve, reject) => {
if (server?.listening) {
server.close((e) => (e ? reject(e) : resolve("ok")));
} else {
resolve("ok");
}
});
}
// server is a global variable set by server = app.listen(port, () => {
await closeServer(server);
}; |
Beta Was this translation helpful? Give feedback.
-
if u are using node just use the new built in e.g: node --watch ./server.mjs or if using ts node --watch --experimental-strip-types ./server.mts |
Beta Was this translation helpful? Give feedback.
-
@jrestall-finact this is great for dev. But how do you make sure the const remixHandler = createRequestHandler({
build: (viteDevServer
? () => viteDevServer.ssrLoadModule("virtual:remix/server-build")
: await import("./build/server/index.js")) as unknown as ServerBuild,
}); |
Beta Was this translation helpful? Give feedback.
You can use a number of options, tsx is a very popular one such as used in the epic-web stack. ts-node is another popular option as seen in xHomu's template here.
A less popular option I personally really like is vite-node since it aligns with using vite for the dev server, can share vite config, use vite plugins and supports fast HMR of the server.ts code. Try them all and see which you prefer.
One complexity with vite-node is that to support HMR you need to cleanup any resources before they are re-initialized on HMR in the "vite:beforeFullReload" hook, such as releasing server ports.