Skip to content

Commit 05c0f55

Browse files
feat: add option reactRefreshPrefix for HMR module federation
1 parent 099719f commit 05c0f55

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

packages/common/refresh-utils.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function addRefreshWrapper<M extends { mappings: string } | undefined>(
1919
map: M | string,
2020
pluginName: string,
2121
id: string,
22+
reactRefreshHost?: string
2223
): { code: string; map: M | string } {
2324
const hasRefresh = refreshContentRE.test(code)
2425
const onlyReactComp = !hasRefresh && reactCompRE.test(code)
@@ -55,7 +56,7 @@ if (import.meta.hot && !inWebWorker) {
5556
}
5657
}
5758

58-
newCode = `import * as RefreshRuntime from "${runtimePublicPath}";
59+
newCode = `import * as RefreshRuntime from "${reactRefreshHost ?? ''}${runtimePublicPath}";
5960
const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
6061
6162
${newCode}

packages/plugin-react/CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
## Unreleased
44

5+
### Add option `reactRefreshHost`
6+
7+
Add option `reactRefreshHost` to set React refresh runtime url prefix.
8+
This is useful in module federation context to enable HMR by setting the host url on a vite config which is serving a remote app.
9+
See full discussion here: https://github.com/module-federation/vite/issues/183#issuecomment-2751825367
10+
11+
```ts
12+
export default defineConfig({
13+
plugins: [react({ reactRefreshHost: 'http://localhost:3000' })],
14+
})
15+
```
16+
517
## 4.3.4 (2024-11-26)
618

719
### Add Vite 6 to peerDependencies range

packages/plugin-react/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ This option does not enable _code transformation_. That is handled by esbuild.
9494

9595
Here's the [complete list of Babel parser plugins](https://babeljs.io/docs/en/babel-parser#ecmascript-proposalshttpsgithubcombabelproposals).
9696

97+
### reactRefreshHost
98+
99+
The `reactRefreshHost` option is only necessary in a module federation context. It allows HMR to work between a remote & host server. In your remote vite config you would add your host origin:
100+
101+
```js
102+
react({ reactRefreshHost: 'http://localhost:3000' })
103+
```
104+
105+
Under the hood this simply updates the react refresh url from "/@react-refresh" to "http://localhost:3000/@react-refresh" allowing HMR updates to flow from your remote to your host.
106+
97107
## Middleware mode
98108

99109
In [middleware mode](https://vite.dev/config/server-options.html#server-middlewaremode), you should make sure your entry `index.html` file is transformed by Vite. Here's an example for an Express server:

packages/plugin-react/src/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ export interface Options {
4444
babel?:
4545
| BabelOptions
4646
| ((id: string, options: { ssr?: boolean }) => BabelOptions)
47+
/**
48+
* React refresh runtime url prefix.
49+
* Useful in module federation context to enable HMR by
50+
* setting the host url on a vite config which is serving a remote app.
51+
* @example
52+
* reactRefreshHost: 'http://localhost:3000'
53+
*/
54+
reactRefreshHost?: string
4755
}
4856

4957
export type BabelOptions = Omit<
@@ -258,6 +266,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
258266
result.map ?? undefined,
259267
'@vitejs/plugin-react',
260268
id,
269+
opts.reactRefreshHost
261270
)
262271
}
263272
},

0 commit comments

Comments
 (0)