@fulgurjs/federation 5.8.0 → 5.9.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 (216) hide show
  1. package/CHANGELOG.md +14 -4
  2. package/README.en.md +60 -24
  3. package/README.md +60 -24
  4. package/dist/cli.js +327 -29
  5. package/dist/index.cjs +2 -2
  6. package/dist/index.js +2 -2
  7. package/dist/runtime.js +1 -1
  8. package/docs/API.en.md +14 -3
  9. package/docs/API.md +7 -6
  10. package/docs/webpack-mf-/345/257/271/347/205/247/344/270/216/347/274/272/345/217/243.md +2 -2
  11. package/examples/README.md +3 -67
  12. package/examples/templates/README.md +88 -0
  13. package/examples/templates/react-host-vue-remote/README.md +18 -0
  14. package/examples/templates/react-host-vue-remote/package.json +11 -0
  15. package/examples/templates/react-host-vue-remote/pnpm-lock.yaml +1627 -0
  16. package/examples/templates/react-host-vue-remote/pnpm-workspace.yaml +10 -0
  17. package/examples/{bridge → templates/react-host-vue-remote}/react-host/README.md +8 -7
  18. package/examples/{bridge → templates/react-host-vue-remote}/react-host/package.json +1 -1
  19. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d/_paths.d.ts +4 -0
  20. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d/bridge.ts +3 -0
  21. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote.d.ts +9 -0
  22. package/examples/templates/react-host-vue-remote/scripts/dev.config.json +6 -0
  23. package/examples/templates/react-host-vue-remote/scripts/dev.mjs +173 -0
  24. package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/README.md +10 -5
  25. package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/package.json +1 -1
  26. package/examples/{react → templates/react-react}/README.md +9 -13
  27. package/examples/{react → templates/react-react}/host/README.md +6 -8
  28. package/examples/{react → templates/react-react}/host/package.json +1 -1
  29. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/ClickButton.ts +3 -0
  30. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/_paths.d.ts +4 -0
  31. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/pages/DetailPage.ts +3 -0
  32. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/pages/HomePage.ts +3 -0
  33. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d/utils.ts +2 -0
  34. package/examples/templates/react-react/host/src/fulgurjs/types/react-remote.d.ts +26 -0
  35. package/examples/templates/react-react/package.json +11 -0
  36. package/examples/templates/react-react/pnpm-lock.yaml +1537 -0
  37. package/examples/templates/react-react/pnpm-workspace.yaml +10 -0
  38. package/examples/{react → templates/react-react}/remote/README.md +7 -6
  39. package/examples/{react → templates/react-react}/remote/package.json +1 -1
  40. package/examples/templates/react-react/scripts/dev.config.json +6 -0
  41. package/examples/templates/react-react/scripts/dev.mjs +173 -0
  42. package/examples/templates/showcase/README.md +109 -0
  43. package/examples/templates/showcase/package.json +13 -0
  44. package/examples/templates/showcase/pnpm-lock.yaml +1858 -0
  45. package/examples/templates/showcase/pnpm-workspace.yaml +12 -0
  46. package/examples/templates/showcase/react-host/fulgurjs.config.ts +21 -0
  47. package/examples/templates/showcase/react-host/index.html +13 -0
  48. package/examples/templates/showcase/react-host/package.json +26 -0
  49. package/examples/templates/showcase/react-host/src/GuardBanner.tsx +33 -0
  50. package/examples/templates/showcase/react-host/src/Layout.tsx +42 -0
  51. package/examples/templates/showcase/react-host/src/ObsPanel.tsx +44 -0
  52. package/examples/templates/showcase/react-host/src/demo-log.ts +74 -0
  53. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d/_paths.d.ts +4 -0
  54. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d/bridge.ts +3 -0
  55. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote.d.ts +7 -0
  56. package/examples/templates/showcase/react-host/src/main.tsx +33 -0
  57. package/examples/templates/showcase/react-host/src/pages/AboutPage.tsx +18 -0
  58. package/examples/templates/showcase/react-host/src/pages/BridgeVuePage.tsx +77 -0
  59. package/examples/templates/showcase/react-host/src/pages/HomePage.tsx +14 -0
  60. package/examples/templates/showcase/react-host/src/routing.ts +30 -0
  61. package/examples/templates/showcase/react-host/tsconfig.json +15 -0
  62. package/examples/templates/showcase/react-host/vite.config.ts +8 -0
  63. package/examples/templates/showcase/react-remote/fulgurjs.config.ts +18 -0
  64. package/examples/templates/showcase/react-remote/index.html +13 -0
  65. package/examples/templates/showcase/react-remote/package.json +25 -0
  66. package/examples/templates/showcase/react-remote/src/ChildLayout.tsx +48 -0
  67. package/examples/templates/showcase/react-remote/src/bridge.tsx +62 -0
  68. package/examples/templates/showcase/react-remote/src/child-bus.ts +32 -0
  69. package/examples/templates/showcase/react-remote/src/main.tsx +18 -0
  70. package/examples/templates/showcase/react-remote/src/pages/Locked.tsx +23 -0
  71. package/examples/templates/showcase/react-remote/src/pages/OrderDetail.tsx +36 -0
  72. package/examples/templates/showcase/react-remote/src/pages/OrderList.tsx +110 -0
  73. package/examples/templates/showcase/react-remote/src/pages/Settings.tsx +50 -0
  74. package/examples/templates/showcase/react-remote/src/settings-store.ts +11 -0
  75. package/examples/templates/showcase/react-remote/tsconfig.json +14 -0
  76. package/examples/templates/showcase/react-remote/vite.config.ts +14 -0
  77. package/examples/templates/showcase/scripts/dev.config.json +8 -0
  78. package/examples/templates/showcase/scripts/dev.mjs +173 -0
  79. package/examples/templates/showcase/vue-host/fulgurjs.config.ts +21 -0
  80. package/examples/templates/showcase/vue-host/index.html +13 -0
  81. package/examples/templates/showcase/vue-host/package.json +25 -0
  82. package/examples/templates/showcase/vue-host/src/App.vue +50 -0
  83. package/examples/templates/showcase/vue-host/src/GuardBanner.vue +24 -0
  84. package/examples/templates/showcase/vue-host/src/ObsPanel.vue +60 -0
  85. package/examples/templates/showcase/vue-host/src/demo-log.ts +49 -0
  86. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d/_paths.d.ts +4 -0
  87. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d/bridge.ts +3 -0
  88. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote.d.ts +7 -0
  89. package/examples/templates/showcase/vue-host/src/guard.ts +47 -0
  90. package/examples/templates/showcase/vue-host/src/main.ts +30 -0
  91. package/examples/templates/showcase/vue-host/src/pages/AboutPage.vue +17 -0
  92. package/examples/templates/showcase/vue-host/src/pages/BridgeReactPage.vue +74 -0
  93. package/examples/templates/showcase/vue-host/src/pages/HomePage.vue +13 -0
  94. package/examples/templates/showcase/vue-host/src/routing.ts +31 -0
  95. package/examples/templates/showcase/vue-host/tsconfig.json +14 -0
  96. package/examples/templates/showcase/vue-remote/fulgurjs.config.ts +17 -0
  97. package/examples/templates/showcase/vue-remote/index.html +13 -0
  98. package/examples/templates/showcase/vue-remote/package.json +23 -0
  99. package/examples/templates/showcase/vue-remote/src/ChildLayout.vue +54 -0
  100. package/examples/templates/showcase/vue-remote/src/bridge.ts +48 -0
  101. package/examples/templates/showcase/vue-remote/src/child-bus.ts +32 -0
  102. package/examples/templates/showcase/vue-remote/src/main.ts +16 -0
  103. package/examples/templates/showcase/vue-remote/src/pages/Locked.vue +28 -0
  104. package/examples/templates/showcase/vue-remote/src/pages/OrderDetail.vue +46 -0
  105. package/examples/templates/showcase/vue-remote/src/pages/OrderList.vue +116 -0
  106. package/examples/templates/showcase/vue-remote/src/pages/Settings.vue +34 -0
  107. package/examples/templates/showcase/vue-remote/src/settings-store.ts +13 -0
  108. package/examples/templates/showcase/vue-remote/tsconfig.json +14 -0
  109. package/examples/templates/showcase/vue-remote/vite.config.ts +14 -0
  110. package/examples/templates/vue-host-react-remote/README.md +18 -0
  111. package/examples/templates/vue-host-react-remote/package.json +11 -0
  112. package/examples/templates/vue-host-react-remote/pnpm-lock.yaml +1663 -0
  113. package/examples/templates/vue-host-react-remote/pnpm-workspace.yaml +10 -0
  114. package/examples/{bridge → templates/vue-host-react-remote}/react-remote/README.md +9 -4
  115. package/examples/{bridge → templates/vue-host-react-remote}/react-remote/package.json +1 -1
  116. package/examples/templates/vue-host-react-remote/scripts/dev.config.json +6 -0
  117. package/examples/templates/vue-host-react-remote/scripts/dev.mjs +173 -0
  118. package/examples/{bridge → templates/vue-host-react-remote}/vue-host/README.md +8 -7
  119. package/examples/{bridge → templates/vue-host-react-remote}/vue-host/package.json +1 -1
  120. package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/App.vue +1 -1
  121. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d/_paths.d.ts +4 -0
  122. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d/bridge.ts +3 -0
  123. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote.d.ts +9 -0
  124. package/examples/{vue → templates/vue-vue}/README.md +9 -13
  125. package/examples/{vue → templates/vue-vue}/host/README.md +6 -8
  126. package/examples/{vue → templates/vue-vue}/host/package.json +1 -1
  127. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/ClickButton.ts +4 -0
  128. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/_paths.d.ts +4 -0
  129. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/pages/DetailPage.ts +4 -0
  130. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/pages/HomePage.ts +4 -0
  131. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d/utils.ts +2 -0
  132. package/examples/templates/vue-vue/host/src/fulgurjs/types/vue-remote.d.ts +29 -0
  133. package/examples/templates/vue-vue/host/vite.config.ts +8 -0
  134. package/examples/templates/vue-vue/package.json +11 -0
  135. package/examples/templates/vue-vue/pnpm-lock.yaml +1199 -0
  136. package/examples/templates/vue-vue/pnpm-workspace.yaml +10 -0
  137. package/examples/{vue → templates/vue-vue}/remote/README.md +7 -6
  138. package/examples/{vue → templates/vue-vue}/remote/package.json +1 -1
  139. package/examples/{vue → templates/vue-vue}/remote/src/App.vue +1 -1
  140. package/examples/templates/vue-vue/scripts/dev.config.json +6 -0
  141. package/examples/templates/vue-vue/scripts/dev.mjs +173 -0
  142. package/package.json +4 -4
  143. package/examples/README.en.md +0 -67
  144. package/examples/bridge/README.md +0 -36
  145. package/examples/bridge/react-host/package-lock.json +0 -2466
  146. package/examples/bridge/react-remote/package-lock.json +0 -2391
  147. package/examples/bridge/vue-host/package-lock.json +0 -1894
  148. package/examples/bridge/vue-remote/package-lock.json +0 -1865
  149. package/examples/react/host/package-lock.json +0 -2391
  150. package/examples/react/remote/package-lock.json +0 -2333
  151. package/examples/vue/host/package-lock.json +0 -1865
  152. package/examples/vue/remote/package-lock.json +0 -1843
  153. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/fulgurjs.config.ts +0 -0
  154. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/index.html +0 -0
  155. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/env.d.ts +0 -0
  156. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/host-session.ts +0 -0
  157. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/src/main.tsx +0 -0
  158. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/tsconfig.json +0 -0
  159. /package/examples/{bridge → templates/react-host-vue-remote}/react-host/vite.config.ts +0 -0
  160. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/fulgurjs.config.ts +0 -0
  161. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/index.html +0 -0
  162. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/App.vue +0 -0
  163. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/bridge.ts +0 -0
  164. /package/examples/{bridge/react-remote → templates/react-host-vue-remote/vue-remote}/src/env.d.ts +0 -0
  165. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/src/main.ts +0 -0
  166. /package/examples/{bridge/vue-host → templates/react-host-vue-remote/vue-remote}/tsconfig.json +0 -0
  167. /package/examples/{bridge → templates/react-host-vue-remote}/vue-remote/vite.config.ts +0 -0
  168. /package/examples/{react → templates/react-react}/host/fulgurjs.config.ts +0 -0
  169. /package/examples/{react → templates/react-react}/host/index.html +0 -0
  170. /package/examples/{react → templates/react-react}/host/src/App.tsx +0 -0
  171. /package/examples/{react → templates/react-react}/host/src/main.tsx +0 -0
  172. /package/examples/{react → templates/react-react}/host/src/pages/UtilsDemo.tsx +0 -0
  173. /package/examples/{react → templates/react-react}/host/src/remotePages.tsx +0 -0
  174. /package/examples/{bridge/react-remote → templates/react-react/host}/tsconfig.json +0 -0
  175. /package/examples/{react → templates/react-react}/host/vite.config.ts +0 -0
  176. /package/examples/{react → templates/react-react}/remote/fulgurjs.config.ts +0 -0
  177. /package/examples/{react → templates/react-react}/remote/index.html +0 -0
  178. /package/examples/{react → templates/react-react}/remote/src/App.tsx +0 -0
  179. /package/examples/{react → templates/react-react}/remote/src/exposes/ClickButton.tsx +0 -0
  180. /package/examples/{react → templates/react-react}/remote/src/exposes/pages/DetailPage.tsx +0 -0
  181. /package/examples/{react → templates/react-react}/remote/src/exposes/pages/HomePage.tsx +0 -0
  182. /package/examples/{react → templates/react-react}/remote/src/exposes/utils.ts +0 -0
  183. /package/examples/{react → templates/react-react}/remote/src/main.tsx +0 -0
  184. /package/examples/{react/host → templates/react-react/remote}/tsconfig.json +0 -0
  185. /package/examples/{react → templates/react-react}/remote/vite.config.ts +0 -0
  186. /package/examples/{vue/host → templates/showcase/vue-host}/vite.config.ts +0 -0
  187. /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/fulgurjs.config.ts +0 -0
  188. /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/index.html +0 -0
  189. /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/src/bridge.tsx +0 -0
  190. /package/examples/{bridge/vue-host → templates/vue-host-react-remote/react-remote}/src/env.d.ts +0 -0
  191. /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/src/main.tsx +0 -0
  192. /package/examples/{react/remote → templates/vue-host-react-remote/react-remote}/tsconfig.json +0 -0
  193. /package/examples/{bridge → templates/vue-host-react-remote}/react-remote/vite.config.ts +0 -0
  194. /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/fulgurjs.config.ts +0 -0
  195. /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/index.html +0 -0
  196. /package/examples/{bridge/vue-remote → templates/vue-host-react-remote/vue-host}/src/env.d.ts +0 -0
  197. /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/host-session.ts +0 -0
  198. /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/src/main.ts +0 -0
  199. /package/examples/{bridge/vue-remote → templates/vue-host-react-remote/vue-host}/tsconfig.json +0 -0
  200. /package/examples/{bridge → templates/vue-host-react-remote}/vue-host/vite.config.ts +0 -0
  201. /package/examples/{vue → templates/vue-vue}/host/fulgurjs.config.ts +0 -0
  202. /package/examples/{vue → templates/vue-vue}/host/index.html +0 -0
  203. /package/examples/{vue → templates/vue-vue}/host/src/App.vue +0 -0
  204. /package/examples/{vue → templates/vue-vue}/host/src/main.ts +0 -0
  205. /package/examples/{vue → templates/vue-vue}/host/src/pages/HomePage.vue +0 -0
  206. /package/examples/{vue → templates/vue-vue}/host/src/pages/UtilsDemo.vue +0 -0
  207. /package/examples/{vue → templates/vue-vue}/host/tsconfig.json +0 -0
  208. /package/examples/{vue → templates/vue-vue}/remote/fulgurjs.config.ts +0 -0
  209. /package/examples/{vue → templates/vue-vue}/remote/index.html +0 -0
  210. /package/examples/{vue → templates/vue-vue}/remote/src/exposes/ClickButton.vue +0 -0
  211. /package/examples/{vue → templates/vue-vue}/remote/src/exposes/pages/DetailPage.vue +0 -0
  212. /package/examples/{vue → templates/vue-vue}/remote/src/exposes/pages/HomePage.vue +0 -0
  213. /package/examples/{vue → templates/vue-vue}/remote/src/exposes/utils.ts +0 -0
  214. /package/examples/{vue → templates/vue-vue}/remote/src/main.ts +0 -0
  215. /package/examples/{vue → templates/vue-vue}/remote/tsconfig.json +0 -0
  216. /package/examples/{vue → templates/vue-vue}/remote/vite.config.ts +0 -0
package/dist/cli.js CHANGED
@@ -215,18 +215,18 @@ function validateHostPages(value) {
215
215
  }
216
216
  return hp;
217
217
  }
218
- function validatePathsInsideApp(options, appRoot, fs3, path2) {
218
+ function validatePathsInsideApp(options, appRoot, fs4, path3) {
219
219
  const checkModule = (field, value) => {
220
220
  if (typeof value !== "string" || value.trim() === "") return;
221
- if (/^(https?:)?\/\//.test(value) || path2.isAbsolute(value)) {
221
+ if (/^(https?:)?\/\//.test(value) || path3.isAbsolute(value)) {
222
222
  appConfigError(
223
223
  `${field} "${value}" \u4E0D\u662F\u672C\u9879\u76EE\u5185\u7684\u6A21\u5757\u8DEF\u5F84`,
224
224
  "exposes/setup \u7684\u503C\u662F\u76F8\u5BF9\u672C\u5E94\u7528\u6839\u76EE\u5F55\u7684\u6E90\u6587\u4EF6\u8DEF\u5F84\uFF08URL/\u7EDD\u5BF9\u8DEF\u5F84\u65E0\u6CD5\u5728\u72EC\u7ACB\u4ED3\u5E93\u95F4\u79FB\u690D\uFF09",
225
225
  `\u6539\u4E3A\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 './src/views/Home.vue'\uFF08\u914D\u7F6E\u6587\u4EF6\u76EE\u5F55 = \u5E94\u7528\u6839 ${appRoot}\uFF09`
226
226
  );
227
227
  }
228
- const abs = path2.resolve(appRoot, value);
229
- if (!fs3.existsSync(abs)) {
228
+ const abs = path3.resolve(appRoot, value);
229
+ if (!fs4.existsSync(abs)) {
230
230
  appConfigError(
231
231
  `${field} \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${value}`,
232
232
  `\u6309\u5E94\u7528\u6839 ${appRoot} \u89E3\u6790\u540E\u672A\u627E\u5230\u8BE5\u6587\u4EF6`,
@@ -295,11 +295,11 @@ function resolveEsbuild(configPath) {
295
295
  );
296
296
  }
297
297
  async function loadAppConfig(configPath) {
298
- const fs3 = await import("node:fs");
298
+ const fs4 = await import("node:fs");
299
299
  const os = await import("node:os");
300
- const path2 = await import("node:path");
301
- const abs = path2.resolve(configPath);
302
- if (!fs3.existsSync(abs)) {
300
+ const path3 = await import("node:path");
301
+ const abs = path3.resolve(configPath);
302
+ if (!fs4.existsSync(abs)) {
303
303
  appConfigError(
304
304
  `\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${abs}`,
305
305
  "--config \u6307\u5411\u7684\u8DEF\u5F84\u5728\u672C\u673A\u4E0D\u5B58\u5728\uFF08\u76F8\u5BF9\u8DEF\u5F84\u4EE5 CLI \u8FDB\u7A0B cwd \u89E3\u6790\uFF09",
@@ -307,11 +307,11 @@ async function loadAppConfig(configPath) {
307
307
  );
308
308
  }
309
309
  if (abs.endsWith(".json")) {
310
- const parsed = JSON.parse(fs3.readFileSync(abs, "utf8"));
310
+ const parsed = JSON.parse(fs4.readFileSync(abs, "utf8"));
311
311
  if (isAggregateShape(parsed)) aggregateMigrationError();
312
- return finishAppShape(parsed, {}, abs, path2.dirname(abs), fs3, path2);
312
+ return finishAppShape(parsed, {}, abs, path3.dirname(abs), fs4, path3);
313
313
  }
314
- const rawSource = fs3.readFileSync(abs, "utf8");
314
+ const rawSource = fs4.readFileSync(abs, "utf8");
315
315
  if (/@fulgurjs\/federation\/config/.test(rawSource)) {
316
316
  appConfigError(
317
317
  `\u914D\u7F6E\u5BFC\u5165\u4E86\u5DF2\u5220\u9664\u7684\u5B50\u8DEF\u5F84 "@fulgurjs/federation/config"`,
@@ -342,21 +342,21 @@ async function loadAppConfig(configPath) {
342
342
  plugins: [selfRedirect],
343
343
  logLevel: "silent"
344
344
  });
345
- const tmpDir = fs3.mkdtempSync(path2.join(os.tmpdir(), "fulgurjs-appcfg-"));
345
+ const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "fulgurjs-appcfg-"));
346
346
  try {
347
- const bundleFile = path2.join(tmpDir, "fulgurjs.config.bundle.mjs");
348
- fs3.writeFileSync(bundleFile, out.outputFiles[0].text);
347
+ const bundleFile = path3.join(tmpDir, "fulgurjs.config.bundle.mjs");
348
+ fs4.writeFileSync(bundleFile, out.outputFiles[0].text);
349
349
  const mod = await import(
350
350
  /* @vite-ignore */
351
351
  `${pathToFileURL(bundleFile).href}?t=${Date.now()}`
352
352
  );
353
353
  if (isAggregateShape(mod.default)) aggregateMigrationError();
354
- return finishAppShape(mod.default, { hostPages: mod.hostPages }, abs, path2.dirname(abs), fs3, path2);
354
+ return finishAppShape(mod.default, { hostPages: mod.hostPages }, abs, path3.dirname(abs), fs4, path3);
355
355
  } finally {
356
- fs3.rmSync(tmpDir, { recursive: true, force: true });
356
+ fs4.rmSync(tmpDir, { recursive: true, force: true });
357
357
  }
358
358
  }
359
- function finishAppShape(def, named, configPath, appRoot, fs3, path2) {
359
+ function finishAppShape(def, named, configPath, appRoot, fs4, path3) {
360
360
  if (def === void 0 || def === null) {
361
361
  appConfigError(
362
362
  "fulgurjs.config.ts \u6CA1\u6709\u53EF\u7528\u7684\u9ED8\u8BA4\u5BFC\u51FA",
@@ -369,7 +369,7 @@ function finishAppShape(def, named, configPath, appRoot, fs3, path2) {
369
369
  }
370
370
  const options = def;
371
371
  validateAppOptions(options);
372
- validatePathsInsideApp(options, appRoot, fs3, path2);
372
+ validatePathsInsideApp(options, appRoot, fs4, path3);
373
373
  const hostPages = named.hostPages !== void 0 ? validateHostPages(named.hostPages) : void 0;
374
374
  return {
375
375
  kind: "app",
@@ -472,7 +472,7 @@ var init_init = __esm({
472
472
  // CLI\uFF08\u7EAF\u672C\u5730\uFF0C\u65E0\u7F51\u7EDC\uFF09\uFF1A
473
473
  // npx fulgurjs explain # \u89E3\u91CA\u672C\u5E94\u7528\u6709\u6548\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE
474
474
  // npx fulgurjs check-pages # \u5BBF\u4E3B\u9875\u9762\u8868 \u2194 \u8FDC\u7A0B manifest \u5951\u7EA6\u6838\u5BF9
475
- // npx fulgurjs doctor --base http://<\u7AD9\u70B9> --apps <\u5BB9\u5668\u540D> # \u90E8\u7F72\u4F53\u68C0
475
+ // npx fulgurjs doctor --base http://<\u7AD9\u70B9> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55> # \u90E8\u7F72\u4F53\u68C0\uFF08\u90E8\u7F72\u5728 /my-remote/ \u5C31\u5199 my-remote\uFF09
476
476
  import type { FederationOptions } from '@fulgurjs/federation'
477
477
 
478
478
  export default {
@@ -518,12 +518,214 @@ export default {
518
518
  "5. \u5E94\u7528\u4EE3\u7801\u552F\u4E00 API \u5165\u53E3\uFF1Aimport { loadRemote, provideAppContext, getAppContext, clearAppContext, definePages, createHostPages, remoteSchema, remoteComponent } from '@fulgurjs/federation/runtime'",
519
519
  '6. dev \u51B7\u542F\u52A8\u9996\u8F6E 30~60s \u6709\u9884\u6784\u5EFA\u7A97\u53E3\uFF08\u77AC\u65F6 504/"ce"\uFF0CDEV-010\uFF09\uFF1A\u5148\u771F\u5B9E\u6253\u5F00\u9875\u9762\u9884\u70ED\u518D\u505A\u65AD\u8A00',
520
520
  "7. \u914D\u7F6E\u89E3\u91CA\uFF1Afulgurjs explain\uFF1B\u9875\u9762\u5951\u7EA6\u6838\u5BF9\uFF1Afulgurjs check-pages\uFF08\u5BBF\u4E3B\u9879\u76EE\u8FD0\u884C\uFF0C--manifest/--site \u6307\u5B9A\u8FDC\u7A0B manifest \u6765\u6E90\uFF09\uFF1B",
521
- " \u90E8\u7F72\u4F53\u68C0\uFF1Afulgurjs doctor --base <URL> --apps <\u5BB9\u5668\u540D...>",
521
+ " \u90E8\u7F72\u4F53\u68C0\uFF1Afulgurjs doctor --base <URL> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55...>\uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u4E0D\u662F\u5BB9\u5668\u540D\uFF09",
522
522
  "8. \u90E8\u7F72\u8BED\u4E49\uFF1AremoteEntry/manifest/index.html \u5FC5\u987B no-cache\uFF08\u4E25\u7981 immutable\uFF09\uFF1B\u5E26 hash \u7684 assets \u957F\u7F13\u5B58"
523
523
  ];
524
524
  }
525
525
  });
526
526
 
527
+ // src/create.ts
528
+ var create_exports = {};
529
+ __export(create_exports, {
530
+ COPY_EXCLUDED: () => COPY_EXCLUDED,
531
+ TEMPLATE_CATALOG: () => TEMPLATE_CATALOG,
532
+ copyTemplate: () => copyTemplate,
533
+ createProject: () => createProject,
534
+ defaultInstall: () => defaultInstall,
535
+ formatCreateResult: () => formatCreateResult,
536
+ isExcluded: () => isExcluded,
537
+ nodeVersionWarning: () => nodeVersionWarning,
538
+ packageRootOf: () => packageRootOf,
539
+ readDevConfig: () => readDevConfig,
540
+ resolveTemplatesRoot: () => resolveTemplatesRoot,
541
+ validateTemplateDir: () => validateTemplateDir
542
+ });
543
+ import fs2 from "node:fs";
544
+ import path2 from "node:path";
545
+ import { fileURLToPath } from "node:url";
546
+ import { spawn } from "node:child_process";
547
+ function packageRootOf(moduleUrl) {
548
+ return fileURLToPath(new URL("..", moduleUrl));
549
+ }
550
+ function resolveTemplatesRoot(moduleUrl) {
551
+ const root = path2.join(packageRootOf(moduleUrl), "examples", "templates");
552
+ if (!fs2.existsSync(root)) {
553
+ throw new Error(
554
+ "[fulgurjs:create] \u5F53\u524D\u5B89\u88C5\u7F3A\u5C11\u6A21\u677F\u8D44\u4EA7\uFF08examples/templates\uFF09\u3002\n \u6839\u56E0\uFF1A\u6A21\u677F\u7531 npm \u6B63\u5F0F\u5305\u9644\u5E26\uFF1B\u4ECE\u4ED3\u5E93\u6E90\u7801\u76F4\u63A5\u8FD0\u884C CLI \u65F6\u8BE5\u76EE\u5F55\u53EA\u5728 build \u540E\u751F\u6210\u3002\n \u4FEE\u6CD5\uFF1A\u7528 npm \u6B63\u5F0F\u5305\u8FD0\u884C\uFF08npx @fulgurjs/federation create\uFF09\uFF0C\u6216\u5728\u63D2\u4EF6\u4ED3\u5E93\u6267\u884C npm --prefix packages/plugin run build \u540E\u91CD\u8BD5"
555
+ );
556
+ }
557
+ return root;
558
+ }
559
+ function isExcluded(name) {
560
+ if (COPY_EXCLUDED.has(name)) return true;
561
+ return name.endsWith(".log");
562
+ }
563
+ function copyTemplate(from, to) {
564
+ fs2.mkdirSync(to, { recursive: true });
565
+ for (const entry of fs2.readdirSync(from, { withFileTypes: true })) {
566
+ if (isExcluded(entry.name)) continue;
567
+ const src = path2.join(from, entry.name);
568
+ const dest = path2.join(to, entry.name);
569
+ if (entry.isDirectory()) copyTemplate(src, dest);
570
+ else fs2.copyFileSync(src, dest);
571
+ }
572
+ }
573
+ function validateTemplateDir(dir) {
574
+ const required = ["package.json", "pnpm-workspace.yaml", "pnpm-lock.yaml", "scripts/dev.mjs", "scripts/dev.config.json"];
575
+ return required.filter((f) => !fs2.existsSync(path2.join(dir, f)));
576
+ }
577
+ function readDevConfig(templateDir) {
578
+ const file = path2.join(templateDir, "scripts", "dev.config.json");
579
+ const parsed = JSON.parse(fs2.readFileSync(file, "utf8"));
580
+ if (!Array.isArray(parsed.apps) || parsed.apps.length === 0) {
581
+ throw new Error(`[fulgurjs:create] ${file} \u7F3A\u5C11 apps \u6570\u7EC4`);
582
+ }
583
+ for (const app of parsed.apps) {
584
+ if (typeof app.name !== "string" || typeof app.dir !== "string" || typeof app.port !== "number") {
585
+ throw new Error(`[fulgurjs:create] ${file} \u7684 apps \u6761\u76EE\u9700\u8981 name/dir/port \u4E09\u4E2A\u5B57\u6BB5`);
586
+ }
587
+ }
588
+ return parsed;
589
+ }
590
+ function pluginVersionOf(templateDir, apps) {
591
+ for (const app of apps) {
592
+ try {
593
+ const pkg = JSON.parse(fs2.readFileSync(path2.join(templateDir, app.dir, "package.json"), "utf8"));
594
+ const version = pkg.dependencies?.["@fulgurjs/federation"];
595
+ if (version) return version;
596
+ } catch {
597
+ }
598
+ }
599
+ return "\uFF08\u672A\u5728\u5B50\u5E94\u7528\u58F0\u660E\u4E2D\u627E\u5230 @fulgurjs/federation\uFF09";
600
+ }
601
+ function formatCreateResult(result) {
602
+ const apps = result.apps;
603
+ const lines = [];
604
+ lines.push(`[fulgurjs:create] \u5DF2\u521B\u5EFA\u5B8C\u6574\u5DE5\u7A0B ${result.target}\uFF08\u6A21\u677F ${result.template}\uFF0C\u63D2\u4EF6\u4F9D\u8D56 ${result.pluginVersion}\uFF09`);
605
+ lines.push("\u540E\u7EED\u6B65\u9AA4\uFF1A");
606
+ lines.push(` cd ${result.target}`);
607
+ if (!result.installRan) lines.push(" pnpm install --frozen-lockfile");
608
+ lines.push(" pnpm dev # \u6309\u542F\u52A8\u987A\u5E8F\u62C9\u8D77\u5168\u90E8\u5E94\u7528\uFF0C\u5931\u8D25\u4F1A\u6574\u7EC4\u9000\u51FA\u5E76\u8BF4\u660E\u539F\u56E0");
609
+ lines.push("\u8BBF\u95EE\u5165\u53E3\uFF08\u8FDC\u7A0B\u5148\u4E8E\u5BBF\u4E3B\u5C31\u7EEA\uFF09\uFF1A");
610
+ for (const app of apps) {
611
+ lines.push(` http://localhost:${app.port}/ ${app.name}${app.dir !== app.name ? `\uFF08\u76EE\u5F55 ${app.dir}\uFF09` : ""}`);
612
+ }
613
+ const hosts = apps.slice().reverse();
614
+ lines.push(`\u6D4F\u89C8\u5668\u6253\u5F00\u5BBF\u4E3B\u5165\u53E3\uFF1A${hosts.length ? `http://localhost:${hosts[0].port}/` : "\uFF08\u89C1\u6A21\u677F README\uFF09"}`);
615
+ lines.push(" pnpm build # \u5404\u5B50\u5E94\u7528\u751F\u4EA7\u6784\u5EFA\uFF08\u8FDC\u7A0B\u751F\u6210 fulgurjs-remoteEntry.js / fulgurjs-manifest.json\uFF09");
616
+ lines.push(" \u90E8\u7F72\u89C4\u5219\uFF08no-cache / SPA \u56DE\u9000 / base \u5BF9\u9F50\uFF09\u89C1\u6A21\u677F\u5185\u5404\u5B50\u5E94\u7528 README\uFF1B\u90E8\u7F72\u540E\u53EF\u7528 npx fulgurjs doctor --base <\u7AD9\u70B9> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55> \u4F53\u68C0");
617
+ lines.push(" \u6539\u7AEF\u53E3\uFF1A\u6539 <\u8FDC\u7A0B|\u5BBF\u4E3B>/package.json \u7684 dev/preview \u7AEF\u53E3\uFF0C\u5E76\u540C\u6B65\u5BBF\u4E3B fulgurjs.config.ts \u7684 remotes dev \u5730\u5740");
618
+ return lines.join("\n");
619
+ }
620
+ function formatCreateJson(result) {
621
+ return JSON.stringify(
622
+ {
623
+ template: result.template,
624
+ target: result.target,
625
+ pluginVersion: result.pluginVersion,
626
+ apps: result.apps,
627
+ installRan: result.installRan,
628
+ ...result.installCode !== void 0 ? { installCode: result.installCode } : {},
629
+ next: {
630
+ cd: result.target,
631
+ dev: "pnpm dev",
632
+ build: "pnpm build"
633
+ }
634
+ },
635
+ null,
636
+ 2
637
+ );
638
+ }
639
+ function nodeVersionWarning(nodeVersion) {
640
+ const major = Number(nodeVersion.replace(/^v/, "").split(".")[0]);
641
+ if (Number.isFinite(major) && major < 20) {
642
+ return `\u5F53\u524D Node ${nodeVersion} \u4F4E\u4E8E\u6A21\u677F\u8981\u6C42\uFF08Node \u2265 20\uFF0C\u5B9E\u6D4B 24.x\uFF09\u2014\u2014\u5B89\u88C5\u53EF\u80FD\u6210\u529F\uFF0C\u4F46\u4E0E\u6A21\u677F\u9A8C\u8BC1\u73AF\u5883\u4E0D\u7B26`;
643
+ }
644
+ return void 0;
645
+ }
646
+ async function createProject(opts, io) {
647
+ const templateName = opts.template ?? await io.prompt("\u9009\u62E9\u6A21\u677F\uFF08" + TEMPLATE_CATALOG.map((t) => t.name).join(" / ") + "\uFF09\uFF1A");
648
+ const info = TEMPLATE_CATALOG.find((t) => t.name === templateName);
649
+ if (!info) {
650
+ throw new Error(
651
+ `[fulgurjs:create] \u672A\u77E5\u6A21\u677F\uFF1A${templateName}
652
+ \u53EF\u7528\u6A21\u677F\uFF1A${TEMPLATE_CATALOG.map((t) => t.name).join("\u3001")}
653
+ \u4FEE\u6CD5\uFF1Afulgurjs create --list \u67E5\u770B\u8BF4\u660E\uFF0C\u6216 fulgurjs create <\u6A21\u677F\u540D> --dir <\u76EE\u6807\u76EE\u5F55>`
654
+ );
655
+ }
656
+ const templateDir = path2.join(opts.templatesRoot, templateName);
657
+ if (!fs2.existsSync(path2.join(templateDir, "package.json"))) {
658
+ throw new Error(`[fulgurjs:create] \u5305\u5185\u6A21\u677F\u4E0D\u5B8C\u6574\uFF1A${templateDir} \u7F3A\u5C11 package.json`);
659
+ }
660
+ const target = path2.resolve(opts.cwd, opts.dir ?? templateName);
661
+ if (fs2.existsSync(target)) {
662
+ const existing = fs2.readdirSync(target);
663
+ if (existing.length > 0 && !opts.force) {
664
+ throw new Error(
665
+ `[fulgurjs:create] \u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF1A${target}
666
+ \u6839\u56E0\uFF1A\u9759\u9ED8\u5408\u5E76\u53EF\u80FD\u63A9\u76D6\u4E0E\u4F60\u5DF2\u6709\u6587\u4EF6\u7684\u51B2\u7A81\u3002
667
+ \u4FEE\u6CD5\uFF1A\u6362\u4E00\u4E2A\u76EE\u5F55\uFF08--dir\uFF09\uFF0C\u6216\u786E\u8BA4\u540E\u52A0 --force\uFF08\u53EA\u65B0\u589E\u6A21\u677F\u6587\u4EF6\uFF0C\u4E0D\u5220\u9664/\u6539\u5199\u4F60\u5DF2\u6709\u7684\u6587\u4EF6\uFF09`
668
+ );
669
+ }
670
+ if (existing.length > 0) {
671
+ io.log(`[fulgurjs:create] --force\uFF1A\u5411\u975E\u7A7A\u76EE\u5F55 ${target} \u589E\u91CF\u590D\u5236\uFF08\u4E0D\u5220\u9664\u5DF2\u6709\u6587\u4EF6\uFF09`);
672
+ }
673
+ }
674
+ const warnings = [];
675
+ const nodeWarn = nodeVersionWarning(process.version);
676
+ if (nodeWarn) warnings.push(nodeWarn);
677
+ copyTemplate(templateDir, target);
678
+ const missing = validateTemplateDir(target);
679
+ if (missing.length > 0) {
680
+ throw new Error(`[fulgurjs:create] \u590D\u5236\u540E\u7684\u6A21\u677F\u7F3A\u5C11\u5173\u952E\u6587\u4EF6\uFF1A${missing.join("\u3001")}\u2014\u2014\u5305\u5185\u6A21\u677F\u8D44\u4EA7\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u53CD\u9988\u7248\u672C\u53F7`);
681
+ }
682
+ const apps = readDevConfig(target).apps;
683
+ const pluginVersion = pluginVersionOf(target, apps);
684
+ let installRan = false;
685
+ let installCode;
686
+ if (opts.install) {
687
+ installRan = true;
688
+ io.log(`[fulgurjs:create] \u5B89\u88C5\u4F9D\u8D56\uFF08pnpm install --frozen-lockfile\uFF0C\u76EE\u5F55 ${target}\uFF09\u2026`);
689
+ installCode = await io.install(target);
690
+ if (installCode !== 0) {
691
+ throw new Error(
692
+ `[fulgurjs:create] \u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF08\u9000\u51FA\u7801 ${installCode}\uFF09\u3002\u4E0A\u9762\u7684\u8F93\u51FA\u5305\u542B\u5177\u4F53\u539F\u56E0\uFF1B\u5E38\u89C1\u539F\u56E0\uFF1Apnpm \u672A\u5B89\u88C5\uFF08corepack enable \u6216 npm i -g pnpm\uFF09\u3001registry \u4E0D\u53EF\u8FBE\u3001Node \u7248\u672C\u8FC7\u4F4E\u3002
693
+ \u4F9D\u8D56\u672A\u88AB\u5047\u88C5\u6210\u529F\uFF1A\u4FEE\u590D\u540E\u8FDB\u5165 ${target} \u624B\u52A8\u6267\u884C pnpm install --frozen-lockfile \u518D pnpm dev`
694
+ );
695
+ }
696
+ } else {
697
+ io.log("[fulgurjs:create] \u6309\u8981\u6C42\u8DF3\u8FC7\u5B89\u88C5\uFF08--no-install\uFF09\uFF1A\u8FDB\u5165\u76EE\u5F55\u540E\u5148\u6267\u884C pnpm install --frozen-lockfile");
698
+ }
699
+ for (const w of warnings) io.log(`[fulgurjs:create] \u8B66\u544A\uFF1A${w}`);
700
+ const result = { template: templateName, target, pluginVersion, apps, installRan, installCode };
701
+ io.log(opts.json ? formatCreateJson(result) : formatCreateResult(result));
702
+ return result;
703
+ }
704
+ function defaultInstall(cwd) {
705
+ return new Promise((resolve2) => {
706
+ const child = spawn("pnpm", ["install", "--frozen-lockfile"], { cwd, stdio: "inherit" });
707
+ child.once("error", (e) => {
708
+ console.error(`[fulgurjs:create] \u65E0\u6CD5\u542F\u52A8 pnpm\uFF1A${e.message}\uFF08corepack enable \u6216 npm i -g pnpm\uFF09`);
709
+ resolve2(1);
710
+ });
711
+ child.once("close", (code) => resolve2(code ?? 1));
712
+ });
713
+ }
714
+ var TEMPLATE_CATALOG, COPY_EXCLUDED;
715
+ var init_create = __esm({
716
+ "src/create.ts"() {
717
+ "use strict";
718
+ TEMPLATE_CATALOG = [
719
+ { name: "vue-vue", summary: "Vue \u5BBF\u4E3B \xD7 Vue \u8FDC\u7A0B\uFF1A\u8FDC\u7A0B\u7EC4\u4EF6/TS \u6A21\u5757/\u9875\u9762\u63A5\u5165\u3001\u9519\u8BEF\u6062\u590D\u3001\u751F\u4EA7\u90E8\u7F72" },
720
+ { name: "react-react", summary: "React \u5BBF\u4E3B \xD7 React \u8FDC\u7A0B\uFF1AremoteComponent/useLoadRemote/ErrorBoundary" },
721
+ { name: "vue-host-react-remote", summary: "Vue \u5BBF\u4E3B \xD7 React \u5B50\u5E94\u7528\uFF1A\u8DE8\u6846\u67B6\u6865\u63A5\uFF08\u6302\u8F7D/\u5378\u8F7D/appProps \u5FEB\u7167\uFF09" },
722
+ { name: "react-host-vue-remote", summary: "React \u5BBF\u4E3B \xD7 Vue \u5B50\u5E94\u7528\uFF1A\u53CD\u65B9\u5411\u6865\u63A5" },
723
+ { name: "showcase", summary: "\u53CC\u5411\u6865\u63A5 + URL \u540C\u6B65 showcase\uFF1AVue/React \u53CC\u5BBF\u4E3B \xD7 \u53CC\u8FDC\u7A0B\uFF0C\u6DF1\u94FE\u5237\u65B0/\u524D\u8FDB\u540E\u9000" }
724
+ ];
725
+ COPY_EXCLUDED = /* @__PURE__ */ new Set(["node_modules", "dist", ".vite", ".run", ".DS_Store"]);
726
+ }
727
+ });
728
+
527
729
  // src/pages.ts
528
730
  function defaultDeriveSpec(route) {
529
731
  return segs(route).slice(1).filter((seg) => !seg.startsWith(":")).join("/");
@@ -646,6 +848,7 @@ var init_pages = __esm({
646
848
  // src/commands.ts
647
849
  var commands_exports = {};
648
850
  __export(commands_exports, {
851
+ bridgeWarningsOf: () => bridgeWarningsOf,
649
852
  checkPages: () => checkPages,
650
853
  explainApp: () => explainApp,
651
854
  formatCheckPages: () => formatCheckPages,
@@ -653,7 +856,7 @@ __export(commands_exports, {
653
856
  manifestUrlForRemoteAddress: () => manifestUrlForRemoteAddress,
654
857
  stripRemoteNamePrefix: () => stripRemoteNamePrefix
655
858
  });
656
- import fs2 from "node:fs";
859
+ import fs3 from "node:fs";
657
860
  function mappingsOf(hp, deriveFallback) {
658
861
  const pages = hp.pages ?? [];
659
862
  const prefixes = Object.entries(hp.remotePrefixes ?? {}).sort((a, b) => b[0].length - a[0].length);
@@ -705,6 +908,50 @@ function chainLines(options, role) {
705
908
  }
706
909
  return chain;
707
910
  }
911
+ function bridgeWarningsOf(options) {
912
+ const warns = [];
913
+ const rawShared = options.shared;
914
+ const shared = rawShared && !Array.isArray(rawShared) ? rawShared : {};
915
+ const hintOf = (name) => {
916
+ const v = shared[name];
917
+ if (v === void 0) return void 0;
918
+ if (typeof v === "string") return { singleton: false };
919
+ return v;
920
+ };
921
+ const isSingleton = (name) => hintOf(name)?.singleton === true;
922
+ const exposeKeys = Object.keys(options.exposes ?? {}).map((k) => k.replace(/^\.\//, ""));
923
+ const hasVue = hintOf("vue") !== void 0;
924
+ const hasReact = hintOf("react") !== void 0;
925
+ if (exposeKeys.includes("bridge")) {
926
+ if (hasVue && !hasReact && !isSingleton("vue")) {
927
+ warns.push(
928
+ "WARN \u6865\u63A5\u5B50\u5E94\u7528 shared.vue \u7F3A\u5C11 singleton: true\u2014\u2014\u5BBF\u4E3B\u4E0E\u5B50\u5E94\u7528\u4F1A\u5404\u6301\u4E00\u4EFD Vue \u5B9E\u4F8B\uFF08\u75C7\u72B6\uFF1Aprovide/inject \u5931\u6548\u3001\u72B6\u6001\u4E0D\u4E92\u901A\uFF09\u3002\n \u4FEE\u6CD5: fulgurjs.config.ts \u7684 shared \u6539\u4E3A vue: { singleton: true }"
929
+ );
930
+ }
931
+ if (hasReact && !hasVue && (!isSingleton("react") || !isSingleton("react-dom"))) {
932
+ warns.push(
933
+ `WARN \u6865\u63A5\u5B50\u5E94\u7528 React \u4FA7\u9700 react \u4E0E react-dom \u53CC singleton\uFF08\u5F53\u524D react=${String(isSingleton("react"))}\uFF0Creact-dom=${hintOf("react-dom") === void 0 ? "\u672A\u5171\u4EAB" : String(isSingleton("react-dom"))}\uFF09\u2014\u2014\u7F3A\u4E00\u4F1A\u51FA\u73B0\u4E24\u5957 React/renderer\uFF08\u75C7\u72B6\uFF1AInvalid hook call\uFF09\u3002
934
+ \u4FEE\u6CD5: shared \u52A0 react: { singleton: true }, 'react-dom': { singleton: true }`
935
+ );
936
+ }
937
+ if (!hasVue && !hasReact) {
938
+ warns.push(
939
+ "WARN exposes \u542B ./bridge\uFF08\u6865\u63A5\u5B50\u5E94\u7528\u5951\u7EA6\uFF09\u4F46 shared \u672A\u58F0\u660E\u4EFB\u4F55\u6846\u67B6\u2014\u2014\u5BBF\u4E3B\u65E0\u6CD5\u4E0E\u5B50\u5E94\u7528\u6536\u655B\u5230\u540C\u4E00\u6846\u67B6\u5B9E\u4F8B\u3002\n \u4FEE\u6CD5: \u5728 shared \u58F0\u660E\u672C\u5E94\u7528\u6846\u67B6\uFF08Vue \u5B50\u5E94\u7528\uFF1Avue\uFF1BReact \u5B50\u5E94\u7528\uFF1Areact + react-dom\uFF09\uFF0C\u5168\u90E8 singleton: true"
940
+ );
941
+ }
942
+ }
943
+ if (hasVue && hasReact) {
944
+ const missing = ["vue", "react", "react-dom"].filter((k) => hintOf(k) !== void 0 && !isSingleton(k));
945
+ const absent = ["vue", "react", "react-dom"].filter((k) => hintOf(k) === void 0);
946
+ if (missing.length > 0 || absent.length > 0) {
947
+ warns.push(
948
+ `WARN \u8DE8\u6846\u67B6\u6865\u63A5\u5BBF\u4E3B\u9700 vue\u3001react\u3001react-dom \u4E09\u952E\u5168\u90E8 singleton: true\uFF08\u672A singleton\uFF1A${missing.join("\u3001") || "\u65E0"}\uFF1B\u672A\u5171\u4EAB\uFF1A${absent.join("\u3001") || "\u65E0"}\uFF09\u2014\u2014\u7F3A\u4E00\u4F1A\u5BFC\u81F4\u8DE8\u6846\u67B6\u6302\u8F7D\u65F6\u51FA\u73B0\u53CC\u5B9E\u4F8B\u6216\u534F\u5546\u9519\u4E71\u3002
949
+ \u4FEE\u6CD5: shared \u58F0\u660E\u4E09\u952E\u5E76\u5404\u914D singleton: true\uFF08\u53C2\u89C1 API \u624B\u518C \xA78.2 \u53CC\u6846\u67B6\u5B89\u88C5\u5408\u540C\uFF09`
950
+ );
951
+ }
952
+ }
953
+ return warns;
954
+ }
708
955
  function explainAppMode(loaded) {
709
956
  const options = loaded.options;
710
957
  const role = roleOfOptions(options);
@@ -722,6 +969,7 @@ function explainAppMode(loaded) {
722
969
  devSharedSelf: { value: devSharedSelfValue, source: devSharedSelfExplicit ? "explicit" : "inferred" },
723
970
  pages: hp ? mappingsOf(hp, DEFAULT_DERIVE) : [],
724
971
  pagesSource: hp ? `fulgurjs.config.ts \u7684 hostPages \u5177\u540D\u5BFC\u51FA\uFF08${hp.pages.length} \u6761\uFF1B\u8FD0\u884C\u65F6\u771F\u6E90\u4E3A\u5E94\u7528\u5185\u540C\u4E00\u6570\u636E\u6A21\u5757\uFF09` : "\u672A\u627E\u5230 hostPages \u5177\u540D\u5BFC\u51FA\uFF08\u7EAF\u8FDC\u7A0B\u5E94\u7528\u65E0\u9700\u9875\u9762\u8868\uFF1B\u5BBF\u4E3B\u82E5\u8981\u8DD1 check-pages \u8BF7\u5728 fulgurjs.config.ts \u8865\u5177\u540D\u5BFC\u51FA hostPages\uFF09",
972
+ bridgeWarnings: bridgeWarningsOf(options),
725
973
  chain: chainLines(options, role)
726
974
  };
727
975
  }
@@ -747,6 +995,10 @@ function formatExplain(r) {
747
995
  }
748
996
  }
749
997
  L.push(`devSharedSelf\uFF1A${r.devSharedSelf.value}\uFF08\u6765\u6E90\uFF1A${r.devSharedSelf.source === "explicit" ? "\u663E\u5F0F\u914D\u7F6E" : "\u6309\u89D2\u8272\u63A8\u65AD\u2014\u2014\u63D0\u4F9B exposes/setup \u7684\u5E94\u7528\u4E3A true\uFF0C\u7EAF\u5BBF\u4E3B\u4E3A false"}\uFF09`);
998
+ if (r.bridgeWarnings?.length) {
999
+ L.push("\u6865\u63A5\u5B8C\u5907\u6027\uFF1A");
1000
+ for (const w of r.bridgeWarnings) L.push(` ${w.replaceAll("\n", "\n ")}`);
1001
+ }
750
1002
  if (r.pages.length) {
751
1003
  L.push(`\u9875\u9762 spec \u6620\u5C04\uFF08${r.pages.length}\uFF09\u2014\u2014\u6765\u6E90\uFF1A${r.pagesSource}\uFF1A`);
752
1004
  for (const p of r.pages) L.push(` ${p.route} \u2192 ${p.spec}${p.title ? `\uFF08${p.title}\uFF09` : ""}`);
@@ -759,7 +1011,7 @@ function formatExplain(r) {
759
1011
  }
760
1012
  function manifestFromFile(p) {
761
1013
  try {
762
- const parsed = parseManifest(JSON.parse(fs2.readFileSync(p, "utf8")));
1014
+ const parsed = parseManifest(JSON.parse(fs3.readFileSync(p, "utf8")));
763
1015
  if (parsed.manifest && !parsed.unsupportedVersion) return parsed.manifest;
764
1016
  } catch {
765
1017
  }
@@ -1236,9 +1488,14 @@ function formatDoctorReport(checks) {
1236
1488
  // src/cli.ts
1237
1489
  var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
1238
1490
 
1239
- \u7528\u6CD5\uFF08\u5355\u9879\u76EE fulgurjs.config.ts \u5728\u5E94\u7528\u6839\u76EE\u5F55\uFF1B\u547D\u4EE4\u9ED8\u8BA4\u8BFB ./fulgurjs.config.ts\uFF09\uFF1A
1491
+ \u65B0\u9879\u76EE\uFF1A\u4ECE\u5B8C\u6574\u6A21\u677F\u521B\u5EFA\u53EF\u72EC\u7ACB\u8FD0\u884C\u7684\u8054\u90A6\u5DE5\u7A0B\uFF08\u590D\u5236\u540E pnpm install + pnpm dev\uFF09\uFF1A
1492
+ fulgurjs create [--list] \u4EA4\u4E92\u9009\u62E9\u6A21\u677F\uFF08TTY\uFF09
1493
+ fulgurjs create <\u6A21\u677F> [--dir <\u8DEF\u5F84>] [--no-install] [--force] [--json]
1494
+ \u975E\u4EA4\u4E92\u521B\u5EFA\uFF1B\u6A21\u677F\uFF1Avue-vue / react-react /
1495
+ vue-host-react-remote / react-host-vue-remote / showcase
1496
+ \u5DF2\u6709\u9879\u76EE\uFF08\u5355\u9879\u76EE fulgurjs.config.ts \u5728\u5E94\u7528\u6839\u76EE\u5F55\uFF1B\u547D\u4EE4\u9ED8\u8BA4\u8BFB ./fulgurjs.config.ts\uFF09\uFF1A
1240
1497
  fulgurjs init [--template <path>] [--force] \u751F\u6210\u5355\u9879\u76EE fulgurjs.config.ts \u8D77\u6B65\u6A21\u677F
1241
- \uFF08\u9ED8\u8BA4\u5BFC\u51FA\u76F4\u63A5\u662F federation() \u9009\u9879\uFF09
1498
+ \uFF08\u9ED8\u8BA4\u5BFC\u51FA\u76F4\u63A5\u662F federation() \u9009\u9879\uFF1B--template \u662F\u8F93\u51FA\u8DEF\u5F84\uFF09
1242
1499
  fulgurjs init --config <path> \u6821\u9A8C\u914D\u7F6E\uFF1B\u8F93\u51FA federation(fulgurjsConfig) \u63A5\u5165\u5757
1243
1500
  \u4E0E\u63A5\u5165\u6838\u5BF9\u6E05\u5355
1244
1501
  fulgurjs explain [--config <path>] [--json] \u89E3\u91CA\u672C\u5E94\u7528\u6709\u6548\u8054\u90A6\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE\uFF08\u7EAF\u672C\u5730\uFF0C\u65E0\u7F51\u7EDC\uFF09
@@ -1248,11 +1505,13 @@ var HELP = `fulgurjs \u2014 Vite Module Federation CLI (@fulgurjs/federation)
1248
1505
  manifest \u6765\u6E90\u4F18\u5148\u7EA7 --manifest > --site/prod \u63A8\u5BFC\uFF0C
1249
1506
  \u663E\u5F0F\u6307\u5B9A\u6765\u6E90\u5931\u8D25\u4E0D\u56DE\u9000\uFF1B\u786E\u5B9A\u6027\u9519\u8BEF\u975E\u96F6\u9000\u51FA\uFF1B
1250
1507
  --require-verified \u65F6\u65E0\u6CD5\u9A8C\u8BC1\u4E5F\u975E\u96F6\uFF09
1508
+ \u90E8\u7F72\u4F53\u68C0\uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u8FDC\u7A0B\u90E8\u7F72\u5728 /remote-a/ \u5C31\u5199 remote-a\uFF09\uFF1A
1251
1509
  fulgurjs doctor --base <URL> --apps <a,b,c> [--dev] [--json] [--chunk-sample N]
1252
1510
  fulgurjs --help
1253
1511
 
1254
- \u793A\u4F8B\uFF08\u5E94\u7528\u6839\u76EE\u5F55\u5185\u8FD0\u884C\uFF09\uFF1A
1255
- fulgurjs init # \u5F53\u524D\u76EE\u5F55\u5199 fulgurjs.config.ts\uFF08\u5DF2\u5B58\u5728\u5219\u62D2\u7EDD\uFF0C--force \u8986\u76D6\uFF09
1512
+ \u793A\u4F8B\uFF1A
1513
+ fulgurjs create vue-vue --dir my-federation # \u521B\u5EFA\u5B8C\u6574\u5DE5\u7A0B\u5E76\u5B89\u88C5\u4F9D\u8D56\uFF08\u63A8\u8350\u7684\u65B0\u9879\u76EE\u8D77\u70B9\uFF09
1514
+ fulgurjs init # \u5DF2\u6709\u9879\u76EE\uFF1A\u5F53\u524D\u76EE\u5F55\u5199 fulgurjs.config.ts\uFF08\u5DF2\u5B58\u5728\u5219\u62D2\u7EDD\uFF0C--force \u8986\u76D6\uFF09
1256
1515
  fulgurjs explain # \u89E3\u91CA\u672C\u5E94\u7528\uFF08--config \u6307\u5411\u5176\u4ED6\u8DEF\u5F84\u65F6\u663E\u5F0F\u4F20\uFF09
1257
1516
  fulgurjs check-pages --site http://your-site # \u6309 remotes prod \u5730\u5740\u63A8\u5BFC\u8FDC\u7A0B manifest \u6838\u5BF9
1258
1517
  fulgurjs check-pages --manifest remote-a=https://cdn.example.com/remote-a/fulgurjs-manifest.json
@@ -1307,11 +1566,50 @@ async function main() {
1307
1566
  import fulgurjsConfig from './fulgurjs.config'
1308
1567
  // plugins: [ ...\u539F\u6709\u63D2\u4EF6, federation(fulgurjsConfig) ]
1309
1568
  3. npx fulgurjs explain # \u6838\u5BF9\u6709\u6548\u5F62\u6001\u4E0E\u52A0\u8F7D\u94FE
1310
- 4. \u5BBF\u4E3B\u5E94\u7528\u53E6\u5728 fulgurjs.config.ts \u5177\u540D\u5BFC\u51FA hostPages\uFF08\u4E0E\u8FD0\u884C\u65F6\u9875\u9762\u6570\u636E\u6A21\u5757\u540C\u6E90\uFF09\uFF0C
1311
- \u8FD0\u884C npx fulgurjs check-pages --site <\u7AD9\u70B9> \u6838\u5BF9\u9875\u9762\u5951\u7EA6
1312
- 5. \u90E8\u7F72\u540E\uFF1Anpx fulgurjs doctor --base <URL> --apps <\u5BB9\u5668\u540D>`);
1569
+ 4. \u90E8\u7F72\u540E\uFF1Anpx fulgurjs doctor --base <URL> --apps <\u90E8\u7F72\u5B50\u76EE\u5F55>
1570
+ \uFF08--apps \u662F\u7AD9\u70B9\u6839\u4E0B\u7684\u90E8\u7F72\u5B50\u76EE\u5F55\uFF0C\u5982\u8FDC\u7A0B\u90E8\u7F72\u5728 /my-remote/ \u5C31\u5199 my-remote\uFF0C\u4E0D\u662F\u5BB9\u5668\u540D\uFF09
1571
+ \u8BF4\u660E\uFF1A\u52A0\u8F7D\u666E\u901A\u7EC4\u4EF6/\u6A21\u5757\u4E0D\u9700\u8981\u9875\u9762\u8868\u3002\u53EA\u6709\u5F53\u5BBF\u4E3B\u7528\u300C\u9875\u9762\u8DEF\u7531\u8868 \u2192 \u8FDC\u7A0B\u9875\u9762\u300D\u65B9\u5F0F\u63A5\u5165\u65F6\uFF0C
1572
+ \u624D\u5728 fulgurjs.config.ts \u8FFD\u52A0\u5177\u540D\u5BFC\u51FA hostPages\uFF0C\u5E76\u8FD0\u884C npx fulgurjs check-pages --site <\u7AD9\u70B9> \u6838\u5BF9\u3002`);
1313
1573
  return 0;
1314
1574
  }
1575
+ if (cmd === "create") {
1576
+ if (has("--list")) {
1577
+ const { TEMPLATE_CATALOG: TEMPLATE_CATALOG2 } = await Promise.resolve().then(() => (init_create(), create_exports));
1578
+ for (const t of TEMPLATE_CATALOG2) console.log(`${t.name.padEnd(24)} ${t.summary}`);
1579
+ return 0;
1580
+ }
1581
+ const { createProject: createProject2, resolveTemplatesRoot: resolveTemplatesRoot2, defaultInstall: defaultInstall2 } = await Promise.resolve().then(() => (init_create(), create_exports));
1582
+ let promptImpl;
1583
+ if (process.stdin.isTTY) {
1584
+ const readline = await import("node:readline/promises");
1585
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1586
+ promptImpl = (q) => rl.question(q);
1587
+ } else {
1588
+ promptImpl = async () => {
1589
+ throw new Error(
1590
+ "[fulgurjs:create] \u5F53\u524D\u4E0D\u662F\u4EA4\u4E92\u7EC8\u7AEF\uFF0C\u7F3A\u5C11\u6A21\u677F\u53C2\u6570\u3002\n \u4FEE\u6CD5\uFF1A\u663E\u5F0F\u4F20\u6A21\u677F\u4E0E\u76EE\u5F55\uFF0C\u4F8B\u5982 fulgurjs create vue-vue --dir my-federation\uFF08--no-install \u53EF\u8DF3\u8FC7\u5B89\u88C5\uFF09"
1591
+ );
1592
+ };
1593
+ }
1594
+ try {
1595
+ await createProject2(
1596
+ {
1597
+ template: argv[1] && !argv[1].startsWith("-") ? argv[1] : void 0,
1598
+ dir: argOf("--dir"),
1599
+ install: !has("--no-install"),
1600
+ force: has("--force"),
1601
+ json: has("--json"),
1602
+ templatesRoot: resolveTemplatesRoot2(import.meta.url),
1603
+ cwd: process.cwd()
1604
+ },
1605
+ { log: (m) => console.log(m), error: (m) => console.error(m), prompt: promptImpl, install: defaultInstall2 }
1606
+ );
1607
+ return 0;
1608
+ } catch (e) {
1609
+ console.error(String(e.message ?? e));
1610
+ return 2;
1611
+ }
1612
+ }
1315
1613
  if (cmd === "explain" || cmd === "check-pages") {
1316
1614
  if (has("--app")) {
1317
1615
  console.error(