Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ jobs:
build-systems/nx-rspack-mf
build-systems/turborepo-rspack-mf
module-federation/airbnb-clone
module-federation/react-rsbuild-monorepo
module-federation/react-vite-rspack-webpack
)
for example in "${standalone[@]}"; do
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/rsbuild-mf-live-fixture.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Rsbuild Module Federation live fixture

on:
workflow_dispatch:
schedule:
- cron: '17 9 * * 1'

permissions:
contents: read

concurrency:
group: rsbuild-mf-live-fixture
cancel-in-progress: false

jobs:
publish:
if: github.repository == 'ZephyrCloudIO/zephyr-examples'
runs-on: depot-ubuntu-latest
timeout-minutes: 30
environment: rsbuild-mf-live-fixture
env:
ZE_SECRET_TOKEN: ${{ secrets.ZEPHYR_AUTH_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24

- uses: pnpm/action-setup@v4
with:
version: 10.33.0
run_install: false

- name: Require the protected Zephyr credential
run: test -n "$ZE_SECRET_TOKEN"

- name: Install pinned example dependencies
working-directory: module-federation/react-rsbuild-monorepo
run: pnpm install --frozen-lockfile

- name: Publish remotes before host
working-directory: module-federation/react-rsbuild-monorepo
run: pnpm build
58 changes: 58 additions & 0 deletions .github/workflows/verify-rsbuild-mf-monorepo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Verify Rsbuild Module Federation monorepo

on:
workflow_dispatch:
pull_request:
paths:
- "module-federation/react-rsbuild-monorepo/**"
- ".github/workflows/verify-rsbuild-mf-monorepo.yml"
push:
branches:
- main
paths:
- "module-federation/react-rsbuild-monorepo/**"
- ".github/workflows/verify-rsbuild-mf-monorepo.yml"

permissions:
contents: read

concurrency:
group: verify-rsbuild-mf-monorepo-${{ github.ref }}
cancel-in-progress: true

jobs:
verify:
runs-on: depot-ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: module-federation/react-rsbuild-monorepo

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24

- uses: pnpm/action-setup@v4
with:
version: 10.33.0
run_install: false

- name: Install pinned dependencies
run: pnpm install --frozen-lockfile

- name: Verify official scaffold and integration commands
run: pnpm verify:scaffold

- name: Build and diagnose the example
run: pnpm verify

- name: Install Chromium
run: pnpm exec playwright install --with-deps chromium

- name: Verify remotes in a browser
run: pnpm verify:browser
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Micro-frontend architecture with Module Federation, Zephyr's core value proposit
| [Angular + Rsbuild Module Federation](module-federation/angular-rsbuild) | angular | rsbuild | intermediate |
| [Angular + Vite Module Federation](module-federation/angular-vite) | angular | vite | intermediate |
| [React + Rsbuild Module Federation](module-federation/react-rsbuild) | react | rsbuild | intermediate |
| [React + Rsbuild Module Federation Monorepo](module-federation/react-rsbuild-monorepo) | react | rsbuild | advanced |
| [React Multi-Bundler Module Federation](module-federation/react-vite-rspack-webpack) | react | webpack | advanced |
| [React + Webpack Module Federation](module-federation/react-webpack) | react | webpack | intermediate |
| [Tractor Store (Module Federation)](module-federation/tractor-sample) | react | rspack | advanced |
Expand Down
6 changes: 6 additions & 0 deletions module-federation/react-rsbuild-monorepo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.mf/
apps/*/@mf-types/
diagnostics/type-001/node_modules/
diagnostics/type-001/outside.d.ts
playwright-report/
test-results/
78 changes: 78 additions & 0 deletions module-federation/react-rsbuild-monorepo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
name: React + Rsbuild Module Federation Monorepo
slug: module-federation/react-rsbuild-monorepo
description: Verified React monorepo with an Rsbuild host, two federated remotes, Zephyr dependencies, DTS diagnostics, and browser tests
framework: react
bundler: rsbuild
features: [module-federation, monorepo, typescript]
complexity: advanced
---

# React + Rsbuild Module Federation Monorepo

> A verified React monorepo with an Rsbuild host, two federated remotes,
> Zephyr dependencies, DTS diagnostics, watch-mode checks, and browser tests.

## Tech Stack

- React 19
- Rsbuild
- Module Federation
- pnpm workspaces
- Zephyr Cloud
- Playwright

## Architecture

The example contains three independently buildable applications:

- `apps/header` exposes `header/Header`;
- `apps/hero` exposes `hero/Hero`;
- `apps/host` consumes both remotes and declares the matching
`zephyr:dependencies`.

The build runs the remotes before the host. The committed verification scripts
check declared, locked, installed, generated, and browser-observed state. The
`diagnostics/type-001` project preserves a reproducible DTS `TS6059` failure and
its expected diagnostic path.

## Quick Start

```bash
npx degit ZephyrCloudIO/zephyr-examples/module-federation/react-rsbuild-monorepo my-app
cd my-app
pnpm install --frozen-lockfile
pnpm dev
```

The local development and verification commands set
`ZEPHYR_EXAMPLE_OFFLINE=1`, which disables publishing while preserving the
Rsbuild and Module Federation configuration.

## Verify

```bash
pnpm verify:scaffold
pnpm verify
pnpm verify:browser
```

These checks verify the official scaffold and integration commands, package
pins, remote-first build order, federation manifests, exposed modules, web
watch behavior, DTS diagnostics, browser rendering, and a remote-only update.

## Deploy

Provide an authorized Zephyr credential, then build:

```bash
pnpm build
```

The build publishes `header`, then `hero`, then `host`.

## Learn More

- [Rsbuild + React Module Federation monorepo guide](https://docs.zephyr-cloud.io/tutorials/rsbuild-react-mf-monorepo)
- [Zephyr Cloud documentation](https://docs.zephyr-cloud.io)
- [Module Federation documentation](https://module-federation.io)
26 changes: 26 additions & 0 deletions module-federation/react-rsbuild-monorepo/apps/header/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "rsbuild-mf-monorepo-header",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "rsbuild build",
"dev": "rsbuild dev",
"inspect": "rsbuild inspect",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.2.7",
"react-dom": "19.2.7"
},
"devDependencies": {
"@module-federation/rsbuild-plugin": "2.8.0",
"@rsbuild/core": "2.1.8",
"@rsbuild/plugin-react": "2.1.0",
"@types/node": "24.5.2",
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3",
"typescript": "6.0.3",
"zephyr-rsbuild-plugin": "1.2.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { withZephyr } from 'zephyr-rsbuild-plugin';

const exampleOffline = process.env['ZEPHYR_EXAMPLE_OFFLINE'] === '1';

export default defineConfig({
source: {
entry: {
index: './src/index.ts',
},
},
server: {
port: 3001,
},
output: {
assetPrefix: 'auto',
},
plugins: [
pluginReact(),
pluginModuleFederation({
name: 'header',
filename: 'remoteEntry.js',
manifest: true,
exposes: {
'./Header': './src/Header.tsx',
},
shared: {
react: {
singleton: true,
requiredVersion: '19.2.7',
},
'react-dom': {
singleton: true,
requiredVersion: '19.2.7',
},
},
dts: {
generateTypes: {
tsConfigPath: './tsconfig.json',
},
},
}),
...(!exampleOffline ? [withZephyr()] : []),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Header() {
return (
<header data-testid="header">
<strong>Header fixture v1</strong>
</header>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Header } from './Header';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src"
},
"include": ["src"]
}
25 changes: 25 additions & 0 deletions module-federation/react-rsbuild-monorepo/apps/hero/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "rsbuild-mf-monorepo-hero",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "rsbuild build",
"dev": "rsbuild dev",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.2.7",
"react-dom": "19.2.7"
},
"devDependencies": {
"@module-federation/rsbuild-plugin": "2.8.0",
"@rsbuild/core": "2.1.8",
"@rsbuild/plugin-react": "2.1.0",
"@types/node": "24.5.2",
"@types/react": "19.2.14",
"@types/react-dom": "19.2.3",
"typescript": "6.0.3",
"zephyr-rsbuild-plugin": "1.2.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { withZephyr } from 'zephyr-rsbuild-plugin';

const exampleOffline = process.env['ZEPHYR_EXAMPLE_OFFLINE'] === '1';

export default defineConfig({
source: {
entry: {
index: './src/index.ts',
},
},
server: {
port: 3002,
},
output: {
assetPrefix: 'auto',
},
plugins: [
pluginReact(),
pluginModuleFederation({
name: 'hero',
filename: 'remoteEntry.js',
manifest: true,
exposes: {
'./Hero': './src/Hero.tsx',
},
shared: {
react: {
singleton: true,
requiredVersion: '19.2.7',
},
'react-dom': {
singleton: true,
requiredVersion: '19.2.7',
},
},
dts: {
generateTypes: {
tsConfigPath: './tsconfig.json',
},
},
}),
...(!exampleOffline ? [withZephyr()] : []),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Hero() {
return (
<main data-testid="hero">
<h1>Hero fixture</h1>
<p>Rsbuild, Module Federation, and Zephyr Cloud are connected.</p>
</main>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Hero } from './Hero';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src"
},
"include": ["src"]
}
Loading
Loading