@fulgurjs/federation 5.1.3 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.en.md +7 -5
  3. package/README.md +14 -12
  4. package/dist/context.cjs +2 -2
  5. package/dist/context.js +2 -2
  6. package/dist/index.cjs +141 -48
  7. package/dist/index.js +141 -48
  8. package/dist/react-adapter.cjs +32 -1
  9. package/dist/react-adapter.d.cts +1 -1
  10. package/dist/react-adapter.d.ts +1 -1
  11. package/dist/react-adapter.js +32 -1
  12. package/dist/react.d.ts +2 -2
  13. package/dist/runtime-entry.d.ts +2 -2
  14. package/dist/runtime.js +7 -7
  15. package/dist/vue-adapter.cjs +99 -15
  16. package/dist/vue-adapter.d.cts +1 -1
  17. package/dist/vue-adapter.d.ts +1 -1
  18. package/dist/vue-adapter.js +100 -16
  19. package/examples/README.en.md +47 -0
  20. package/examples/README.md +40 -18
  21. package/examples/react/README.md +83 -0
  22. package/examples/react/host/README.md +49 -0
  23. package/examples/react/host/fulgurjs.config.ts +31 -0
  24. package/examples/{react-remote → react/host}/index.html +2 -1
  25. package/examples/react/host/package-lock.json +2381 -0
  26. package/examples/react/host/package.json +24 -0
  27. package/examples/react/host/src/App.tsx +19 -0
  28. package/examples/react/host/src/main.tsx +33 -0
  29. package/examples/react/host/src/pages/UtilsDemo.tsx +32 -0
  30. package/examples/react/host/src/remotePages.tsx +16 -0
  31. package/examples/{react-remote → react/host}/tsconfig.json +2 -3
  32. package/examples/{react-remote → react/host}/vite.config.ts +2 -2
  33. package/examples/react/remote/README.md +47 -0
  34. package/examples/react/remote/fulgurjs.config.ts +20 -0
  35. package/examples/{react-host → react/remote}/index.html +2 -1
  36. package/examples/react/remote/package-lock.json +2323 -0
  37. package/examples/react/remote/package.json +23 -0
  38. package/examples/react/remote/src/App.tsx +16 -0
  39. package/examples/react/remote/src/exposes/ClickButton.tsx +15 -0
  40. package/examples/react/remote/src/exposes/pages/DetailPage.tsx +10 -0
  41. package/examples/react/remote/src/exposes/pages/HomePage.tsx +12 -0
  42. package/examples/react/remote/src/exposes/utils.ts +10 -0
  43. package/examples/react/remote/src/main.tsx +11 -0
  44. package/examples/{react-host → react/remote}/tsconfig.json +3 -4
  45. package/examples/{react-host → react/remote}/vite.config.ts +2 -2
  46. package/examples/vue/README.md +85 -0
  47. package/examples/vue/host/README.md +50 -0
  48. package/examples/vue/host/fulgurjs.config.ts +30 -0
  49. package/examples/vue/host/index.html +12 -0
  50. package/examples/vue/host/package-lock.json +1855 -0
  51. package/examples/vue/host/package.json +21 -0
  52. package/examples/vue/host/src/App.vue +12 -0
  53. package/examples/vue/host/src/main.ts +44 -0
  54. package/examples/vue/host/src/pages/HomePage.vue +16 -0
  55. package/examples/vue/host/src/pages/UtilsDemo.vue +45 -0
  56. package/examples/vue/host/tsconfig.json +13 -0
  57. package/examples/vue/host/vite.config.ts +8 -0
  58. package/examples/vue/remote/README.md +47 -0
  59. package/examples/vue/remote/fulgurjs.config.ts +20 -0
  60. package/examples/vue/remote/index.html +12 -0
  61. package/examples/vue/remote/package-lock.json +1833 -0
  62. package/examples/vue/remote/package.json +20 -0
  63. package/examples/vue/remote/src/App.vue +16 -0
  64. package/examples/vue/remote/src/exposes/ClickButton.vue +16 -0
  65. package/examples/vue/remote/src/exposes/pages/DetailPage.vue +14 -0
  66. package/examples/vue/remote/src/exposes/pages/HomePage.vue +11 -0
  67. package/examples/vue/remote/src/exposes/utils.ts +10 -0
  68. package/examples/vue/remote/src/main.ts +6 -0
  69. package/examples/vue/remote/tsconfig.json +13 -0
  70. package/examples/vue/remote/vite.config.ts +8 -0
  71. package/package.json +2 -2
  72. package/examples/host/fulgurjs.config.ts +0 -26
  73. package/examples/react-host/README.md +0 -28
  74. package/examples/react-host/fulgurjs.config.ts +0 -19
  75. package/examples/react-host/package.json +0 -23
  76. package/examples/react-host/src/App.tsx +0 -66
  77. package/examples/react-host/src/federation/pages.data.ts +0 -21
  78. package/examples/react-host/src/main.tsx +0 -8
  79. package/examples/react-remote/fulgurjs.config.ts +0 -17
  80. package/examples/react-remote/package.json +0 -22
  81. package/examples/react-remote/src/Button.tsx +0 -15
  82. package/examples/react-remote/src/main.tsx +0 -6
  83. package/examples/react-remote/src/pages/Detail.tsx +0 -10
  84. package/examples/react-remote/src/pages/Home.tsx +0 -14
  85. package/examples/react-remote/src/utils.ts +0 -3
  86. package/examples/remote-a/fulgurjs.config.ts +0 -24
  87. package/examples/remote-a/src/views/Detail.vue +0 -3
  88. package/examples/remote-a/src/views/Home.vue +0 -3
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "fulgurjs-demo-react-host",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite --port 5204 --strictPort",
8
+ "build": "vite build",
9
+ "preview": "vite preview --port 5204 --strictPort"
10
+ },
11
+ "dependencies": {
12
+ "@fulgurjs/federation": "file:../../../../work/fulgurjs-federation-5.2.0.tgz",
13
+ "react": "^19.1.0",
14
+ "react-dom": "^19.1.0",
15
+ "react-router-dom": "^7.1.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/react": "^19.1.0",
19
+ "@types/react-dom": "^19.1.0",
20
+ "@vitejs/plugin-react": "^5.0.0",
21
+ "typescript": "^5.8.0",
22
+ "vite": "^6.3.5"
23
+ }
24
+ }
@@ -0,0 +1,19 @@
1
+ import { remoteComponent } from '@fulgurjs/federation/react'
2
+
3
+ // remoteComponent:首次渲染才真正加载远程模块;失败时插件呈现默认错误占位
4
+ // (含「重试加载 / 刷新页面重试」),无需自己实现错误组件。
5
+ const RemoteButton = remoteComponent('react-remote/ClickButton')
6
+
7
+ /** 宿主首页:演示单个远程组件消费(按需懒加载) */
8
+ export default function App() {
9
+ return (
10
+ <div style={{ fontFamily: 'sans-serif', padding: 16 }}>
11
+ <h2>宿主首页</h2>
12
+ <p>
13
+ 下面的按钮来自 react-remote(<code>./ClickButton</code> expose)。
14
+ 仅在进入本页时按需加载——首页不会批量预取未访问的远程页面。
15
+ </p>
16
+ <RemoteButton />
17
+ </div>
18
+ )
19
+ }
@@ -0,0 +1,33 @@
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import { BrowserRouter, Link, Route, Routes, useParams, useSearchParams } from 'react-router-dom'
4
+ import App from './App'
5
+ import UtilsDemo from './pages/UtilsDemo'
6
+ import { RemoteHomePage, RemoteDetailPage } from './remotePages'
7
+
8
+ createRoot(document.getElementById('root')!).render(
9
+ <StrictMode>
10
+ <BrowserRouter>
11
+ <nav style={{ display: 'flex', gap: 16, padding: 16, fontFamily: 'sans-serif' }}>
12
+ <Link to="/">首页</Link>
13
+ <Link to="/remote/home">远程首页</Link>
14
+ <Link to="/remote/detail/7?tab=basic">远程详情(id=7)</Link>
15
+ <Link to="/utils-demo">TS 模块调用</Link>
16
+ </nav>
17
+ <Routes>
18
+ <Route path="/" element={<App />} />
19
+ <Route path="/utils-demo" element={<UtilsDemo />} />
20
+ <Route path="/remote/home" element={<RemoteHomePage />} />
21
+ {/* 远程参数页:params + query 全量透传给远程页面组件 */}
22
+ <Route path="/remote/detail/:id" element={<RemoteDetailRoute />} />
23
+ </Routes>
24
+ </BrowserRouter>
25
+ </StrictMode>,
26
+ )
27
+
28
+ /** 从 react-router 取 params/query 再交给页面适配器组件(适配器与路由库解耦) */
29
+ function RemoteDetailRoute() {
30
+ const { id } = useParams()
31
+ const [search] = useSearchParams()
32
+ return <RemoteDetailPage id={id} tab={search.get('tab') ?? undefined} />
33
+ }
@@ -0,0 +1,32 @@
1
+ import type { ReactNode } from 'react'
2
+ import { useLoadRemote } from '@fulgurjs/federation/react'
3
+
4
+ interface RemoteUtils {
5
+ DEMO_ANSWER: number
6
+ sumNumbers: (...numbers: number[]) => number
7
+ formatPrice: (yuan: number) => string
8
+ }
9
+
10
+ /** 普通 TS 模块调用演示:useLoadRemote 返回模块命名空间(loading/error/reload 内置) */
11
+ export default function UtilsDemo(): ReactNode {
12
+ const { data, error, loading, reload } = useLoadRemote<RemoteUtils>('react-remote/utils')
13
+ return (
14
+ <div style={{ fontFamily: 'sans-serif', padding: 16 }}>
15
+ <h2>普通 TS 模块调用</h2>
16
+ {error ? (
17
+ <p data-testid="demo-utils-error" style={{ color: '#c45656' }}>
18
+ 调用失败:{String((error as Error)?.message ?? error)}
19
+ </p>
20
+ ) : loading || !data ? (
21
+ <p>加载中…</p>
22
+ ) : (
23
+ <ul data-testid="demo-utils-result">
24
+ <li>sumNumbers(2, 3, 7) = {data.sumNumbers(2, 3, 7)}</li>
25
+ <li>DEMO_ANSWER = {data.DEMO_ANSWER}</li>
26
+ <li>formatPrice(12.5) = {data.formatPrice(12.5)}</li>
27
+ </ul>
28
+ )}
29
+ <button data-testid="demo-utils-reload" onClick={() => void reload()}>重新调用</button>
30
+ </div>
31
+ )
32
+ }
@@ -0,0 +1,16 @@
1
+ import { createReactHostPages } from '@fulgurjs/federation/react'
2
+ import { pages, remotePrefixes } from '../fulgurjs.config.ts'
3
+
4
+ // 页面适配器:URL 解析、最长前缀远程归属、异步组件缓存、
5
+ // 加载/错误占位(含「重试加载 / 刷新页面重试」)全部由插件完成。
6
+ // 模块顶层创建一次(不能在组件 render 内调用工厂)。
7
+ const hostPages = createReactHostPages({
8
+ pages,
9
+ remotePrefixes,
10
+ })
11
+
12
+ /** 远程首页组件(spec = 远程名 + exposes 键) */
13
+ export const RemoteHomePage = hostPages.component('react-remote/pages/HomePage')
14
+
15
+ /** 远程详情组件:宿主路由层把 params/query 作为 props 传入 */
16
+ export const RemoteDetailPage = hostPages.component<{ id?: string; tab?: string }>('react-remote/pages/DetailPage')
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
4
  "module": "ESNext",
6
5
  "moduleResolution": "bundler",
7
- "jsx": "react-jsx",
8
6
  "strict": true,
7
+ "jsx": "react-jsx",
9
8
  "skipLibCheck": true,
10
9
  "noEmit": true,
11
- "isolatedModules": true
10
+ "types": ["vite/client"]
12
11
  },
13
12
  "include": ["src", "fulgurjs.config.ts", "vite.config.ts"]
14
13
  }
@@ -1,7 +1,7 @@
1
1
  import { defineConfig } from 'vite'
2
2
  import react from '@vitejs/plugin-react'
3
- import federation from '@fulgurjs/federation'
4
- import fulgurjsConfig from './fulgurjs.config'
3
+ import { federation } from '@fulgurjs/federation'
4
+ import fulgurjsConfig from './fulgurjs.config.ts'
5
5
 
6
6
  export default defineConfig({
7
7
  plugins: [react(), federation(fulgurjsConfig)],
@@ -0,0 +1,47 @@
1
+ # react-remote —— React 远程(fulgurjs 联邦演示)
2
+
3
+ > **角色:React 远程(被消费方)。** 向 [`../host/`](../host/)(react-host,端口 5204)暴露可点击按钮组件、普通 TS 工具模块、联邦首页与参数详情页;也可独立运行调试。
4
+
5
+ ## 从干净拷贝运行
6
+
7
+ ```bash
8
+ cd react-remote # 把本目录复制到任意位置后进入
9
+ npm install
10
+ npm run dev # http://localhost:5203
11
+ ```
12
+
13
+ 独立运行画面:`react-remote 独立运行` 页面 + 一枚可点击计数按钮(远程自己的壳;联邦消费走 `fulgurjs-remoteEntry.js` 容器入口,与壳无关)。
14
+
15
+ ## 暴露的模块(exposes)
16
+
17
+ | expose 键 | 源文件 | 说明 |
18
+ | --- | --- | --- |
19
+ | `./ClickButton` | `src/exposes/ClickButton.tsx` | 可点击计数按钮(useState 本地状态) |
20
+ | `./utils` | `src/exposes/utils.ts` | 普通 TS 模块:`sumNumbers` / `DEMO_ANSWER` / `formatPrice` |
21
+ | `./pages/HomePage` | `src/exposes/pages/HomePage.tsx` | 联邦页面:远程首页 |
22
+ | `./pages/DetailPage` | `src/exposes/pages/DetailPage.tsx` | 联邦页面:详情页(接收宿主路由的 `id` / `tab` props) |
23
+
24
+ 宿主如何调用 `./utils`(宿主侧代码):
25
+
26
+ ```tsx
27
+ import { useLoadRemote } from '@fulgurjs/federation/react'
28
+ const { data } = useLoadRemote<{ sumNumbers: (...n: number[]) => number }>('react-remote/utils')
29
+ data?.sumNumbers(2, 3, 7) // 12
30
+ ```
31
+
32
+ ## 关键配置
33
+
34
+ - `fulgurjs.config.ts`:**联邦唯一声明**(name = `react-remote`、exposes、shared)。
35
+ - `vite.config.ts`:`federation(fulgurjsConfig)` 挂载插件;端口在 `package.json` 的 `dev` 脚本(5203)。
36
+
37
+ ## 生产构建与部署
38
+
39
+ ```bash
40
+ npm run build # dist/(含 fulgurjs-remoteEntry.js 与 fulgurjs-manifest.json)
41
+ ```
42
+
43
+ 部署到 Nginx 子路径 `/react-remote/`(与宿主 `prod: '/react-remote'` 对应)。完整 Nginx 示例见[组合说明](../README.md#生产构建与最小-nginx-部署)。
44
+
45
+ ## 故障演练(配合宿主)
46
+
47
+ 停掉本 dev server → 宿主远程页面出现插件默认错误占位 → 重启本服务 → 宿主占位上「重试加载」同页恢复,或「刷新页面重试」整页恢复。
@@ -0,0 +1,20 @@
1
+ import type { FederationOptions } from '@fulgurjs/federation'
2
+
3
+ /**
4
+ * 远程端联邦配置(唯一需要维护的联邦声明文件)。
5
+ * exposes:宿主将按这里的键加载模块;改键名时宿主页面表/引用需同步。
6
+ */
7
+ export default {
8
+ name: 'react-remote',
9
+ filename: 'fulgurjs-remoteEntry.js',
10
+ exposes: {
11
+ './ClickButton': './src/exposes/ClickButton.tsx',
12
+ './utils': './src/exposes/utils.ts',
13
+ './pages/HomePage': './src/exposes/pages/HomePage.tsx',
14
+ './pages/DetailPage': './src/exposes/pages/DetailPage.tsx',
15
+ },
16
+ shared: {
17
+ react: { singleton: true },
18
+ 'react-dom': { singleton: true },
19
+ },
20
+ } satisfies FederationOptions
@@ -2,7 +2,8 @@
2
2
  <html lang="zh-CN">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <title>react-host(fulgurjs example)</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>react-remote(fulgurjs 演示远程)</title>
6
7
  </head>
7
8
  <body>
8
9
  <div id="root"></div>