@fulgurjs/federation 3.0.0 → 4.0.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.
@@ -12,7 +12,9 @@
12
12
  | 主子应用 window 隔离/沙箱 | 无沙箱:同 realm 直渲染(`window.xxx` 全局桥自然可用) |
13
13
  | props 传递(qiankun 传参) | 组件 props(路由通道 = params+query 合并;弹窗通道 = 显式 v-bind) |
14
14
  | 公共依赖 externals/主应用共享 | `shared`(singleton 协商,"已加载优先") |
15
- | `qiankun` 运行时 + single-spa | `virtual:fulgurjs-runtime`(15KB 级,无 single-spa) |
15
+ | `qiankun` 运行时 + single-spa | `@fulgurjs/federation/runtime`(运行时内核 15KB 级,无 single-spa) |
16
+
17
+ 应用代码统一从 `@fulgurjs/federation/runtime` 导入。Vite 配置继续从 `@fulgurjs/federation` 导入插件。升级自 3.x 时,将 `virtual:fulgurjs-api` 替换为物理子路径;`remoteSchema` 仍按具名导入,开发态由插件填充,构建态为空清单。
16
18
 
17
19
  ## 二、迁移步骤(真实案例顺序)
18
20
 
@@ -36,7 +38,7 @@
36
38
  - [ ] 零兜底:联邦不可用显式报错(杀 remote 故障注入)
37
39
  - [ ] 装后可用:npm pack → 干净项目 dev+prod(e2e/h7-install-test.sh)
38
40
 
39
- > **目录约定说明**:联邦相关产物统一收在 **`src/fulgurjs/`** 一个文件夹(每个应用一份,内附 README 说明归属)——`types/`(插件每次 dev 自动生成的类型直连与运行时类型垫片,**勿手改**;src 布局 tsconfig 零配置生效,无 src 布局回退根目录 `.fulgurjs/types/`)与按角色划分的代码子目录:远程应用为 `exposes/`(联邦启动引导 federatedBoot + 供外部加载的组件),宿主应用为 `host/`(桥接 bridge.ts + 页面路由表 pages.ts)。均为迁移工具脚手架约定而非插件要求,可按团队习惯重组,只要 vite `exposes` 映射与调用点跟着改。
41
+ > **目录约定说明**:联邦相关产物统一收在 **`src/fulgurjs/`** 一个文件夹(每个应用一份,内附 README 说明归属)——`types/`(插件每次 dev 自动生成的远程 exposes 类型直连,**勿手改**;运行时类型由包的 `/runtime` 子路径直接解析;无 src 布局回退根目录 `.fulgurjs/types/`)与按角色划分的代码子目录:远程应用为 `exposes/`(联邦启动引导 federatedBoot + 供外部加载的组件),宿主应用为 `host/`(桥接 bridge.ts + 页面路由表 pages.ts)。均为迁移工具脚手架约定而非插件要求,可按团队习惯重组,只要 vite `exposes` 映射与调用点跟着改。
40
42
 
41
43
  ## 三B、首次使用避坑清单(真实迁移踩坑实录,全文见仓库 README「避坑指南」节)
42
44
 
@@ -51,24 +53,24 @@
51
53
  | 7 | 登录异步链未完成就断言 | e2e 偶发被弹回登录页 | 等「登录表单消失」而非固定秒数;后台慢链 ≥15s |
52
54
  | 8 | 多版本组件库 CSS | 后加载覆盖 `:root` 变量 | 主流版本变量一致则无感;升级时留意 |
53
55
  | 9 | 后端缺端点 | 404/401 资源报错 | 代理/NGINX 层加诚实空响应垫片(不伪造业务数据) |
54
- | 10 | 远程页面(exposes 目标文件)静态导入 `virtual:fulgurjs-runtime` | 直接静态导入 | 插件自动把该导入改写为惰性单例代理——远程页面写法与宿主完全一致(详见下节三B-1) |
56
+ | 10 | 远程页面(exposes 目标文件)静态导入 `@fulgurjs/federation/runtime` | 直接静态导入 | 插件自动把该导入改写为惰性单例代理——远程页面写法与宿主完全一致(详见下节三B-1) |
55
57
 
56
58
  ### 三B-1、远程页面如何取宿主运行时
57
59
 
58
60
  exposes 目标文件(被宿主跨源加载的远程页面/组件)**可以直接静态导入**
59
- `virtual:fulgurjs-runtime`——插件自动把远程页面里的该导入改写为**惰性单例代理**:
61
+ `@fulgurjs/federation/runtime`——插件自动把远程页面里的该导入改写为**惰性单例代理**:
60
62
  求值期零副作用、调用期转发页面级运行时单例。宿主与远程写法完全一致,无需区分。
61
63
 
62
64
  ```ts
63
65
  // 远程页面内,与宿主页面写法完全一致
64
- import { loadRemote } from 'virtual:fulgurjs-runtime'
66
+ import { loadRemote } from '@fulgurjs/federation/runtime'
65
67
  ```
66
68
 
67
- 组件直渲染推荐用 `@fulgurjs/federation/vue` 子路径的 `remoteComponent`——
69
+ 组件直渲染推荐用 `@fulgurjs/federation/runtime` 子路径的 `remoteComponent`——
68
70
  `defineAsyncComponent + loadRemote` 的标准封装,加载失败显式错误占位(错误码+根因+修法),无任何兜底:
69
71
 
70
72
  ```ts
71
- import { remoteComponent } from '@fulgurjs/federation/vue'
73
+ import { remoteComponent } from '@fulgurjs/federation/runtime'
72
74
  const FederatedBusinessForm = remoteComponent('demo-host/FormRouterPage')
73
75
  ```
74
76
 
@@ -81,7 +83,7 @@ realm 检测等特殊场景,常规集成无需使用。
81
83
 
82
84
  ```ts
83
85
  // 宿主桥(admin/src/fulgurjs/host/bridge.ts)——登录完成后一次性提供
84
- import { provideAppContext } from '@fulgurjs/federation/context'
86
+ import { provideAppContext } from '@fulgurjs/federation/runtime'
85
87
  provideAppContext({
86
88
  user, getToken, store, hostApp, locale, // 只传有真实消费的键(token 一律 getToken() 拉取)
87
89
  events: { main: mainEvents }, // 方法池:宿主提供 main.*,子应用反向注册 bpm.* / lowcode.*
@@ -89,12 +91,12 @@ provideAppContext({
89
91
  })
90
92
 
91
93
  // 远程启动引导(xxx/src/fulgurjs/exposes/federatedBoot.ts)——显式校验消费
92
- import { requireAppContext } from '@fulgurjs/federation/context'
94
+ import { requireAppContext } from '@fulgurjs/federation/runtime'
93
95
  const { store, user, hostApp } = requireAppContext('store', 'user', 'hostApp')
94
96
  // 缺键 → [fulgurjs:CC-001](三段式,指向宿主桥);独立直开远程页 → [fulgurjs:CC-002]
95
97
 
96
98
  // 页面读点(替代 window.mainAppProps?.xxx)
97
- import { getAppContext } from '@fulgurjs/federation/context'
99
+ import { getAppContext } from '@fulgurjs/federation/runtime'
98
100
  const dict = getAppContext().events?.main?.getDictItems?.('sex')
99
101
  ```
100
102
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fulgurjs/federation",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
5
  "description": "Vite Module Federation with full Webpack MF parity. Dev & production, no compromise.",
6
6
  "license": "MIT",
@@ -18,8 +18,9 @@
18
18
  "import": "./dist/config.js",
19
19
  "require": "./dist/config.cjs"
20
20
  },
21
- "./client": {
22
- "types": "./client.d.ts"
21
+ "./runtime": {
22
+ "types": "./dist/runtime-entry.d.ts",
23
+ "import": "./dist/runtime-entry.js"
23
24
  },
24
25
  "./package.json": "./package.json",
25
26
  "./internal/context.js": {
@@ -36,18 +37,25 @@
36
37
  "types": "./dist/vue.d.ts",
37
38
  "import": "./dist/vue.js",
38
39
  "require": "./dist/vue.cjs"
40
+ },
41
+ "./internal/vue-adapter.js": {
42
+ "types": "./dist/vue-adapter.d.ts",
43
+ "import": "./dist/vue-adapter.js",
44
+ "require": "./dist/vue-adapter.cjs"
39
45
  }
40
46
  },
41
47
  "typesVersions": {
42
48
  "*": {
43
49
  "config": [
44
50
  "dist/config.d.ts"
51
+ ],
52
+ "runtime": [
53
+ "dist/runtime-entry.d.ts"
45
54
  ]
46
55
  }
47
56
  },
48
57
  "files": [
49
58
  "dist",
50
- "client.d.ts",
51
59
  "README.md",
52
60
  "LICENSE",
53
61
  "CHANGELOG.md",
@@ -59,7 +67,7 @@
59
67
  "docs/P5-vite7-8兼容矩阵.md"
60
68
  ],
61
69
  "scripts": {
62
- "build": "cp ../../README.md README.md && mkdir -p docs && cp ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md && rm -rf examples && cp -r ../../examples examples && 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/config.ts src/vue.ts src/context.ts --format esm,cjs --dts --external vite --target node18 --clean && 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/check-gzip.mjs && node scripts/check-manual-codes.mjs",
70
+ "build": "cp ../../README.md README.md && mkdir -p docs && cp ../../docs/迁移指南.md ../../docs/webpack-mf-对照与缺口.md ../../docs/沙箱边界审计.md ../../docs/P5-vite7-8兼容矩阵.md docs/ && cp ../../CHANGELOG.md CHANGELOG.md && cp ../../DESIGN.md DESIGN.md && rm -rf examples && cp -r ../../examples examples && 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/config.ts src/vue.ts src/vue-adapter.ts src/context.ts --format esm,cjs --dts --external vite --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite,vue --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",
63
71
  "dev": "tsup --watch",
64
72
  "test": "vitest run",
65
73
  "typecheck": "tsc --noEmit",
package/client.d.ts DELETED
@@ -1,180 +0,0 @@
1
- /**
2
- * virtual:fulgurjs-api 客户端类型声明(3.0.0 起唯一公开运行时入口)。
3
- *
4
- * 应用代码的一切联邦导入——runtime 函数、context 三函数(provideAppContext/
5
- * getAppContext/requireAppContext)、definePages/validatePages、remoteSchema、
6
- * remoteComponent——全部来自 'virtual:fulgurjs-api'。旧入口
7
- * (virtual:fulgurjs-runtime、@fulgurjs/federation/{context,pages,vue})已删除。
8
- * 类型由本声明聚合(script 文件:顶层无 import/export,环境模块声明才生效)。
9
- *
10
- * 用法(二选一):
11
- * 1. dev 启动后插件自动在类型目录(默认 src/fulgurjs/types/,无 src 布局回退 .fulgurjs/types/)
12
- * 生成 fulgurjs-runtime.d.ts 加载垫片——只要 tsconfig include 了该目录
13
- * (远程模块类型直连本就要求),运行时类型零配置生效;
14
- * 2. tsconfig.json → compilerOptions.types 加 "@fulgurjs/federation/client"(对齐 vite/client 模式)。
15
- *
16
- * ⚠️ 本文件必须是 script 形态(顶层不得出现 import/export)——环境模块声明
17
- * (declare module)住在 module 文件里会退化为 augmentation 被静默忽略。
18
- * 与 dist/runtime.js 的导出面一一对应(tests/client-types.test.ts 守漂移)。
19
- * 对外类型(LoadRemoteOptions 等)经 'virtual:fulgurjs-runtime' 模块本身导出,
20
- * 用法:import type { LoadRemoteOptions } from 'virtual:fulgurjs-runtime'。
21
- */
22
- declare module 'virtual:fulgurjs-api' {
23
- /** shared 协商条目(window.__FULGURJS_SCOPE__ 内的形态) */
24
- export interface ShareEntry {
25
- version: string
26
- get: () => Promise<any>
27
- from: string
28
- eager: boolean
29
- loaded?: boolean
30
- }
31
-
32
- /** 远程注册配置(federation({ remotes }) 对象形态的运行时等价物) */
33
- export interface RemoteInput {
34
- name: string
35
- entry: string
36
- shareScope?: string
37
- timeout?: number
38
- retries?: number
39
- fallback?: string[]
40
- breaker?: { threshold: number; resetMs: number }
41
- manifestUrl?: string
42
- container?: unknown
43
- containerPromise?: Promise<unknown>
44
- }
45
-
46
- export interface LoadRemoteOptions {
47
- /** 单次调用级重试覆盖(缺省用远程注册值,默认 2) */
48
- retries?: number
49
- /** 显式降级:加载失败时返回该模块(错误事件仍显式发出,绝不静默兜底) */
50
- fallbackModule?: () => Promise<any> | any
51
- }
52
-
53
- export interface PreloadRemoteOptions {
54
- /** preload = 立即高优先级;prefetch = 空闲时低优先级 */
55
- mode?: 'preload' | 'prefetch'
56
- }
57
-
58
- export interface LoadShareOptions {
59
- shareScope?: string
60
- shareKey?: string
61
- requiredVersion?: string | false
62
- singleton?: boolean
63
- strictVersion?: boolean
64
- fallback?: () => Promise<any>
65
- }
66
-
67
- /**
68
- * 跨应用上下文标准字段表见 README §9。token 快照 / formUrl / baseUrl 不在默认 provide 内——
69
- * 取 token 用 getToken()(拉取式不过期),其余按项目需要经扩展位自定。
70
- * 值 API 在 '@fulgurjs/federation/context' 子路径(runtime.js 不导出 context 函数,
71
- * 此处仅类型随虚拟模块声明供 type-only import);读写约定:宿主桥先写标准字段,
72
- * 远程 boot 只增不改宿主键;嵌套对象(如 events)引用共享。
73
- */
74
- export interface AppContext {
75
- /** 宿主登录用户原始形态(只读约定) */
76
- user: Record<string, any>
77
- /** 取最新 token(拉取式防过期;0.8.2 起 bridge 不再传一次性 token 快照) */
78
- getToken?: () => string | undefined
79
- /** 宿主 pinia 实例:子应用 useUserStore(ctx.store) 拿共享响应式状态 */
80
- store?: unknown
81
- /** 宿主 Vue App 实例(同 realm 直引用):全局组件/指令注册目标 */
82
- hostApp?: unknown
83
- /** EP locale 等 UI 配置(原 W4 字段) */
84
- locale?: unknown
85
- /** 事件/方法池:events.main.* 宿主提供、events.bpm.* / events.lowcode.* 子应用反向注册 */
86
- events?: Record<string, any>
87
- /** 项目扩展位(formUrl/baseUrl 等自定义键,按需自行提供) */
88
- [key: string]: unknown
89
- }
90
-
91
- /** 运行时单例(与 globalThis.__FULGURJS_RUNTIME__ 同一实例,方法面冻结) */
92
- export interface FgRuntime {
93
- shareScopeMap: Record<string, Record<string, Record<string, ShareEntry>>>
94
- initSharing(scopeName?: string): FgRuntime['shareScopeMap']
95
- registerShare(
96
- scopeName: string,
97
- name: string,
98
- version: string,
99
- get: () => Promise<any>,
100
- opts?: { from?: string; eager?: boolean; loaded?: boolean },
101
- ): void
102
- registerRemotes(remotes: RemoteInput[]): void
103
- registerRemote(remote: RemoteInput): void
104
- registerPlugins(plugins: unknown[]): void
105
- loadShare<T = any>(name: string, opts?: LoadShareOptions): Promise<T>
106
- loadRemote<T = Record<string, any>>(spec: string, opts?: LoadRemoteOptions): Promise<T>
107
- getContainer(name: string): Promise<{ name: string; init: (scope: unknown) => void | Promise<void>; get: (module: string) => Promise<any> }>
108
- preloadRemote(spec: string, opts?: PreloadRemoteOptions): Promise<void>
109
- parseSpec(spec: string): { remote: string; module: string }
110
- }
111
-
112
- export const version: string
113
- export const runtime: FgRuntime
114
- export const shareScopeMap: FgRuntime['shareScopeMap']
115
- export function getRuntime(): FgRuntime
116
- export function initSharing(scopeName?: string): FgRuntime['shareScopeMap']
117
- export function registerShare(
118
- scopeName: string,
119
- name: string,
120
- version: string,
121
- get: () => Promise<any>,
122
- opts?: { from?: string; eager?: boolean; loaded?: boolean },
123
- ): void
124
- export function registerRemotes(remotes: RemoteInput[]): void
125
- export function registerRemote(remote: RemoteInput): void
126
- export function registerPlugins(plugins: unknown[]): void
127
- export function loadShare<T = any>(name: string, opts?: LoadShareOptions): Promise<T>
128
- export function loadRemote<T = Record<string, any>>(spec: string, opts?: LoadRemoteOptions): Promise<T>
129
- export function getContainer(
130
- name: string,
131
- ): Promise<{ name: string; init: (scope: unknown) => void | Promise<void>; get: (module: string) => Promise<any> }>
132
- export function preloadRemote(spec: string, opts?: PreloadRemoteOptions): Promise<void>
133
- export function parseSpec(spec: string): { remote: string; module: string }
134
- /** 兜底解包:命名空间有 default 取 default,否则原样返回 */
135
- export function unwrapDefault<T>(ns: { default?: T } | T): T
136
- /** 与 globalThis.__FULGURJS_RUNTIME__ 同一实例(方法面冻结) */
137
- const runtimeDefault: FgRuntime
138
- export default runtimeDefault
139
-
140
- // ── 跨应用上下文(原 @fulgurjs/federation/context,3.0.0 并入)──
141
- export function provideAppContext(config: Partial<AppContext> & Record<string, unknown>): void
142
- export function getAppContext(): AppContext
143
- export function requireAppContext(...keys: string[]): AppContext
144
-
145
- // ── 页面路由表(原 @fulgurjs/federation/pages,3.0.0 并入)──
146
- export interface PageRouteLike {
147
- route: string
148
- name?: string
149
- spec?: string
150
- title?: string
151
- keepAlive?: boolean
152
- }
153
- export interface PagesOptions {
154
- pages: PageRouteLike[]
155
- remoteSchema?: { [remoteKey: string]: { exposes: string[]; exists: boolean } }
156
- remoteNameOf?: (route: string) => string
157
- exposeOf?: (route: string, remoteName: string) => string
158
- }
159
- export interface PageViolation {
160
- level: 'ERROR' | 'WARN'
161
- route: string
162
- reason: string
163
- }
164
- export function validatePages(pages: PageRouteLike[], opts?: PagesOptions): PageViolation[]
165
- export function definePages<P extends PageRouteLike[]>(pages: P, opts?: PagesOptions): P
166
-
167
- // ── Vue 远程组件直渲染(原 @fulgurjs/federation/vue,3.0.0 并入)──
168
- export interface RemoteComponentOptions {
169
- loadingComponent?: unknown
170
- errorComponent?: unknown
171
- retries?: number
172
- delay?: number
173
- timeout?: number
174
- }
175
- export function remoteComponent(spec: string, opts?: RemoteComponentOptions): unknown
176
-
177
- // ── 远程 exposes 清单(dev 异步 probe;build 为空表,路由校验按 R3 降级)──
178
- export const remoteSchema: { [remoteKey: string]: { exposes: string[]; exists: boolean } }
179
- }
180
-