@fulgurjs/federation 5.8.0 → 5.9.1
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.
- package/CHANGELOG.md +19 -4
- package/README.en.md +60 -24
- package/README.md +60 -24
- package/dist/cli.js +327 -29
- package/dist/index.cjs +2 -2
- package/dist/index.js +2 -2
- package/dist/runtime.js +1 -1
- package/docs/API.en.md +14 -3
- package/docs/API.md +7 -6
- package/docs/webpack-mf-/345/257/271/347/205/247/344/270/216/347/274/272/345/217/243.md +2 -2
- package/examples/README.md +3 -67
- package/examples/templates/README.md +88 -0
- package/examples/templates/react-host-vue-remote/README.md +18 -0
- package/examples/templates/react-host-vue-remote/package.json +11 -0
- package/examples/templates/react-host-vue-remote/pnpm-lock.yaml +1627 -0
- package/examples/templates/react-host-vue-remote/pnpm-workspace.yaml +10 -0
- package/examples/{bridge → templates/react-host-vue-remote}/react-host/README.md +8 -7
- package/examples/{bridge → templates/react-host-vue-remote}/react-host/package.json +1 -1
- package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d/_paths.d.ts +4 -0
- package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d/bridge.ts +3 -0
- package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d.ts +9 -0
- package/examples/templates/react-host-vue-remote/scripts/dev.config.json +6 -0
- package/examples/templates/react-host-vue-remote/scripts/dev.mjs +173 -0
- package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/README.md +10 -5
- package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/package.json +1 -1
- package/examples/{react → templates/react-react}/README.md +9 -13
- package/examples/{react → templates/react-react}/host/README.md +6 -8
- package/examples/{react → templates/react-react}/host/package.json +1 -1
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/ClickButton.ts +3 -0
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/_paths.d.ts +4 -0
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/pages/DetailPage.ts +3 -0
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/pages/HomePage.ts +3 -0
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/utils.ts +2 -0
- package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d.ts +26 -0
- package/examples/templates/react-react/package.json +11 -0
- package/examples/templates/react-react/pnpm-lock.yaml +1537 -0
- package/examples/templates/react-react/pnpm-workspace.yaml +10 -0
- package/examples/{react → templates/react-react}/remote/README.md +7 -6
- package/examples/{react → templates/react-react}/remote/package.json +1 -1
- package/examples/templates/react-react/scripts/dev.config.json +6 -0
- package/examples/templates/react-react/scripts/dev.mjs +173 -0
- package/examples/templates/showcase/README.md +109 -0
- package/examples/templates/showcase/package.json +13 -0
- package/examples/templates/showcase/pnpm-lock.yaml +1858 -0
- package/examples/templates/showcase/pnpm-workspace.yaml +12 -0
- package/examples/templates/showcase/react-host/fulgurjs.config.ts +21 -0
- package/examples/templates/showcase/react-host/index.html +13 -0
- package/examples/templates/showcase/react-host/package.json +26 -0
- package/examples/templates/showcase/react-host/src/GuardBanner.tsx +33 -0
- package/examples/templates/showcase/react-host/src/Layout.tsx +42 -0
- package/examples/templates/showcase/react-host/src/ObsPanel.tsx +44 -0
- package/examples/templates/showcase/react-host/src/demo-log.ts +74 -0
- package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d/_paths.d.ts +4 -0
- package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d/bridge.ts +3 -0
- package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d.ts +7 -0
- package/examples/templates/showcase/react-host/src/main.tsx +33 -0
- package/examples/templates/showcase/react-host/src/pages/AboutPage.tsx +18 -0
- package/examples/templates/showcase/react-host/src/pages/BridgeVuePage.tsx +77 -0
- package/examples/templates/showcase/react-host/src/pages/HomePage.tsx +14 -0
- package/examples/templates/showcase/react-host/src/routing.ts +30 -0
- package/examples/templates/showcase/react-host/tsconfig.json +15 -0
- package/examples/templates/showcase/react-host/vite.config.ts +8 -0
- package/examples/templates/showcase/react-remote/fulgurjs.config.ts +18 -0
- package/examples/templates/showcase/react-remote/index.html +13 -0
- package/examples/templates/showcase/react-remote/package.json +25 -0
- package/examples/templates/showcase/react-remote/src/ChildLayout.tsx +48 -0
- package/examples/templates/showcase/react-remote/src/bridge.tsx +62 -0
- package/examples/templates/showcase/react-remote/src/child-bus.ts +32 -0
- package/examples/templates/showcase/react-remote/src/main.tsx +18 -0
- package/examples/templates/showcase/react-remote/src/pages/Locked.tsx +23 -0
- package/examples/templates/showcase/react-remote/src/pages/OrderDetail.tsx +36 -0
- package/examples/templates/showcase/react-remote/src/pages/OrderList.tsx +110 -0
- package/examples/templates/showcase/react-remote/src/pages/Settings.tsx +50 -0
- package/examples/templates/showcase/react-remote/src/settings-store.ts +11 -0
- package/examples/templates/showcase/react-remote/tsconfig.json +14 -0
- package/examples/templates/showcase/react-remote/vite.config.ts +14 -0
- package/examples/templates/showcase/scripts/dev.config.json +8 -0
- package/examples/templates/showcase/scripts/dev.mjs +173 -0
- package/examples/templates/showcase/vue-host/fulgurjs.config.ts +21 -0
- package/examples/templates/showcase/vue-host/index.html +13 -0
- package/examples/templates/showcase/vue-host/package.json +25 -0
- package/examples/templates/showcase/vue-host/src/App.vue +50 -0
- package/examples/templates/showcase/vue-host/src/GuardBanner.vue +24 -0
- package/examples/templates/showcase/vue-host/src/ObsPanel.vue +60 -0
- package/examples/templates/showcase/vue-host/src/demo-log.ts +49 -0
- package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d/_paths.d.ts +4 -0
- package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d/bridge.ts +3 -0
- package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d.ts +7 -0
- package/examples/templates/showcase/vue-host/src/guard.ts +47 -0
- package/examples/templates/showcase/vue-host/src/main.ts +30 -0
- package/examples/templates/showcase/vue-host/src/pages/AboutPage.vue +17 -0
- package/examples/templates/showcase/vue-host/src/pages/BridgeReactPage.vue +74 -0
- package/examples/templates/showcase/vue-host/src/pages/HomePage.vue +13 -0
- package/examples/templates/showcase/vue-host/src/routing.ts +31 -0
- package/examples/templates/showcase/vue-host/tsconfig.json +14 -0
- package/examples/templates/showcase/vue-remote/fulgurjs.config.ts +17 -0
- package/examples/templates/showcase/vue-remote/index.html +13 -0
- package/examples/templates/showcase/vue-remote/package.json +23 -0
- package/examples/templates/showcase/vue-remote/src/ChildLayout.vue +54 -0
- package/examples/templates/showcase/vue-remote/src/bridge.ts +48 -0
- package/examples/templates/showcase/vue-remote/src/child-bus.ts +32 -0
- package/examples/templates/showcase/vue-remote/src/main.ts +16 -0
- package/examples/templates/showcase/vue-remote/src/pages/Locked.vue +28 -0
- package/examples/templates/showcase/vue-remote/src/pages/OrderDetail.vue +46 -0
- package/examples/templates/showcase/vue-remote/src/pages/OrderList.vue +116 -0
- package/examples/templates/showcase/vue-remote/src/pages/Settings.vue +34 -0
- package/examples/templates/showcase/vue-remote/src/settings-store.ts +13 -0
- package/examples/templates/showcase/vue-remote/tsconfig.json +14 -0
- package/examples/templates/showcase/vue-remote/vite.config.ts +14 -0
- package/examples/templates/vue-host-react-remote/README.md +18 -0
- package/examples/templates/vue-host-react-remote/package.json +11 -0
- package/examples/templates/vue-host-react-remote/pnpm-lock.yaml +1663 -0
- package/examples/templates/vue-host-react-remote/pnpm-workspace.yaml +10 -0
- package/examples/{bridge → templates/vue-host-react-remote}/react-remote/README.md +9 -4
- package/examples/{bridge → templates/vue-host-react-remote}/react-remote/package.json +1 -1
- package/examples/templates/vue-host-react-remote/scripts/dev.config.json +6 -0
- package/examples/templates/vue-host-react-remote/scripts/dev.mjs +173 -0
- package/examples/{bridge → templates/vue-host-react-remote}/vue-host/README.md +8 -7
- package/examples/{bridge → templates/vue-host-react-remote}/vue-host/package.json +1 -1
- package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/App.vue +1 -1
- package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d/_paths.d.ts +4 -0
- package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d/bridge.ts +3 -0
- package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d.ts +9 -0
- package/examples/{vue → templates/vue-vue}/README.md +9 -13
- package/examples/{vue → templates/vue-vue}/host/README.md +6 -8
- package/examples/{vue → templates/vue-vue}/host/package.json +1 -1
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/ClickButton.ts +4 -0
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/_paths.d.ts +4 -0
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/pages/DetailPage.ts +4 -0
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/pages/HomePage.ts +4 -0
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/utils.ts +2 -0
- package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d.ts +29 -0
- package/examples/templates/vue-vue/host/vite.config.ts +8 -0
- package/examples/templates/vue-vue/package.json +11 -0
- package/examples/templates/vue-vue/pnpm-lock.yaml +1199 -0
- package/examples/templates/vue-vue/pnpm-workspace.yaml +10 -0
- package/examples/{vue → templates/vue-vue}/remote/README.md +7 -6
- package/examples/{vue → templates/vue-vue}/remote/package.json +1 -1
- package/examples/{vue → templates/vue-vue}/remote/src/App.vue +1 -1
- package/examples/templates/vue-vue/scripts/dev.config.json +6 -0
- package/examples/templates/vue-vue/scripts/dev.mjs +173 -0
- package/package.json +4 -4
- package/examples/README.en.md +0 -67
- package/examples/bridge/README.md +0 -36
- package/examples/bridge/react-host/package-lock.json +0 -2466
- package/examples/bridge/react-remote/package-lock.json +0 -2391
- package/examples/bridge/vue-host/package-lock.json +0 -1894
- package/examples/bridge/vue-remote/package-lock.json +0 -1865
- package/examples/react/host/package-lock.json +0 -2391
- package/examples/react/remote/package-lock.json +0 -2333
- package/examples/vue/host/package-lock.json +0 -1865
- package/examples/vue/remote/package-lock.json +0 -1843
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/fulgurjs.config.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/index.html +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/env.d.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/host-session.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/main.tsx +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/tsconfig.json +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/react-host/vite.config.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/fulgurjs.config.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/index.html +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/App.vue +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/bridge.ts +0 -0
- /package/examples/{bridge/react-remote → templates/react-host-vue-remote/vue-remote}/src/env.d.ts +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/main.ts +0 -0
- /package/examples/{bridge/vue-host → templates/react-host-vue-remote/vue-remote}/tsconfig.json +0 -0
- /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/vite.config.ts +0 -0
- /package/examples/{react → templates/react-react}/host/fulgurjs.config.ts +0 -0
- /package/examples/{react → templates/react-react}/host/index.html +0 -0
- /package/examples/{react → templates/react-react}/host/src/App.tsx +0 -0
- /package/examples/{react → templates/react-react}/host/src/main.tsx +0 -0
- /package/examples/{react → templates/react-react}/host/src/pages/UtilsDemo.tsx +0 -0
- /package/examples/{react → templates/react-react}/host/src/remotePages.tsx +0 -0
- /package/examples/{bridge/react-remote → templates/react-react/host}/tsconfig.json +0 -0
- /package/examples/{react → templates/react-react}/host/vite.config.ts +0 -0
- /package/examples/{react → templates/react-react}/remote/fulgurjs.config.ts +0 -0
- /package/examples/{react → templates/react-react}/remote/index.html +0 -0
- /package/examples/{react → templates/react-react}/remote/src/App.tsx +0 -0
- /package/examples/{react → templates/react-react}/remote/src/exposes/ClickButton.tsx +0 -0
- /package/examples/{react → templates/react-react}/remote/src/exposes/pages/DetailPage.tsx +0 -0
- /package/examples/{react → templates/react-react}/remote/src/exposes/pages/HomePage.tsx +0 -0
- /package/examples/{react → templates/react-react}/remote/src/exposes/utils.ts +0 -0
- /package/examples/{react → templates/react-react}/remote/src/main.tsx +0 -0
- /package/examples/{react/host → templates/react-react/remote}/tsconfig.json +0 -0
- /package/examples/{react → templates/react-react}/remote/vite.config.ts +0 -0
- /package/examples/{vue/host → templates/showcase/vue-host}/vite.config.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/fulgurjs.config.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/index.html +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/src/bridge.tsx +0 -0
- /package/examples/{bridge/vue-host → templates/vue-host-react-remote/react-remote}/src/env.d.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/src/main.tsx +0 -0
- /package/examples/{react/remote → templates/vue-host-react-remote/react-remote}/tsconfig.json +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/vite.config.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/fulgurjs.config.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/index.html +0 -0
- /package/examples/{bridge/vue-remote → templates/vue-host-react-remote/vue-host}/src/env.d.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/host-session.ts +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/main.ts +0 -0
- /package/examples/{bridge/vue-remote → templates/vue-host-react-remote/vue-host}/tsconfig.json +0 -0
- /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/vite.config.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/host/fulgurjs.config.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/host/index.html +0 -0
- /package/examples/{vue → templates/vue-vue}/host/src/App.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/host/src/main.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/host/src/pages/HomePage.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/host/src/pages/UtilsDemo.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/host/tsconfig.json +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/fulgurjs.config.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/index.html +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/src/exposes/ClickButton.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/src/exposes/pages/DetailPage.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/src/exposes/pages/HomePage.vue +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/src/exposes/utils.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/src/main.ts +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/tsconfig.json +0 -0
- /package/examples/{vue → templates/vue-vue}/remote/vite.config.ts +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
packages:
|
|
2
|
+
- host
|
|
3
|
+
- remote
|
|
4
|
+
minimumReleaseAgeExclude:
|
|
5
|
+
- '@fulgurjs/federation@5.7.1 || 5.8.0 || 5.9.0'
|
|
6
|
+
# pnpm >=12 构建脚本批准(12 起弃用 onlyBuiltDependencies;pnpm 9-11 忽略本键:
|
|
7
|
+
# esbuild >=0.16 二进制经 optionalDependencies 平台包分发,postinstall 仅校验,不阻塞安装)
|
|
8
|
+
allowBuilds:
|
|
9
|
+
esbuild: true
|
|
10
|
+
vue-demi: true
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# vue-remote —— Vue 远程(fulgurjs 联邦演示)
|
|
2
2
|
|
|
3
|
-
> **角色:Vue 远程(被消费方)。** 向 [`../host/`](../host
|
|
3
|
+
> **角色:Vue 远程(被消费方)。** 向 [`../host/`](../host)(vue-host,端口 5214)暴露可点击按钮组件、普通 TS 工具模块、联邦首页与参数详情页;也可独立运行调试。
|
|
4
4
|
|
|
5
5
|
## 从干净拷贝运行
|
|
6
6
|
|
|
7
|
+
复制整个 `vue-vue/` 模板,在模板根安装依赖后启动本应用:
|
|
8
|
+
|
|
7
9
|
```bash
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
npm run dev # http://localhost:5213
|
|
10
|
+
pnpm install --frozen-lockfile
|
|
11
|
+
pnpm --dir remote dev
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
宿主需要先启动对应远程;也可以在模板根执行 `pnpm dev` 启动完整组合。环境和完整运行步骤见[组合说明](../README.md)。
|
|
14
15
|
|
|
15
16
|
## 暴露的模块(exposes)
|
|
16
17
|
|
|
@@ -37,7 +38,7 @@ utils.sumNumbers(2, 3, 7) // 12
|
|
|
37
38
|
## 生产构建与部署
|
|
38
39
|
|
|
39
40
|
```bash
|
|
40
|
-
|
|
41
|
+
pnpm run build # dist/(含 fulgurjs-remoteEntry.js 与 fulgurjs-manifest.json)
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
部署到 Nginx 子路径 `/vue-remote/`(与宿主 `fulgurjs.config.ts` 的 `prod: '/vue-remote'` 对应;`vite.config.ts` 已配置 `base` 随 `build` 自动切换为 `/vue-remote/`(dev 不受影响);不要去掉它,否则 modulepreload 链接会指向站点根导致 404)。完整 Nginx 示例见[组合说明](../README.md#生产构建与最小-nginx-部署)。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div style="font-family: sans-serif; padding: 16px">
|
|
3
3
|
<h1>vue-remote 独立运行</h1>
|
|
4
|
-
<p>这是远程应用自己的壳,用于单独开发。联邦消费方(examples/vue/host)按 exposes 加载以下模块:</p>
|
|
4
|
+
<p>这是远程应用自己的壳,用于单独开发。联邦消费方(examples/templates/vue-vue/host)按 exposes 加载以下模块:</p>
|
|
5
5
|
<ul>
|
|
6
6
|
<li>./ClickButton —— 可点击计数按钮组件</li>
|
|
7
7
|
<li>./utils —— 普通 TS 工具模块</li>
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 模板统一 dev 启动器(规范源)。
|
|
4
|
+
*
|
|
5
|
+
* 本文件经 examples/scripts/sync-template-scripts.mjs 同步到五个模板的 scripts/dev.mjs;
|
|
6
|
+
* 模板内副本必须与规范源逐字节一致(check-catalog.mjs 校验哈希),模板复制出仓库后独立可用——
|
|
7
|
+
* 只依赖同目录 dev.config.json 与 Node 内置模块,不依赖仓库其他文件。
|
|
8
|
+
*
|
|
9
|
+
* 行为契约(与模板 README 一致):
|
|
10
|
+
* - 启动前预检全部端口:任何端口被占用则拒绝启动并指认处理方法(绝不按端口杀别人的进程);
|
|
11
|
+
* - 按 dev.config.json 顺序(远程在前宿主在后)启动各应用,逐个探活;
|
|
12
|
+
* - 任一应用启动失败/超时/中途退出:整组停止(只杀本次启动的子进程),非零退出并打印该应用日志尾部;
|
|
13
|
+
* - Ctrl+C / SIGTERM:清理本次启动的全部子进程后退出;不依赖 PID 文件;
|
|
14
|
+
* - 全部就绪后打印访问入口;探活 = 端口可连接(dev server 已监听),页面可用以浏览器验收为准。
|
|
15
|
+
*
|
|
16
|
+
* 平台:macOS/Linux 实测;Windows 走 taskkill 兜底路径,未经验证(见模板 README)。
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from 'node:child_process'
|
|
19
|
+
import fs from 'node:fs'
|
|
20
|
+
import net from 'node:net'
|
|
21
|
+
import path from 'node:path'
|
|
22
|
+
import { fileURLToPath } from 'node:url'
|
|
23
|
+
|
|
24
|
+
const templateRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
25
|
+
const { apps, readyTimeoutMs = 120000 } = JSON.parse(
|
|
26
|
+
fs.readFileSync(path.join(templateRoot, 'scripts', 'dev.config.json'), 'utf8'),
|
|
27
|
+
)
|
|
28
|
+
const isTTY = process.stdout.isTTY
|
|
29
|
+
const color = (code, text) => (isTTY ? `\x1b[${code}m${text}\x1b[0m` : text)
|
|
30
|
+
const EXIT = { ok: 0, startupFailed: 1, portConflict: 2, signal: 130 }
|
|
31
|
+
|
|
32
|
+
/** 双栈端口探测(vite 可能只绑 IPv4 或 IPv6 回环) */
|
|
33
|
+
function isPortUp(port) {
|
|
34
|
+
const probe = (host) =>
|
|
35
|
+
new Promise((resolve, reject) => {
|
|
36
|
+
const s = net.connect({ port, host, timeout: 800 })
|
|
37
|
+
s.on('connect', () => { s.destroy(); resolve(true) })
|
|
38
|
+
s.on('error', reject)
|
|
39
|
+
s.on('timeout', () => { s.destroy(); reject(new Error('timeout')) })
|
|
40
|
+
})
|
|
41
|
+
return Promise.any([probe('127.0.0.1'), probe('::1')]).catch(() => false)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const tailOf = new Map()
|
|
45
|
+
const children = new Map()
|
|
46
|
+
let shuttingDown = false
|
|
47
|
+
|
|
48
|
+
function recordOutput(name, chunk) {
|
|
49
|
+
const lines = (tailOf.get(name) ?? [])
|
|
50
|
+
for (const line of String(chunk).split('\n')) {
|
|
51
|
+
if (line === '') continue
|
|
52
|
+
lines.push(line)
|
|
53
|
+
}
|
|
54
|
+
while (lines.length > 60) lines.shift()
|
|
55
|
+
tailOf.set(name, lines)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function printAppLine(name, text) {
|
|
59
|
+
process.stdout.write(`${color('2', `[${name}]`)} ${text}\n`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function preflight() {
|
|
63
|
+
const conflicts = []
|
|
64
|
+
for (const app of apps) {
|
|
65
|
+
if (await isPortUp(app.port)) conflicts.push(app)
|
|
66
|
+
}
|
|
67
|
+
if (conflicts.length === 0) return
|
|
68
|
+
console.error(color('31', '[dev] 启动前检查失败:以下端口已被占用(不区分占用者,一律不启动):'))
|
|
69
|
+
for (const app of conflicts) {
|
|
70
|
+
const posix = `lsof -nP -iTCP:${app.port} -sTCP:LISTEN`
|
|
71
|
+
const win = `netstat -ano | findstr :${app.port}`
|
|
72
|
+
console.error(
|
|
73
|
+
` ${app.name} → 端口 ${app.port} 已监听。查看占用:${process.platform === 'win32' ? win : posix};` +
|
|
74
|
+
`结束占用进程,或同步修改 ${app.dir}/package.json 的 dev/preview 端口与宿主 fulgurjs.config.ts 的 remotes dev 地址后重试`,
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
console.error('[dev] 本启动器只清理自己启动的进程,不会替你结束端口上的既有服务。')
|
|
78
|
+
process.exit(EXIT.portConflict)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function spawnApp(app) {
|
|
82
|
+
const child = spawn('pnpm', ['--dir', app.dir, 'run', 'dev'], {
|
|
83
|
+
cwd: templateRoot,
|
|
84
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
85
|
+
// POSIX:独立进程组,便于整组终止;Windows:shell 解析 pnpm.cmd,树杀交给 taskkill
|
|
86
|
+
detached: true,
|
|
87
|
+
shell: process.platform === 'win32',
|
|
88
|
+
})
|
|
89
|
+
children.set(app.name, child)
|
|
90
|
+
child.stdout.on('data', (c) => { recordOutput(app.name, c); String(c).split('\n').filter(Boolean).forEach((l) => printAppLine(app.name, l)) })
|
|
91
|
+
child.stderr.on('data', (c) => { recordOutput(app.name, c); String(c).split('\n').filter(Boolean).forEach((l) => printAppLine(app.name, l)) })
|
|
92
|
+
return child
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const exitedOnce = (child) =>
|
|
96
|
+
new Promise((resolve) => {
|
|
97
|
+
child.once('exit', (code, signal) => resolve({ code, signal }))
|
|
98
|
+
child.once('error', (e) => resolve({ code: -1, signal: null, error: e }))
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
async function waitReady(app, child) {
|
|
102
|
+
const exited = exitedOnce(child)
|
|
103
|
+
const deadline = Date.now() + readyTimeoutMs
|
|
104
|
+
while (Date.now() < deadline) {
|
|
105
|
+
if (await isPortUp(app.port)) return { ok: true }
|
|
106
|
+
const done = await Promise.race([exited.then(() => 'exit'), new Promise((r) => setTimeout(() => r('tick'), 400))])
|
|
107
|
+
if (done === 'exit') return { ok: false, reason: `进程提前退出(启动命令失败——看下方日志尾部)` }
|
|
108
|
+
}
|
|
109
|
+
return { ok: false, reason: `${Math.round(readyTimeoutMs / 1000)}s 内端口 ${app.port} 未就绪(dev server 未监听)` }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function killTree(appName) {
|
|
113
|
+
const child = children.get(appName)
|
|
114
|
+
if (!child || child.exitCode !== null || child.signalCode !== null) return Promise.resolve()
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
const force = setTimeout(() => {
|
|
117
|
+
try { process.kill(process.platform === 'win32' ? child.pid : -child.pid, 'SIGKILL') } catch { /* 已退出 */ }
|
|
118
|
+
}, 3000).unref()
|
|
119
|
+
child.once('exit', () => { clearTimeout(force); resolve() })
|
|
120
|
+
try {
|
|
121
|
+
if (process.platform === 'win32') spawn('taskkill', ['/pid', String(child.pid), '/T', '/F'], { stdio: 'ignore' })
|
|
122
|
+
else process.kill(-child.pid, 'SIGTERM')
|
|
123
|
+
} catch { clearTimeout(force); resolve() }
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function shutdown(exitCode, reason) {
|
|
128
|
+
if (shuttingDown) return
|
|
129
|
+
shuttingDown = true
|
|
130
|
+
if (reason) console.log(`[dev] ${reason}`)
|
|
131
|
+
console.log(`[dev] 正在停止本次启动的 ${children.size} 个应用…`)
|
|
132
|
+
await Promise.all([...children.keys()].map(killTree))
|
|
133
|
+
console.log('[dev] 已全部停止。')
|
|
134
|
+
process.exit(exitCode)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
process.on('SIGINT', () => void shutdown(EXIT.signal, '[dev] 收到 Ctrl+C'))
|
|
138
|
+
process.on('SIGTERM', () => void shutdown(143, '[dev] 收到 SIGTERM'))
|
|
139
|
+
|
|
140
|
+
await preflight()
|
|
141
|
+
|
|
142
|
+
console.log(`[dev] 模板 ${path.basename(templateRoot)}:按顺序启动 ${apps.map((a) => a.name).join(' → ')}`)
|
|
143
|
+
for (const app of apps) {
|
|
144
|
+
printAppLine(app.name, `启动(pnpm --dir ${app.dir} run dev),等待端口 ${app.port} 就绪…`)
|
|
145
|
+
const child = spawnApp(app)
|
|
146
|
+
const ready = await waitReady(app, child)
|
|
147
|
+
if (!ready.ok) {
|
|
148
|
+
console.error(color('31', `\n[dev] 启动失败:${app.name} —— ${ready.reason}`))
|
|
149
|
+
const tail = tailOf.get(app.name) ?? []
|
|
150
|
+
if (tail.length) {
|
|
151
|
+
console.error(color('31', `[dev] ${app.name} 日志尾部(最后 ${tail.length} 行):`))
|
|
152
|
+
for (const line of tail) console.error(` [${app.name}] ${line}`)
|
|
153
|
+
}
|
|
154
|
+
await Promise.all([...children.keys()].map(killTree))
|
|
155
|
+
console.error(`[dev] 已停止本次启动的全部进程(${children.size} 个)。修复上面的问题后重新运行 pnpm dev。`)
|
|
156
|
+
process.exit(EXIT.startupFailed)
|
|
157
|
+
}
|
|
158
|
+
printAppLine(app.name, `就绪 → http://localhost:${app.port}/`)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log(color('32', '\n[dev] 全部应用已就绪:'))
|
|
162
|
+
for (const app of [...apps].reverse()) {
|
|
163
|
+
console.log(` http://localhost:${app.port}/ ${app.name}`)
|
|
164
|
+
}
|
|
165
|
+
console.log('[dev] Ctrl+C 停止全部应用(只清理本次启动的进程)。dev server 已监听 ≠ 页面必然可用,验收请以浏览器实际加载为准。\n')
|
|
166
|
+
|
|
167
|
+
// 运行期任何子应用退出(崩溃/被外部杀掉)→ 整组停止,不让半残组合冒充正常运行
|
|
168
|
+
for (const [name, child] of children) {
|
|
169
|
+
child.once('exit', (code) => {
|
|
170
|
+
if (!shuttingDown) void shutdown(EXIT.startupFailed, `[dev] ${name} 意外退出(退出码 ${code})——停止其余应用`)
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
await new Promise(() => {})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fulgurjs/federation",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.9.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite Module Federation for Vue and React: remote modules, shared dependencies and app bridges.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -124,9 +124,9 @@
|
|
|
124
124
|
"docs/API.en.md"
|
|
125
125
|
],
|
|
126
126
|
"scripts": {
|
|
127
|
-
"build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && cp ../../docs/API.md ../../docs/API.en.md ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md &&
|
|
127
|
+
"build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && cp ../../docs/API.md ../../docs/API.en.md ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md && node scripts/sync-package-examples.mjs && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/vue-adapter.ts src/react-adapter.ts src/context.ts src/bridge-core.ts src/bridge-errors.ts src/bridge-app-vue.ts src/bridge-app-react.ts src/bridge-host-vue.ts src/bridge-host-react.ts --format esm,cjs --dts --external vite --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite,vue --target node18 && tsup src/react.ts --format esm --dts --external vite,react --target node18 && tsup src/bridge.ts src/bridge-vue.ts src/bridge-react.ts --format esm --dts --external vite,vue,react,react-dom --target node18 && tsup src/bridge-router-vue.ts --format esm --dts --external vite,vue,vue-router --target node18 && tsup src/bridge-router-react.tsx --format esm --dts --external vite,react,react-dom,react-router-dom --target node18 && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime-entry.mjs && node scripts/check-gzip.mjs && node scripts/check-manual-codes.mjs",
|
|
128
128
|
"dev": "tsup --watch",
|
|
129
|
-
"test": "vitest run",
|
|
129
|
+
"test": "vitest run --dir tests",
|
|
130
130
|
"typecheck": "tsc --noEmit",
|
|
131
131
|
"typecheck:latest": "node scripts/typecheck-latest.mjs"
|
|
132
132
|
},
|
|
@@ -205,4 +205,4 @@
|
|
|
205
205
|
"optional": true
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
}
|
|
208
|
+
}
|
package/examples/README.en.md
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# fulgurjs-federation Examples
|
|
2
|
-
|
|
3
|
-
Pick your framework, copy the host and remote directories, run `npm install`, and you get a full module federation demo. All four projects are standalone: no dependency on this repo's source, the monorepo workspace, or any parent `node_modules` — the plugin dependency is an exact published version from the npm registry.
|
|
4
|
-
|
|
5
|
-
## Vue (host 5214 / remote 5213)
|
|
6
|
-
|
|
7
|
-
Full walkthrough: **[vue/README.md](./vue/README.md)** (Chinese).
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
cd examples/vue/remote && npm install && npm run dev # terminal 1: vue-remote, http://localhost:5213
|
|
11
|
-
cd examples/vue/host && npm install && npm run dev # terminal 2: vue-host, http://localhost:5214
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## React (host 5204 / remote 5203)
|
|
15
|
-
|
|
16
|
-
Full walkthrough: **[react/README.md](./react/README.md)** (Chinese).
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
cd examples/react/remote && npm install && npm run dev # terminal 1: react-remote, http://localhost:5203
|
|
20
|
-
cd examples/react/host && npm install && npm run dev # terminal 2: react-host, http://localhost:5204
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Cross-framework bridge (Vue host 5314 × React remote 5303; React host 5304 × Vue remote 5313)
|
|
24
|
-
|
|
25
|
-
Full walkthrough: **[bridge/README.md](./bridge/README.md)** (Chinese).
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
# Vue host × React sub-app
|
|
29
|
-
cd examples/bridge/react-remote && npm install && npm run dev # 5303
|
|
30
|
-
cd examples/bridge/vue-host && npm install && npm run dev # 5314
|
|
31
|
-
|
|
32
|
-
# React host × Vue sub-app
|
|
33
|
-
cd examples/bridge/vue-remote && npm install && npm run dev # 5313
|
|
34
|
-
cd examples/bridge/react-host && npm install && npm run dev # 5304
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## What each pair demonstrates
|
|
38
|
-
|
|
39
|
-
- A clickable remote counter component (local state lives inside the remote component; operated on the host page)
|
|
40
|
-
- Cross-application plain TS module calls (the host renders real return values)
|
|
41
|
-
- A remote home page plus a parameterized detail page (deep links survive refresh)
|
|
42
|
-
- Host navigation with route-level lazy loading (the home page never bulk-prefetches unvisited remote pages)
|
|
43
|
-
- The plugin's built-in loading/error placeholders and recovery actions (**Retry load** recovers in-page; **Refresh page to retry** recovers via a user-initiated full reload)
|
|
44
|
-
- Production build with a minimal Nginx deployment (including SPA fallback)
|
|
45
|
-
|
|
46
|
-
## Layout
|
|
47
|
-
|
|
48
|
-
```text
|
|
49
|
-
examples/
|
|
50
|
-
├── README.md / README.en.md # this entry (CN/EN)
|
|
51
|
-
├── bridge/ # Cross-framework bridge (sub-app-level mount/unmount, §8.2)
|
|
52
|
-
│ ├── README.md
|
|
53
|
-
│ ├── vue-host/ # Vue host × React sub-app (5314)
|
|
54
|
-
│ ├── react-remote/ # React sub-app (5303)
|
|
55
|
-
│ ├── react-host/ # React host × Vue sub-app (5304)
|
|
56
|
-
│ └── vue-remote/ # Vue sub-app (5313)
|
|
57
|
-
├── vue/
|
|
58
|
-
│ ├── README.md # guide for the Vue pair
|
|
59
|
-
│ ├── host/ # Vue host (vue-host, 5214)
|
|
60
|
-
│ └── remote/ # Vue remote (vue-remote, 5213)
|
|
61
|
-
└── react/
|
|
62
|
-
├── README.md # guide for the React pair
|
|
63
|
-
├── host/ # React host (react-host, 5204)
|
|
64
|
-
└── remote/ # React remote (react-remote, 5203)
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
> `examples/` is for users to copy and run. The repository-root `fixtures/` are internal regression harnesses (source-linked to the plugin workspace) — do not treat them as usage templates.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# 跨框架桥接示例(/bridge)
|
|
2
|
-
|
|
3
|
-
双向「子应用级跨框架嵌入」的最小可运行组合(README §8.2):
|
|
4
|
-
|
|
5
|
-
| 组合 | 宿主 | 子应用 | 端口 |
|
|
6
|
-
|---|---|---|---|
|
|
7
|
-
| Vue 宿主 × React 子应用 | [vue-host](./vue-host)(5314) | [react-remote](./react-remote)(5303) | 先起 5303 |
|
|
8
|
-
| React 宿主 × Vue 子应用 | [react-host](./react-host)(5304) | [vue-remote](./vue-remote)(5313) | 先起 5313 |
|
|
9
|
-
|
|
10
|
-
四个工程互相独立:`npm install` 即用 registry 正式包;宿主同时安装两套框架并全部 singleton(桥接使用合同),子应用只装自己的框架。
|
|
11
|
-
|
|
12
|
-
## 快速开始(Vue 宿主 × React 子应用)
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
cd react-remote && npm install && npm run dev # 终端 1:http://localhost:5303
|
|
16
|
-
cd ../vue-host && npm install && npm run dev # 终端 2:http://localhost:5314
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
打开 5314:点击「切换到 Bob / 登出」体验受控会话(卸载→清 context→新代次重挂);子应用内部按钮操作其 memory 路由与本地状态。
|
|
20
|
-
|
|
21
|
-
## 快速开始(React 宿主 × Vue 子应用)
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
cd vue-remote && npm install && npm run dev # 终端 1:http://localhost:5313
|
|
25
|
-
cd ../react-host && npm install && npm run dev # 终端 2:http://localhost:5304
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 生产构建与部署
|
|
29
|
-
|
|
30
|
-
每个示例 `npm run build` 产出各自子路径(`/bridge-vue-host/` 等)。部署时保持「子应用子路径 + 宿主子路径」并列,宿主 fulgurjs 配置的 `prod` 指向子应用子路径(已是根相对写法)。NGINX 需对各 `fulgurjs-remoteEntry.js`/`fulgurjs-manifest.json`/`index.html` 设置 no-cache,其余静态资源可长缓存。
|
|
31
|
-
|
|
32
|
-
## 范围声明(v1)
|
|
33
|
-
|
|
34
|
-
- 只做子应用级挂载/卸载;组件级混渲染(Vue 里直接渲染 React 组件)不支持。
|
|
35
|
-
- 子应用用 memory 路由,不与宿主 URL 同步。
|
|
36
|
-
- 无 JS 沙箱与 CSS 隔离:远程全局样式/body 级副作用会影响宿主,需自行命名空间治理。
|