Skip to content

Instantly share code, notes, and snippets.

@cpojer
Last active July 29, 2024 06:13
Show Gist options
  • Save cpojer/b07a7b512f03c0b1692e35dfb94da90b to your computer and use it in GitHub Desktop.
Save cpojer/b07a7b512f03c0b1692e35dfb94da90b to your computer and use it in GitHub Desktop.
When using `vite-node` with http servers, any HMR update will crash the process because the port is in use. This code can be inserted at the top-level of your script to gracefully stop the previous server instance before starting the new one.
#!/usr/bin/env node_modules/.bin/vite-node --watch
// `vite-node` HMR handler for servers.
type TeardownCallback = () => Promise<void>;
type Listener = () => TeardownCallback;
declare global {
// eslint-disable-next-line no-var
var __HMR__: {
listeners: ReadonlyArray<Listener>;
teardownCallbacks: ReadonlyArray<TeardownCallback>;
};
}
const key = '__HMR__';
function register(listener: Listener) {
if (import.meta.hot) {
import.meta.hot.accept(async () => {
const hmr = global[key];
const teardownCallbacks = hmr.teardownCallbacks.map((fn) => fn());
hmr.teardownCallbacks = [];
await Promise.all(teardownCallbacks);
hmr.teardownCallbacks = hmr.listeners.map((listener) => listener());
hmr.listeners = [];
});
} else {
listener();
return;
}
if (!global[key]) {
const teardown = listener();
Object.defineProperty(global, key, {
value: {
listeners: [],
teardownCallbacks: [teardown],
},
});
} else {
global[key].listeners = [...global[key].listeners, listener];
}
}
register(() => {
httpServer.listen(port);
return () => new Promise((resolve) => httpServer.close(() => resolve()));
});
@paynecodes
Copy link

@cpojer I've been scouring the internet for something like this. How's this treating you in 2024?

@Eflyax
Copy link

Eflyax commented Jul 23, 2024

Not working for me. Variable import.meta is undefined in my code.

@cpojer
Copy link
Author

cpojer commented Jul 29, 2024

Sorry, I didn't notice the comments on this gist. I could never get vite-node to work well for me. I'm using ts-node together with swc, see https://cpojer.net/posts/fastest-frontend-tooling-in-2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment