@fulgurjs/federation 4.2.1 → 4.3.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 +37 -0
- package/README.md +30 -23
- package/dist/{chunk-S3MYAJG5.js → chunk-LU3MBKB2.js} +1 -1
- package/dist/{chunk-NUZKZUTD.js → chunk-NOMYWDZN.js} +6 -9
- package/dist/cli.js +78 -33
- package/dist/context.cjs +5 -5
- package/dist/context.js +5 -5
- package/dist/index.cjs +74 -89
- package/dist/index.js +74 -89
- package/dist/runtime.js +22 -10
- package/dist/vue-adapter.cjs +6 -9
- package/dist/vue-adapter.js +1 -1
- package/dist/vue.cjs +72 -58
- package/docs//350/277/201/347/247/273/346/214/207/345/215/227.md +6 -5
- package/examples/README.md +22 -0
- package/examples/host/fulgurjs.config.ts +26 -0
- package/examples/remote-a/fulgurjs.config.ts +24 -0
- package/examples/remote-a/src/views/Detail.vue +3 -0
- package/examples/remote-a/src/views/Home.vue +3 -0
- package/package.json +2 -1
- package/examples/fulgurjs.config.example.ts +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.3.1(2026-09-26)
|
|
4
|
+
|
|
5
|
+
- 将插件自身的配置、共享依赖和远程加载诊断改为中文,保留错误码与原始底层异常;修复 `MFU-010` 将多个兼容候选版本误判为冲突的问题,真正不兼容时显示原因与修法,并对同一版本组合去重。
|
|
6
|
+
- 移除基于裸导入前缀猜测“漏配远程”的提示;它会将 `vite/modulepreload-polyfill`、`@vue/runtime-dom` 等普通依赖误报为远程配置问题。真正无法解析的导入仍由构建工具报错。
|
|
7
|
+
- 中文诊断使运行时 gzip 从 7547B 增至约 8649B;体积门禁由 8192B 调整为 9216B,仍限制无意增长。
|
|
8
|
+
|
|
9
|
+
## 4.3.0(2026-09-25)
|
|
10
|
+
|
|
11
|
+
### 修复(4.2.1 复核问题)
|
|
12
|
+
|
|
13
|
+
- **`check-pages` 远程地址全形态推导**:新增 `manifestUrlForRemoteAddress` 共享解析(与运行时同语义)——绝对 prod 地址支持目录 URL / 完整 `fulgurjs-remoteEntry.js` URL / `name@url` 前缀 / `fulgurjs-manifest.json` 直链;`name@url` 形态此前被 `^https?://` 门禁误判为相对地址而报「无法验证」。相对 prod + `--site` 组合同样经统一推导。
|
|
14
|
+
- **`check-pages` manifest 来源优先级**:显式 `--manifest` > 显式 `--site`(只用指定来源,失败=「无法验证」)> 本地 dist(仅在未指定任何线上来源时兜底)。修复旧聚合配置在 `--site` 指定死地址时仍回退本地旧 dist 并退出 0 的问题——指定线上站点验证时不再可能被本地产物冒充。来源报告带实际命中 URL(含 localhost 回退)。
|
|
15
|
+
- **CLI 独立目录 TS 配置加载**(`app-config.ts`):esbuild 定位改为「受控编译器」——候选(配置工程直连 → 经 vite 传递依赖 → CLI 自身依赖树)必须先通过 `satisfies` 语法能力探针(esbuild ≥0.14.49),不再按「找到就用」收编偶然悬挂的旧版(曾实测 esbuild 0.11.23 使合法配置报 `Expected ";" but found "satisfies"`);`esbuild` 成为包直接依赖(^0.27.0),无本地 Vite 的独立目录 `init`/`explain` 开箱可用(Node 18/24 实测)。
|
|
16
|
+
- **CLI localhost 回环回退**:Node 18 的 fetch 将 `localhost` 只解析到 `::1`(本机服务通常只监听 IPv4),CLI 抓取 manifest 失败时自动改试 `127.0.0.1` 并以实际命中的 URL 作为来源报告(Node 18 下 `--site http://localhost:8662` 不再误报「无法验证」)。
|
|
17
|
+
|
|
18
|
+
### 文档订正
|
|
19
|
+
|
|
20
|
+
- **remoteEntry 缓存语义统一**:修正「固定文件名利于 CDN 长缓存」与部署章节「必须 no-cache」的自相矛盾——统一为「文件名稳定便于引用,入口内容每次构建变必须 no-cache;只有带内容哈希的 chunk 才可长缓存」。
|
|
21
|
+
- **README「真实工程验证」表述**:移除「27 页零报错、逐页写操作闭环」等以 23/23 页有字为证据的过度结论,改为「以 26 条页面记录 + 27 个菜单入口的逐项业务断言为准,结论见对应版本验收报告」。
|
|
22
|
+
- **示例重构**:`examples/fulgurjs.config.example.ts`(无默认导出、不可运行)拆为 `examples/remote-a/` 与 `examples/host/` 两个真实可复制、可 CLI 校验的单项目配置(含最小源文件),附 README 复制方法。
|
|
23
|
+
|
|
24
|
+
### 修复(续)
|
|
25
|
+
|
|
26
|
+
- **`createHostPages` 异步组件包装结构回归 4.2.1 已验证形态**:直接命名 `defineAsyncComponent`
|
|
27
|
+
包装器(按 spec 独立创建,不触碰远程模块导出对象),移除外层 stateless `defineComponent`
|
|
28
|
+
包装——外层包装会在「保活页 → 登出/切换布局」的卸载路径上触发 Vue core
|
|
29
|
+
`parentComponent.ctx.deactivate is not a function`(KeepAlive + async component 竞态,
|
|
30
|
+
vue 3.5.43 实测复现)。
|
|
31
|
+
- **会话组件缓存只在新的非空 `sessionKey` 出现时重置**:登出(sessionKey 变 undefined)不清缓存——
|
|
32
|
+
`clearAppContext` 后路由过渡期宿主布局仍会重渲染当前联邦页,此刻重建组件会让 KeepAlive
|
|
33
|
+
在激活路径上换子组件。会话语义不受影响:onSession 去重由 runtime 在 `loadRemote` 时按当前
|
|
34
|
+
sessionKey 判定;下一次登录出现新代次 ID 时缓存照常重置。
|
|
35
|
+
|
|
36
|
+
### 性能
|
|
37
|
+
|
|
38
|
+
- **整远程预载默认关闭**(宿主桥模板契约):`PREFETCH_REMOTES` 默认 `[]`——首次进入联邦页只下载该页所需资源(dashboard 不再因登录而预载全部 expose 清单)。`preloadRemote('remote')` 显式整远程预载能力保留;README §9.1.3 新增四层区分(路由表声明 / 页面真实加载 / 单页预取 / 整远程预取)与「预取是下载不等于执行」语义。
|
|
39
|
+
|
|
3
40
|
## 4.2.1(2026-09-25)
|
|
4
41
|
|
|
5
42
|
### 修复
|
package/README.md
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
| 运行时体积 | ~40KB+ | 不等 | **gzip < 5KB** |
|
|
20
20
|
| 配置出错时 | 难排查 | 报错晦涩 | 三段式报错:`got / expected / example` |
|
|
21
21
|
|
|
22
|
-
**真实工程验证**:某企业级 mes 系统(admin 宿主 + bpm/lowcode 两个子应用,21+6 页)已全量迁移,三个应用各自维护项目根目录的 `fulgurjs.config.ts`、Vite 一处 `federation(fulgurjsConfig)`
|
|
22
|
+
**真实工程验证**:某企业级 mes 系统(admin 宿主 + bpm/lowcode 两个子应用,21+6 页)已全量迁移,三个应用各自维护项目根目录的 `fulgurjs.config.ts`、Vite 一处 `federation(fulgurjsConfig)` 接入。历史版本验收曾出现"23/23 页面有字即全过"的口径偏差(4.2.1 复核订正:参数页需用有效业务数据进入、错误页不得算通过);最新一轮以 26 条页面记录 + 27 个菜单入口的逐项业务断言为准,结论见对应版本验收报告与 `docs/` 下证据文件(见[迁移指南](#文档))。
|
|
23
23
|
|
|
24
24
|
## 特性
|
|
25
25
|
|
|
26
26
|
- **exposes / remotes / shared 全语义**:`name@url` 语法、键重命名、promise-based remote、semver 全语法 requiredVersion、版本协商(最高版本胜出)、singleton / strictVersion、已加载版本永不替换、多版本共存、shareKey 重定向、多 shareScope
|
|
27
27
|
- **UMD / CJS-only 依赖开箱即用**:element-plus、avue 等只有 UMD/CJS 产物的依赖直接进 `optimizeDeps.include` 即可——dev 期插件自动把预构建产物内的 shared 键改道协商门面;build 期自动把 CJS `require(<shared>)` 重定向到垫片,双运行时免疫
|
|
28
28
|
- **自动异步边界**:top-level await 自动注入(es2022+),无需 webpack 式手工 `import('./bootstrap')`
|
|
29
|
-
- **稳定产物**:remoteEntry
|
|
29
|
+
- **稳定产物**:remoteEntry 固定文件名便于稳定引用(入口内容每次构建变,**必须 no-cache**——只有带内容哈希的 chunk 才可长缓存);`fulgurjs-manifest.json` 资源清单;expose 独立 chunk
|
|
30
30
|
- **容错(对齐 webpack MF 2.0 errorLoadRemote)**:加载重试 / 熔断 / 超时内置;`loadRemote(spec, { retries, fallbackModule })` 单次调用级覆盖——失败时返回 fallback 模块,错误事件仍显式发出(**绝不静默兜底**,不传则照旧抛错)
|
|
31
31
|
- **增强能力**:dts 类型直连(dev 补全直达 remote 源码)、`preloadRemote()` manifest 驱动精确预载、runtimePlugins 钩子
|
|
32
32
|
- **HMR 全链路**:remote 改动 → host 页面热更,L1 组件热替换 / L2 状态保留 / L3 错误覆盖与恢复
|
|
@@ -234,7 +234,7 @@ import { loadRemote, provideAppContext, getAppContext, requireAppContext, clearA
|
|
|
234
234
|
```bash
|
|
235
235
|
# 1) 生成单项目 fulgurjs.config.ts 起步模板(默认导出直接是 federation() 选项;已存在则拒绝,--force 覆盖)
|
|
236
236
|
npx fulgurjs init
|
|
237
|
-
# 样例:examples/fulgurjs.config.
|
|
237
|
+
# 样例:examples/remote-a/fulgurjs.config.ts 与 examples/host/fulgurjs.config.ts(可整份复制的单项目配置)
|
|
238
238
|
|
|
239
239
|
# 2) 校验配置并输出接入块:federation(fulgurjsConfig) 两行接法 + 通用核对清单(纯打印,不写文件)
|
|
240
240
|
npx fulgurjs init --config fulgurjs.config.ts
|
|
@@ -316,7 +316,7 @@ import { federation, type FederationOptions } from '@fulgurjs/federation'
|
|
|
316
316
|
| 选项 | 类型 | 默认 | 说明 |
|
|
317
317
|
|---|---|---|---|
|
|
318
318
|
| `name` | `string` **必填** | — | 容器名。同页面宿主/远程必须唯一(也是 uniqueName);须匹配 `/^[a-zA-Z][\w.-]*$/` |
|
|
319
|
-
| `filename` | `string` | `'fulgurjs-remoteEntry.js'` | prod
|
|
319
|
+
| `filename` | `string` | `'fulgurjs-remoteEntry.js'` | prod 容器入口文件名(固定文件名便于引用与部署规则落位;入口内容每次构建变,**必须 no-cache**,长缓存只给带内容哈希的 chunk) |
|
|
320
320
|
| `exposes` | `Record<string, string \| { import: string; name?: string }>` | — | 对外暴露模块:键 `'./X'`,值源文件路径;`name` 为稳定 chunk 文件名。键不得占用内部保留键 `./__fulgurjs_setup__`(CFG-012) |
|
|
321
321
|
| `setup` | `string` | —(无初始化行为) | **可选远程初始化入口**:相对应用根的 TS/JS 模块路径。默认导出 `setup(context)` 应用级执行一次(容器首次被加载业务模块前);可选具名导出 `onSession(context)` 按宿主 `sessionKey` 去重执行。其余导出不作为生命周期入口。执行时序/去重/失败重试/错误码见 §10 |
|
|
322
322
|
| `remotes` | `Record<string, string \| RemoteEntryConfig \| (() => Promise<any>)>` | — | 消费的远程,三种形态见下表 |
|
|
@@ -400,7 +400,7 @@ shared: {
|
|
|
400
400
|
}
|
|
401
401
|
```
|
|
402
402
|
|
|
403
|
-
版本裁决语义对齐 webpack:满足 requiredVersion 的最高版本胜出;已加载版本永不替换;singleton
|
|
403
|
+
版本裁决语义对齐 webpack:满足 requiredVersion 的最高版本胜出;已加载版本永不替换;singleton 收敛到唯一实例;strictVersion 冲突抛 MFU-003。`MFU-010` 仅在最终选中的单例版本不满足某个消费方的 `requiredVersion` 时告警。提示会列出候选版本、实际提供方、影响及修法;同一版本组合只提示一次。多个候选版本本身不是错误,例如 `^2.1.7` 包含 `2.3.1`,不能仅凭两个版本号不同就判定不兼容。
|
|
404
404
|
|
|
405
405
|
### 2. 运行时 API — `@fulgurjs/federation/runtime`
|
|
406
406
|
|
|
@@ -595,7 +595,7 @@ apps[] })` 形态自动识别并保持 4.1.0 行为;程序化加载 `loadRepoC
|
|
|
595
595
|
| | `MFU-007` | 预加载失败(不阻断业务) |
|
|
596
596
|
| | `MFU-008` | 未知远程 |
|
|
597
597
|
| | `MFU-009` | 加载到的模块没有任何导出 |
|
|
598
|
-
| | `MFU-010` |
|
|
598
|
+
| | `MFU-010` | 选中的共享单例版本不满足消费方要求;显示版本、提供方、影响和修法,同一组合只告警一次 |
|
|
599
599
|
| | `MFU-011` | setup 生命周期入口导出形态非法(默认导出/具名 onSession 不是函数;报实际类型/预期签名/修法) |
|
|
600
600
|
| | `MFU-012` | setup/onSession 执行抛错(该次 loadRemote 拒绝;仅清失败阶段缓存,可直接重试,已成功的阶段不重复) |
|
|
601
601
|
| | `MFU-013` | 远程声明 onSession 但宿主 AppContext 缺 sessionKey(登录代次;禁止用 token 充当) |
|
|
@@ -740,7 +740,7 @@ const res = await getDictItems('sex')
|
|
|
740
740
|
|---|---|---|---|---|
|
|
741
741
|
| 页面保活 | `keepAlive` | `boolean` | `false` | 页面路由表条目(`src/fulgurjs/host/pages.ts`) |
|
|
742
742
|
| 页面加载骨架屏 | —(内置,无配置项) | — | 见下方内置参数 | `src/fulgurjs/host/pages.ts` 页面工厂 |
|
|
743
|
-
| 空闲预载 | `PREFETCH_REMOTES` | `string[]` |
|
|
743
|
+
| 空闲预载 | `PREFETCH_REMOTES` | `string[]` | `[]`(关闭整远程预载,按需加载;详见 §9.1.3) | `src/fulgurjs/host/bridge.ts` 顶部常量 |
|
|
744
744
|
| 联邦诊断面板 | —(内置页面) | — | 常驻 | 路由 `/fulgurjs-demo` |
|
|
745
745
|
|
|
746
746
|
#### 9.1.1 页面保活 — `keepAlive`
|
|
@@ -780,25 +780,32 @@ const res = await getDictItems('sex')
|
|
|
780
780
|
|
|
781
781
|
如需自定义加载占位(如品牌 logo 动画),不经页面工厂,改用 `remoteComponent(spec, { loadingComponent })`(见 §8)。
|
|
782
782
|
|
|
783
|
-
#### 9.1.3 空闲预载 — `PREFETCH_REMOTES
|
|
783
|
+
#### 9.1.3 空闲预载 — `PREFETCH_REMOTES`(默认关闭)
|
|
784
784
|
|
|
785
|
-
|
|
785
|
+
**先分清四层(重要,勿把「路由声明多」当成「首屏会执行所有页面代码」)**:
|
|
786
786
|
|
|
787
|
-
|
|
|
787
|
+
| 层 | 机制 | 时机 | 网络成本 |
|
|
788
788
|
|---|---|---|---|
|
|
789
|
-
|
|
|
789
|
+
| ① 路由表声明 | `pages.data.ts` 26 条记录只是**数据映射**,不导入任何远程代码 | 构建期 | 零 |
|
|
790
|
+
| ② 页面真实加载 | `createHostPages` 对每页 `defineAsyncComponent` 包装,**渲染时**才 `loadRemote(spec)` | 用户打开该页 | 该页 chunk + CSS(首次该远程还有入口/共享依赖/setup) |
|
|
791
|
+
| ③ 单页预取 | `preloadRemote('remote-a/pages/remote-a/home', { mode: 'prefetch' })` | 项目主动调用 | 该 expose 的 chunk + CSS(**只下载不执行**) |
|
|
792
|
+
| ④ 整远程预取 | `preloadRemote('remote-a', { mode: 'prefetch' })` | 项目显式开启 | manifest 全部 expose 的 chunk + CSS(**只下载不执行**) |
|
|
793
|
+
|
|
794
|
+
预取是**下载**(`modulepreload`/`stylesheet` 链接,`fetchPriority=low` 只是降低优先级、不等于不下载),**不等于执行页面代码**——`container.get()`、组件实例化、`setup/onSession` 都只由真实页面的 `loadRemote` 触发。已加载模块有 Promise 缓存:重复打开同页复用模块,换账号重做会话初始化但不重新下载 JS。多个 expose 共享同一 chunk 是正常打包结果。
|
|
795
|
+
|
|
796
|
+
宿主桥默认**关闭整远程预载**(`PREFETCH_REMOTES = []`):首次进入联邦页只下载该页所需资源,dashboard 不因登录而提前下载两个远程的全部页面文件。某项目的用户路径确有明确的「下一步页面」时,可低优先级预取一两个明确指定的 spec;把 `PREFETCH_REMOTES` 写成远程名列表则是**显式选择**整远程预热(下载完整 expose 清单)。
|
|
790
797
|
|
|
791
798
|
> 插件配置面(`FederationOptions`)**没有** `host.prefetch` 字段——4.1.0 前文档曾声称该配置存在,属错误描述,已订正。预载名单就是宿主桥里的常量,改名单只改这一个地方。
|
|
792
799
|
|
|
793
800
|
```ts
|
|
794
801
|
// src/fulgurjs/host/bridge.ts 顶部常量
|
|
795
|
-
const PREFETCH_REMOTES: string[] = [
|
|
802
|
+
const PREFETCH_REMOTES: string[] = [] // 默认:关闭整远程预载(按需加载)
|
|
796
803
|
|
|
797
|
-
//
|
|
798
|
-
|
|
804
|
+
// 只预取下一步很可能打开的明确页面(低优先级,只下载不执行)
|
|
805
|
+
// idle(() => preloadRemote('mes-bpm/pages/bpm/task/todo', { mode: 'prefetch' }))
|
|
799
806
|
|
|
800
|
-
//
|
|
801
|
-
const PREFETCH_REMOTES: string[] = []
|
|
807
|
+
// 显式预热整个远程(下载完整 expose 清单;确有真实使用路径再开启)
|
|
808
|
+
// const PREFETCH_REMOTES: string[] = ['mes-bpm', 'mes-lowcode']
|
|
802
809
|
```
|
|
803
810
|
|
|
804
811
|
行为与边界:
|
|
@@ -981,16 +988,16 @@ const Panel = await loadRemote('shop/Panel', {
|
|
|
981
988
|
所有配置问题在 `vite` 启动瞬间即报,固定三段式,可直接照抄修正:
|
|
982
989
|
|
|
983
990
|
```
|
|
984
|
-
[fulgurjs]
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
//
|
|
991
|
+
[fulgurjs] federation() 配置无效:remotes["remote-a"] 没有地址(external、dev、prod 至少填写一个)
|
|
992
|
+
当前值:{"dev":""}
|
|
993
|
+
预期值:至少一个地址;只填一个地址时开发与生产共用
|
|
994
|
+
修法示例:remotes: { 'remote-a': 'http://localhost:5101' }
|
|
995
|
+
// 或分别填写:{ 'remote-a': { dev: 'http://localhost:5101', prod: '/remote-a' } }
|
|
989
996
|
```
|
|
990
997
|
|
|
991
998
|
运行时加载失败同样给排查指引(remote dev server 未启动 / 地址配错 / CORS / NGINX 回退),并携带统一错误码:
|
|
992
999
|
|
|
993
|
-
统一错误码体系(CFG/DEV/BLD/MFU/CC 五段共 41 个)——**完整总表见上方 [API 参考 §6](#6-错误码总表41-个)
|
|
1000
|
+
统一错误码体系(CFG/DEV/BLD/MFU/CC 五段共 41 个)——**完整总表见上方 [API 参考 §6](#6-错误码总表41-个)**。插件自身的诊断文案使用中文,保留 API 名、配置键、版本号及第三方底层异常原文,以便定位问题。`MFU-010` 只表示实际复用的单例版本不满足消费方要求;多个兼容版本共存不会触发该告警。浏览器中来自 qiankun/single-spa、vue-i18n 等第三方的告警不由 fulgurjs 生成,应按各自来源排查。
|
|
994
1001
|
|
|
995
1002
|
调试出口:`window.__FULGURJS_SCOPE__`(share 协商实时结果)、`window.__FULGURJS_INFO__`(remote 状态/耗时/错误)。
|
|
996
1003
|
|
|
@@ -1016,7 +1023,7 @@ const Panel = await loadRemote('shop/Panel', {
|
|
|
1016
1023
|
pnpm --dir packages/plugin install && pnpm --dir packages/plugin build
|
|
1017
1024
|
for app in fixtures/host-vue fixtures/remote-a fixtures/remote-b e2e; do pnpm --dir "$app" install; done
|
|
1018
1025
|
|
|
1019
|
-
pnpm test:unit #
|
|
1026
|
+
pnpm test:unit # 单测(当前 385)
|
|
1020
1027
|
pnpm test:dev # dev e2e(10)
|
|
1021
1028
|
pnpm test:prod # prod e2e(8,需 NGINX,见 e2e/scripts/prod-setup.sh)
|
|
1022
1029
|
pnpm test # unit + dev + prod 全跑
|
|
@@ -53,7 +53,7 @@ function createHostPages(options, load) {
|
|
|
53
53
|
if (route.startsWith(prefix) || `${route}/` === prefix) return name;
|
|
54
54
|
}
|
|
55
55
|
throw new Error(
|
|
56
|
-
`[fulgurjs]
|
|
56
|
+
`[fulgurjs] \u9875\u9762\u8DEF\u7531 "${route}" \u672A\u5339\u914D\u4EFB\u4F55 remotePrefixes\uFF1A{ ${Object.entries(remotePrefixes).map(([k, v]) => `'${k}': '${v}'`).join(", ")} }
|
|
57
57
|
\u6839\u56E0: \u9875\u9762\u8868\u6761\u76EE\u7684\u8DEF\u7531\u4E0D\u5728\u4EFB\u4F55\u5DF2\u58F0\u660E\u7684\u8FDC\u7A0B\u524D\u7F00\u4E0B\u3002
|
|
58
58
|
\u4FEE\u6CD5: \u5728 remotePrefixes \u8865\u5145\u8BE5\u8DEF\u7531\u524D\u7F00 \u2192 \u8FDC\u7A0B\u540D\u7684\u6620\u5C04\uFF0C\u6216\u4FEE\u6B63\u9875\u9762\u8868 route\u3002`
|
|
59
59
|
);
|
|
@@ -100,8 +100,8 @@ function createHostPages(options, load) {
|
|
|
100
100
|
};
|
|
101
101
|
const component = (spec) => {
|
|
102
102
|
const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
|
|
103
|
-
const sessionKey = typeof sk === "string" ? sk : void 0;
|
|
104
|
-
if (sessionKey !== cacheSession) {
|
|
103
|
+
const sessionKey = typeof sk === "string" && sk !== "" ? sk : void 0;
|
|
104
|
+
if (sessionKey !== void 0 && sessionKey !== cacheSession) {
|
|
105
105
|
compCache.clear();
|
|
106
106
|
cacheSession = sessionKey;
|
|
107
107
|
}
|
|
@@ -115,7 +115,7 @@ function createHostPages(options, load) {
|
|
|
115
115
|
const inner = mod?.default ?? mod;
|
|
116
116
|
if (!inner) {
|
|
117
117
|
throw new Error(
|
|
118
|
-
`[fulgurjs]
|
|
118
|
+
`[fulgurjs] \u8FDC\u7A0B\u6A21\u5757 "${spec}" \u6CA1\u6709\u5BFC\u51FA\u53EF\u6E32\u67D3\u7EC4\u4EF6\uFF1B\u5F53\u524D\u503C\u7C7B\u578B\u4E3A ${inner === null ? "null" : typeof inner}\u3002
|
|
119
119
|
\u4FEE\u6CD5: \u6838\u5BF9\u8FDC\u7A0B exposes \u952E\u540D\u4E0E\u9875\u9762\u8868 spec \u662F\u5426\u4E00\u81F4\uFF08MFU-006 \u8BED\u4E49\uFF09`
|
|
120
120
|
);
|
|
121
121
|
}
|
|
@@ -125,11 +125,8 @@ function createHostPages(options, load) {
|
|
|
125
125
|
errorComponent: errorComponent ?? RemoteErrorPlaceholder,
|
|
126
126
|
delay
|
|
127
127
|
});
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
inheritAttrs: false,
|
|
131
|
-
setup: (_props, ctx) => () => h(asyncComp, ctx.attrs, ctx.slots)
|
|
132
|
-
});
|
|
128
|
+
asyncComp.name = name;
|
|
129
|
+
comp = asyncComp;
|
|
133
130
|
compCache.set(spec, comp);
|
|
134
131
|
}
|
|
135
132
|
return comp;
|
package/dist/cli.js
CHANGED
|
@@ -387,14 +387,27 @@ function resolveSpec(spec, from) {
|
|
|
387
387
|
return void 0;
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
+
function esbuildSupportsConfigSyntax(esb) {
|
|
391
|
+
try {
|
|
392
|
+
esb.transformSync(TS_SYNTAX_PROBE, { loader: "ts" });
|
|
393
|
+
return true;
|
|
394
|
+
} catch {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
390
398
|
function resolveEsbuild(configPath) {
|
|
391
399
|
const esbuildOf = (base) => {
|
|
400
|
+
const candidates = [];
|
|
392
401
|
const direct = resolveSpec("esbuild", base);
|
|
393
|
-
if (direct)
|
|
402
|
+
if (direct) candidates.push(direct);
|
|
394
403
|
const viteEntry = resolveSpec("vite", base);
|
|
395
404
|
if (viteEntry) {
|
|
396
405
|
const viaVite = resolveSpec("esbuild", viteEntry);
|
|
397
|
-
if (viaVite)
|
|
406
|
+
if (viaVite) candidates.push(viaVite);
|
|
407
|
+
}
|
|
408
|
+
for (const c of candidates) {
|
|
409
|
+
const esb = createRequire(c)("esbuild");
|
|
410
|
+
if (esbuildSupportsConfigSyntax(esb)) return esb;
|
|
398
411
|
}
|
|
399
412
|
return void 0;
|
|
400
413
|
};
|
|
@@ -403,9 +416,9 @@ function resolveEsbuild(configPath) {
|
|
|
403
416
|
if (got) return got;
|
|
404
417
|
}
|
|
405
418
|
appConfigError(
|
|
406
|
-
"\u65E0\u6CD5\u52A0\u8F7D esbuild\uFF08\u5355\u9879\u76EE\u914D\u7F6E\u52A0\u8F7D\u9700\u8981\u5B83\u8F6C\u8BD1 TS \u4E0E\u76F8\u5BF9\u5BFC\u5165\uFF09",
|
|
407
|
-
"\u914D\u7F6E\u5DE5\u7A0B\uFF08\u542B\u5176 vite \u4F9D\u8D56\u6811\uFF09\u4E0E CLI \u4F9D\u8D56\u6811\u4E2D\u90FD\u89E3\u6790\u4E0D\u5230 esbuild",
|
|
408
|
-
"\
|
|
419
|
+
"\u65E0\u6CD5\u52A0\u8F7D\u80FD\u89E3\u6790\u914D\u7F6E\u6A21\u677F\u8BED\u6CD5\u7684 esbuild\uFF08\u5355\u9879\u76EE\u914D\u7F6E\u52A0\u8F7D\u9700\u8981\u5B83\u8F6C\u8BD1 TS \u4E0E\u76F8\u5BF9\u5BFC\u5165\uFF09",
|
|
420
|
+
"\u914D\u7F6E\u5DE5\u7A0B\uFF08\u542B\u5176 vite \u4F9D\u8D56\u6811\uFF09\u4E0E CLI \u4F9D\u8D56\u6811\u4E2D\u90FD\u89E3\u6790\u4E0D\u5230\u6EE1\u8DB3\u8981\u6C42\u7684 esbuild\uFF08\u9700 \u22650.14.49\uFF0C\u652F\u6301 satisfies\uFF09",
|
|
421
|
+
"\u672C\u5305\u5DF2\u81EA\u5E26 esbuild \u4F9D\u8D56\u2014\u2014\u51FA\u73B0\u6B64\u9519\u8BEF\u901A\u5E38\u662F\u5B89\u88C5\u4E0D\u5B8C\u6574\uFF0C\u91CD\u88C5 @fulgurjs/federation\uFF1B\u6216\u9879\u76EE\u5185 npm i -D esbuild \u540E\u91CD\u8BD5"
|
|
409
422
|
);
|
|
410
423
|
}
|
|
411
424
|
async function loadAppConfig(configPath) {
|
|
@@ -435,7 +448,7 @@ async function loadAppConfig(configPath) {
|
|
|
435
448
|
build.onResolve({ filter: /^@fulgurjs\/federation(\/|$)/ }, (args) => {
|
|
436
449
|
const resolved = resolveSelfEntry(abs, args.path);
|
|
437
450
|
if (!resolved) {
|
|
438
|
-
return { errors: [{ text:
|
|
451
|
+
return { errors: [{ text: `\u65E0\u6CD5\u4ECE\u914D\u7F6E\u9879\u76EE\u6216 CLI \u81EA\u8EAB\u89E3\u6790 "${args.path}"\uFF1B\u8BF7\u5148\u5728\u5F53\u524D\u9879\u76EE\u5B89\u88C5 @fulgurjs/federation` }] };
|
|
439
452
|
}
|
|
440
453
|
return { path: resolved };
|
|
441
454
|
});
|
|
@@ -494,10 +507,12 @@ function roleOfOptions(options) {
|
|
|
494
507
|
if (hasRemotes && hasProvides) return "dual";
|
|
495
508
|
return hasRemotes ? "host" : "remote";
|
|
496
509
|
}
|
|
510
|
+
var TS_SYNTAX_PROBE;
|
|
497
511
|
var init_app_config = __esm({
|
|
498
512
|
"src/app-config.ts"() {
|
|
499
513
|
"use strict";
|
|
500
514
|
init_config();
|
|
515
|
+
TS_SYNTAX_PROBE = "export default {} satisfies Record<string, unknown>";
|
|
501
516
|
}
|
|
502
517
|
});
|
|
503
518
|
|
|
@@ -863,7 +878,9 @@ __export(commands_exports, {
|
|
|
863
878
|
checkPages: () => checkPages,
|
|
864
879
|
explainApp: () => explainApp,
|
|
865
880
|
formatCheckPages: () => formatCheckPages,
|
|
866
|
-
formatExplain: () => formatExplain
|
|
881
|
+
formatExplain: () => formatExplain,
|
|
882
|
+
manifestUrlForRemoteAddress: () => manifestUrlForRemoteAddress,
|
|
883
|
+
stripRemoteNamePrefix: () => stripRemoteNamePrefix
|
|
867
884
|
});
|
|
868
885
|
import fs2 from "node:fs";
|
|
869
886
|
import path2 from "node:path";
|
|
@@ -1054,23 +1071,50 @@ function manifestFromFile(p) {
|
|
|
1054
1071
|
}
|
|
1055
1072
|
return void 0;
|
|
1056
1073
|
}
|
|
1057
|
-
async function
|
|
1074
|
+
async function manifestFromUrlOnce(url) {
|
|
1058
1075
|
try {
|
|
1059
1076
|
const res = await fetch(url, { signal: AbortSignal.timeout(5e3) });
|
|
1060
1077
|
if (res.ok) {
|
|
1061
1078
|
const parsed = parseManifest(await res.json());
|
|
1062
|
-
if (parsed.manifest && !parsed.unsupportedVersion) return parsed.manifest;
|
|
1079
|
+
if (parsed.manifest && !parsed.unsupportedVersion) return { manifest: parsed.manifest, url };
|
|
1063
1080
|
}
|
|
1064
1081
|
} catch {
|
|
1065
1082
|
}
|
|
1066
1083
|
return void 0;
|
|
1067
1084
|
}
|
|
1085
|
+
async function manifestFromUrl(url) {
|
|
1086
|
+
const got = await manifestFromUrlOnce(url);
|
|
1087
|
+
if (got) return got;
|
|
1088
|
+
if (/^http:\/\/localhost(?=[:/])/.test(url)) {
|
|
1089
|
+
return manifestFromUrlOnce(url.replace(/^http:\/\/localhost(?=[:/])/, "http://127.0.0.1"));
|
|
1090
|
+
}
|
|
1091
|
+
return void 0;
|
|
1092
|
+
}
|
|
1093
|
+
function stripRemoteNamePrefix(addr) {
|
|
1094
|
+
return addr.replace(/^[A-Za-z0-9_.-]+@/, "");
|
|
1095
|
+
}
|
|
1096
|
+
function manifestUrlForRemoteAddress(addr) {
|
|
1097
|
+
const stripped = stripRemoteNamePrefix(addr);
|
|
1098
|
+
const clean = stripped.replace(/\/+$/, "");
|
|
1099
|
+
if (/fulgurjs-manifest\.json$/.test(clean)) return clean;
|
|
1100
|
+
if (/fulgurjs-remoteEntry\.js$/.test(clean)) return clean.replace(/fulgurjs-remoteEntry\.js$/, "fulgurjs-manifest.json");
|
|
1101
|
+
return `${clean}/fulgurjs-manifest.json`;
|
|
1102
|
+
}
|
|
1068
1103
|
async function fetchRemoteManifestRepo(cfg, app, opts) {
|
|
1069
1104
|
const explicit = opts.manifests?.[app.name] ?? opts.manifests?.[app.path];
|
|
1070
1105
|
if (explicit) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1106
|
+
if (/^https?:\/\//.test(explicit)) {
|
|
1107
|
+
const got2 = await manifestFromUrl(explicit);
|
|
1108
|
+
return got2 ? { manifest: got2.manifest, from: explicit } : void 0;
|
|
1109
|
+
}
|
|
1110
|
+
const got = manifestFromFile(explicit);
|
|
1111
|
+
return got ? { manifest: got, from: explicit } : void 0;
|
|
1112
|
+
}
|
|
1113
|
+
if (opts.site) {
|
|
1114
|
+
const base = app.base === "/" ? "" : app.base.replace(/\/$/, "");
|
|
1115
|
+
const url = `${opts.site.replace(/\/$/, "")}${base}/fulgurjs-manifest.json`;
|
|
1116
|
+
const got = await manifestFromUrl(url);
|
|
1117
|
+
if (got) return { manifest: got.manifest, from: got.url };
|
|
1074
1118
|
return void 0;
|
|
1075
1119
|
}
|
|
1076
1120
|
const candidates = [app.deployDir || app.base.replace(/^\/|\/$/g, ""), "dist"];
|
|
@@ -1079,37 +1123,35 @@ async function fetchRemoteManifestRepo(cfg, app, opts) {
|
|
|
1079
1123
|
const got = manifestFromFile(p);
|
|
1080
1124
|
if (got) return { manifest: got, from: p };
|
|
1081
1125
|
}
|
|
1082
|
-
if (opts.site) {
|
|
1083
|
-
const base = app.base === "/" ? "" : app.base.replace(/\/$/, "");
|
|
1084
|
-
const url = `${opts.site.replace(/\/$/, "")}${base}/fulgurjs-manifest.json`;
|
|
1085
|
-
const got = await manifestFromUrl(url);
|
|
1086
|
-
if (got) return { manifest: got, from: url };
|
|
1087
|
-
}
|
|
1088
1126
|
return void 0;
|
|
1089
1127
|
}
|
|
1090
1128
|
async function fetchRemoteManifestApp(loaded, options, remoteName, opts) {
|
|
1091
1129
|
const explicit = opts.manifests?.[remoteName];
|
|
1092
1130
|
if (explicit) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1131
|
+
if (/^https?:\/\//.test(explicit)) {
|
|
1132
|
+
const got2 = await manifestFromUrl(explicit);
|
|
1133
|
+
return got2 ? { manifest: got2.manifest, from: explicit } : void 0;
|
|
1134
|
+
}
|
|
1135
|
+
const got = manifestFromFile(explicit);
|
|
1136
|
+
return got ? { manifest: got, from: explicit } : void 0;
|
|
1097
1137
|
}
|
|
1098
1138
|
const remoteCfg = (options.remotes ?? {})[remoteName];
|
|
1099
1139
|
if (!remoteCfg) return void 0;
|
|
1100
1140
|
const cfg = typeof remoteCfg === "string" ? { external: remoteCfg } : remoteCfg;
|
|
1101
|
-
const
|
|
1102
|
-
if (!
|
|
1141
|
+
const prodRaw = cfg.prod ?? cfg.external ?? "";
|
|
1142
|
+
if (!prodRaw) return void 0;
|
|
1143
|
+
const prodBase = stripRemoteNamePrefix(prodRaw);
|
|
1103
1144
|
if (/^https?:\/\//.test(prodBase)) {
|
|
1104
|
-
const url =
|
|
1145
|
+
const url = manifestUrlForRemoteAddress(prodBase);
|
|
1105
1146
|
const got = await manifestFromUrl(url);
|
|
1106
|
-
if (got) return { manifest: got, from: url };
|
|
1147
|
+
if (got) return { manifest: got.manifest, from: got.url };
|
|
1107
1148
|
return void 0;
|
|
1108
1149
|
}
|
|
1109
1150
|
if (opts.site) {
|
|
1110
|
-
const url = `${opts.site.replace(/\/$/, "")}${prodBase.startsWith("/") ? prodBase : `/${prodBase}`}
|
|
1151
|
+
const url = manifestUrlForRemoteAddress(`${opts.site.replace(/\/$/, "")}${prodBase.startsWith("/") ? prodBase : `/${prodBase}`}`);
|
|
1111
1152
|
const got = await manifestFromUrl(url);
|
|
1112
|
-
if (got) return { manifest: got, from: url };
|
|
1153
|
+
if (got) return { manifest: got.manifest, from: got.url };
|
|
1154
|
+
return void 0;
|
|
1113
1155
|
}
|
|
1114
1156
|
return void 0;
|
|
1115
1157
|
}
|
|
@@ -1208,10 +1250,11 @@ async function checkPagesRepo(cfg, appPathOrName, opts) {
|
|
|
1208
1250
|
}
|
|
1209
1251
|
const got = await fetchRemoteManifestRepo(cfg, remoteApp, opts);
|
|
1210
1252
|
if (!got) {
|
|
1253
|
+
const how = opts.manifests?.[name] ?? opts.manifests?.[remoteApp.path] ? `--manifest \u6307\u5B9A\u6765\u6E90\u4E0D\u53EF\u8FBE\u6216\u975E\u6709\u6548 manifest` : opts.site ? `--site ${opts.site} \u6309 base \u63A8\u5BFC\u7684 manifest URL \u4E0D\u53EF\u8FBE\uFF08\u663E\u5F0F\u6307\u5B9A\u6765\u6E90\u5931\u8D25\u65F6\u4E0D\u56DE\u9000\u672C\u5730 dist\uFF09` : "\u672C\u5730 dist \u672A\u547D\u4E2D\u4E14\u672A\u6307\u5B9A --site/--manifest";
|
|
1211
1254
|
issues.push({
|
|
1212
1255
|
level: "unverified",
|
|
1213
|
-
message: `\u8FDC\u7A0B "${name}" \u7684 manifest \u4E0D\u53EF\u5F97\uFF08
|
|
1214
|
-
\u4FEE\u6CD5: \u5148\u6784\u5EFA\u8BE5\u8FDC\u7A0B\uFF08\u4EA7\u7269\u542B fulgurjs-manifest.json\uFF09\uFF0C\u6216\u7528 --site <URL> \u6307\u5411\u5DF2\u90E8\u7F72\u7AD9\u70B9
|
|
1256
|
+
message: `\u8FDC\u7A0B "${name}" \u7684 manifest \u4E0D\u53EF\u5F97\uFF08${how}\uFF09\u2014\u2014\u8BE5\u8FDC\u7A0B\u7684 spec \u5B58\u5728\u6027\u65E0\u6CD5\u6838\u5BF9\u3002
|
|
1257
|
+
\u4FEE\u6CD5: \u5148\u6784\u5EFA\u8BE5\u8FDC\u7A0B\uFF08\u4EA7\u7269\u542B fulgurjs-manifest.json\uFF09\uFF0C\u6216\u7528 --site <URL> \u6307\u5411\u5DF2\u90E8\u7F72\u7AD9\u70B9\uFF0C\u6216 --manifest ${name}=<\u8DEF\u5F84|URL>`
|
|
1215
1258
|
});
|
|
1216
1259
|
continue;
|
|
1217
1260
|
}
|
|
@@ -1262,7 +1305,7 @@ function formatCheckPages(r) {
|
|
|
1262
1305
|
const warns = r.issues.filter((i) => i.level === "warn");
|
|
1263
1306
|
L.push(`[fulgurjs:check-pages] \u5E94\u7528 ${r.app}\uFF1A\u6838\u5BF9 ${r.checked} \u6761\u9875\u9762\uFF0Cerror ${errors.length} / warn ${warns.length} / \u65E0\u6CD5\u9A8C\u8BC1 ${unverified.length}`);
|
|
1264
1307
|
if (r.manifestSources?.length) {
|
|
1265
|
-
L.push("manifest \u6765\u6E90\uFF08\u4F18\u5148\u7EA7\uFF1A--manifest > --site/prod \u63A8\u5BFC
|
|
1308
|
+
L.push("manifest \u6765\u6E90\uFF08\u4F18\u5148\u7EA7\uFF1A--manifest > --site/prod \u63A8\u5BFC\uFF1B\u672C\u5730 dist \u4EC5\u5728\u672A\u6307\u5B9A\u4EFB\u4F55\u7EBF\u4E0A\u6765\u6E90\u65F6\u515C\u5E95\uFF1B\u4EE5\u5B9E\u9645\u547D\u4E2D\u7684\u6765\u6E90\u4E3A\u51C6\uFF09\uFF1A");
|
|
1266
1309
|
for (const s of r.manifestSources) L.push(` ${s.remote} \u2190 ${s.from}`);
|
|
1267
1310
|
}
|
|
1268
1311
|
for (const i of [...errors, ...warns, ...unverified]) L.push(`
|
|
@@ -1611,8 +1654,10 @@ var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
|
|
|
1611
1654
|
fulgurjs check-pages [--config <path>] [--app <name>] [--site <URL>]
|
|
1612
1655
|
[--manifest <remote>=<\u8DEF\u5F84|URL>]... [--require-verified] [--json]
|
|
1613
1656
|
\u6838\u5BF9\u5BBF\u4E3B\u9875\u9762\u8868\u4E0E\u8FDC\u7A0B exposes\uFF08\u5BBF\u4E3B\u9879\u76EE\u8FD0\u884C\uFF1B
|
|
1614
|
-
manifest \u6765\u6E90\u4F18\u5148\u7EA7 --manifest > --site/prod \u63A8\u5BFC\
|
|
1615
|
-
\
|
|
1657
|
+
manifest \u6765\u6E90\u4F18\u5148\u7EA7 --manifest > --site/prod \u63A8\u5BFC\uFF0C
|
|
1658
|
+
\u663E\u5F0F\u6307\u5B9A\u6765\u6E90\u5931\u8D25\u4E0D\u56DE\u9000\u672C\u5730 dist\uFF1B\u672C\u5730 dist \u4EC5\u5728
|
|
1659
|
+
\u672A\u6307\u5B9A\u4EFB\u4F55\u7EBF\u4E0A\u6765\u6E90\u65F6\u515C\u5E95\uFF1B\u786E\u5B9A\u6027\u9519\u8BEF\u975E\u96F6\u9000\u51FA\uFF1B
|
|
1660
|
+
--require-verified \u65F6\u65E0\u6CD5\u9A8C\u8BC1\u4E5F\u975E\u96F6\uFF09
|
|
1616
1661
|
fulgurjs doctor --base <URL> --apps <a,b,c> [--dev] [--json] [--chunk-sample N]
|
|
1617
1662
|
fulgurjs --help
|
|
1618
1663
|
|
package/dist/context.cjs
CHANGED
|
@@ -53,7 +53,7 @@ function requireRuntime() {
|
|
|
53
53
|
if (!rt || typeof rt.loadRemote !== "function") {
|
|
54
54
|
throw new FgError(
|
|
55
55
|
ContextErrorCodes.CONTEXT_NO_RUNTIME,
|
|
56
|
-
"fulgurjs
|
|
56
|
+
"\u73B0\u8C61\uFF1A\u5F53\u524D\u9875\u9762\u627E\u4E0D\u5230 fulgurjs \u8FD0\u884C\u65F6\u5355\u4F8B\uFF08globalThis.__FULGURJS_RUNTIME__ \u672A\u5B9A\u4E49\uFF09\u3002\n \u6839\u56E0: \u5F53\u524D\u9875\u9762\u6CA1\u6709\u7ECF\u5BBF\u4E3B\u7684\u8054\u90A6\u8FD0\u884C\u65F6\u52A0\u8F7D\uFF08\u72EC\u7ACB\u76F4\u5F00\u8FDC\u7A0B\u9875\uFF0C\u6216\u5BBF\u4E3B\u6865\u665A\u4E8E\u672C\u8C03\u7528\u6267\u884C\uFF09\u3002\n \u4FEE\u6CD5: \u2460 \u4ECE\u5BBF\u4E3B\u5E94\u7528\u7684\u8054\u90A6\u8DEF\u7531\u6253\u5F00\u672C\u9875\u9762\uFF08\u5BBF\u4E3B\u6865\u4F1A\u5148\u52A0\u8F7D\u8FD0\u884C\u65F6\u5E76\u63D0\u4F9B context\uFF09\uFF1B\n \u2461 \u82E5\u4F60\u662F\u5BBF\u4E3B\u6865\u4F5C\u8005\uFF1A\u628A provideAppContext \u653E\u5728\u6865\u521D\u59CB\u5316\u5C3E\u90E8\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 \u8FDC\u7A0B setup \u2192 \u9875\u9762\u6A21\u5757\uFF09\u3002",
|
|
57
57
|
{ runtime: false }
|
|
58
58
|
);
|
|
59
59
|
}
|
|
@@ -83,10 +83,10 @@ function requireAppContext(...keys) {
|
|
|
83
83
|
const got = Object.keys(ctx);
|
|
84
84
|
const err = new FgError(
|
|
85
85
|
ContextErrorCodes.CONTEXT_MISSING_KEY,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
`\u73B0\u8C61\uFF1AAppContext \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5 ${missing.map((k) => `"${k}"`).join("\u3001")}\u3002
|
|
87
|
+
\u5F53\u524D\u5B57\u6BB5\uFF1A${got.length ? got.map((k) => `"${k}"`).join("\u3001") : "\u7A7A\uFF08\u5BBF\u4E3B\u6865\u53EF\u80FD\u5C1A\u672A\u8C03\u7528 provideAppContext\uFF09"}\u3002
|
|
88
|
+
\u9884\u671F\uFF1A\u5BBF\u4E3B\u6865\u5E94\u5728\u8FDC\u7A0B\u9875\u9762\u52A0\u8F7D\u524D\u63D0\u4F9B ${missing.map((k) => `"${k}"`).join("\u3001")}\u3002
|
|
89
|
+
\u793A\u4F8B\uFF1Ahost/src/fulgurjs/host/bridge.ts \u2192 provideAppContext({ ${keys.join(", ")}, ... })
|
|
90
90
|
\u4FEE\u6CD5: \u68C0\u67E5\u5BBF\u4E3B\u5E94\u7528\u7684 fulgurjs \u6865\u662F\u5426\u5728 loadRemote \u9875\u9762\u524D\u5B8C\u6210 context provide\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 \u8FDC\u7A0B setup \u2192 \u9875\u9762\u6A21\u5757\uFF09`,
|
|
91
91
|
{ missing, got }
|
|
92
92
|
);
|
package/dist/context.js
CHANGED
|
@@ -15,7 +15,7 @@ function requireRuntime() {
|
|
|
15
15
|
if (!rt || typeof rt.loadRemote !== "function") {
|
|
16
16
|
throw new FgError(
|
|
17
17
|
ContextErrorCodes.CONTEXT_NO_RUNTIME,
|
|
18
|
-
"fulgurjs
|
|
18
|
+
"\u73B0\u8C61\uFF1A\u5F53\u524D\u9875\u9762\u627E\u4E0D\u5230 fulgurjs \u8FD0\u884C\u65F6\u5355\u4F8B\uFF08globalThis.__FULGURJS_RUNTIME__ \u672A\u5B9A\u4E49\uFF09\u3002\n \u6839\u56E0: \u5F53\u524D\u9875\u9762\u6CA1\u6709\u7ECF\u5BBF\u4E3B\u7684\u8054\u90A6\u8FD0\u884C\u65F6\u52A0\u8F7D\uFF08\u72EC\u7ACB\u76F4\u5F00\u8FDC\u7A0B\u9875\uFF0C\u6216\u5BBF\u4E3B\u6865\u665A\u4E8E\u672C\u8C03\u7528\u6267\u884C\uFF09\u3002\n \u4FEE\u6CD5: \u2460 \u4ECE\u5BBF\u4E3B\u5E94\u7528\u7684\u8054\u90A6\u8DEF\u7531\u6253\u5F00\u672C\u9875\u9762\uFF08\u5BBF\u4E3B\u6865\u4F1A\u5148\u52A0\u8F7D\u8FD0\u884C\u65F6\u5E76\u63D0\u4F9B context\uFF09\uFF1B\n \u2461 \u82E5\u4F60\u662F\u5BBF\u4E3B\u6865\u4F5C\u8005\uFF1A\u628A provideAppContext \u653E\u5728\u6865\u521D\u59CB\u5316\u5C3E\u90E8\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 \u8FDC\u7A0B setup \u2192 \u9875\u9762\u6A21\u5757\uFF09\u3002",
|
|
19
19
|
{ runtime: false }
|
|
20
20
|
);
|
|
21
21
|
}
|
|
@@ -45,10 +45,10 @@ function requireAppContext(...keys) {
|
|
|
45
45
|
const got = Object.keys(ctx);
|
|
46
46
|
const err = new FgError(
|
|
47
47
|
ContextErrorCodes.CONTEXT_MISSING_KEY,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
`\u73B0\u8C61\uFF1AAppContext \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5 ${missing.map((k) => `"${k}"`).join("\u3001")}\u3002
|
|
49
|
+
\u5F53\u524D\u5B57\u6BB5\uFF1A${got.length ? got.map((k) => `"${k}"`).join("\u3001") : "\u7A7A\uFF08\u5BBF\u4E3B\u6865\u53EF\u80FD\u5C1A\u672A\u8C03\u7528 provideAppContext\uFF09"}\u3002
|
|
50
|
+
\u9884\u671F\uFF1A\u5BBF\u4E3B\u6865\u5E94\u5728\u8FDC\u7A0B\u9875\u9762\u52A0\u8F7D\u524D\u63D0\u4F9B ${missing.map((k) => `"${k}"`).join("\u3001")}\u3002
|
|
51
|
+
\u793A\u4F8B\uFF1Ahost/src/fulgurjs/host/bridge.ts \u2192 provideAppContext({ ${keys.join(", ")}, ... })
|
|
52
52
|
\u4FEE\u6CD5: \u68C0\u67E5\u5BBF\u4E3B\u5E94\u7528\u7684 fulgurjs \u6865\u662F\u5426\u5728 loadRemote \u9875\u9762\u524D\u5B8C\u6210 context provide\uFF08\u65F6\u5E8F\u5951\u7EA6 bridge \u2192 \u8FDC\u7A0B setup \u2192 \u9875\u9762\u6A21\u5757\uFF09`,
|
|
53
53
|
{ missing, got }
|
|
54
54
|
);
|