Skip to content

Instantly share code, notes, and snippets.

@mildronize
Forked from cpojer/index.ts
Created March 23, 2023 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mildronize/2a7df8ea0c9b133857b45500473b7cfc to your computer and use it in GitHub Desktop.
Save mildronize/2a7df8ea0c9b133857b45500473b7cfc 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()));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment