@antdevx/vite-plugin-hmr-sync
Version:
A Vite plugin for synchronizing HMR across multiple workspaces in a monorepo setup.
231 lines (168 loc) β’ 6.89 kB
Markdown
# π @antdevx/vite-plugin-hmr-sync
A minimal and powerful Vite plugin that **synchronizes Hot Module Reloading (HMR)** across multiple Vite apps β perfect for **micro-frontends**, **monorepos**, or **Module Federation** setups.
> When one app rebuilds, others automatically reload in development. No manual refresh, no stale modules.
## π§ Use Case: Micro-Frontend in Dev Mode
You have:
- A **Host App** that dynamically loads **Remote Apps** using Module Federation or import maps.
- All apps run separately using their own `vite dev` servers.
- You want the **Host** to automatically reload when a **Remote** rebuilds.
Without this plugin:
You must manually reload the browser to see updates from the remote.
**With this plugin:**
1. **Remote App** uses `notifyOnRebuild()` to ping the host when it finishes rebuilding.
2. **Host App** uses `listenForRemoteRebuilds()` to receive the ping and trigger a hot reload.
> π₯ You stay in sync across apps in development β like magic.
## π¦ Installation
```bash
npm install @antdevx/vite-plugin-hmr-sync --save-dev
```
## π§© Example Setup
### π Project Structure
```bash
.
βββ host-app/
β βββ vite.config.ts
β
βββ remote-app/
βββ vite.config.ts
```
### π Host App Setup
```ts
// host-app/vite.config.ts
import { defineConfig } from 'vite';
import { listenForRemoteRebuilds } from '@antdevx/vite-plugin-hmr-sync';
export default defineConfig({
plugins: [
listenForRemoteRebuilds({
allowedApps: ['remote-app'],
endpoint: '/on-child-rebuild',
hotPayload: { type: 'full-reload', path: '*' },
onRebuild: (appName) => {
console.log(`[host-app] π Triggered by: ${appName}`);
}
})
],
server: {
port: 5173
}
});
```
### π Remote App Setup
```ts
// remote-app/vite.config.ts
import { defineConfig } from 'vite';
import { notifyOnRebuild } from '@antdevx/vite-plugin-hmr-sync';
export default defineConfig({
plugins: [
notifyOnRebuild({
appName: 'remote-app',
hostUrl: 'http://localhost:5173', // Host app's dev server
endpoint: '/on-child-rebuild',
notifyOnSuccessOnly: true
})
],
server: {
port: 5174
}
});
```
## βοΈ API Reference
### `listenForRemoteRebuilds(options)`
Listens for incoming HTTP requests from other apps to trigger HMR.
| Option | Type | Default | Description |
|------------------|---------------------------|----------------------------------|-------------|
| `endpoint` | `string` | `'/on-child-rebuild'` | Path to listen for rebuild requests |
| `allowedApps` | `string[]` | `undefined` | Apps allowed to trigger rebuild |
| `hotPayload` | `HMRPayload` | `{ type: 'full-reload', path: '*' }` | HMR payload sent to Vite client |
| `onRebuild` | `(appName, server) => {}` | `undefined` | Callback after rebuild |
| `suppressLogs` | `boolean` | `false` | Hide logs |
### `notifyOnRebuild(options | appName)`
Notifies a remote server (e.g., host app) after a successful rebuild.
| Option | Type | Default | Description |
|----------------------|-----------|--------------------------------|-------------|
| `appName` | `string` | _Required_ | Name of the app notifying |
| `hostUrl` | `string` | `'http://127.0.0.1:9000'` | URL of host to notify |
| `endpoint` | `string` | `'/on-child-rebuild'` | Path to ping on host |
| `method` | `string` | `'GET'` | HTTP method used |
| `notifyOnSuccessOnly`| `boolean` | `true` | Skip if build fails |
| `suppressLogs` | `boolean` | `false` | Hide logs |
## π Nodemon + HMR Sync Setup
Use `startBuildAndServer()` to auto-build and serve your app with rebuild notifications.
### π§ `nodemon.json` Example
```json
{
"watch": [
"src",
"quasar.config.ts"
],
"ext": "js,ts,vue,scss,json",
"exec": "node -e \"import('@antdevx/vite-plugin-hmr-sync').then(m => m.startBuildAndServer())\"",
"hmrSync": {
"port": 5002,
"notify": true,
"hostUrl": "http://localhost:5000",
"appName": "todo-form",
"buildCommand": "quasar build",
"serveCommand": "quasar serve"
}
}
```
### π `package.json`
```json
"scripts": {
"build:watch": "nodemon"
}
```
## π Available `hmrSync` / `startBuildAndServer()` Options
| Option | Type | Default | Description |
|----------------|-----------|------------------|-------------|
| `notify` | `boolean` | `true` | Whether to notify the host after successful rebuild. |
| `hostUrl` | `string` | β | The full URL of the host app to notify (e.g. `http://localhost:5000`). |
| `appName` | `string` | β | Name of your app. Used in the query string to identify rebuild origin. |
| `port` | `string` | β | Port number to serve your local dev preview. |
| `cache` | `string` | `'0'` | Time (in seconds) to cache the static files. `0` means no caching. |
| `cors` | `boolean` | `true` | Enable CORS headers for the dev server. |
| `buildCommand` | `string` | `'quasar build'` or `'vite build'` | Command used to build the app before serving. |
| `serveCommand` | `string` | `'quasar serve'` or `'vite preview'` | Command used to start the static server after build. |
## π Workflow Overview
```
[remote-app] buildEnd() π
β
Sends request to host endpoint `/on-child-rebuild?app=remote-app`
β
[host-app] listens and validates app name
β
Triggers Vite's `server.ws.send(hotPayload)` β π Full page reload
```
## π₯ͺ Development Tips
- Use different ports for each app in `vite.config.ts`.
- Ensure app names match in `notifyOnRebuild(appName)` and `allowedApps` on the host.
- Combine with Viteβs native `server.proxy` to load remotes via `localhost`.
## π‘ Troubleshooting
| Problem | Fix |
|--------|-----|
| Nothing reloads | Make sure the host server and endpoint are reachable from the remote. |
| 403 Forbidden | Ensure `allowedApps` includes the correct `appName`. |
| Silent fails | Set `suppressLogs: false` to enable debugging logs. |
| Partial updates not working | Try changing `hotPayload` from `'full-reload'` to a more specific HMR type. |
## π₯ Contributors
Maintained by [@antdevx](https://github.com/antdevx)
## π License
MIT Β© antdevx
## π Like it?
Star β the repo and share with others using Vite and micro-frontends!