@fulgurjs/federation 6.8.7 → 6.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.en.md +3 -0
  3. package/README.md +3 -0
  4. package/dist/application-core-BuhXQmLF.d.cts +16 -0
  5. package/dist/application-core-DWI3eKme.d.ts +16 -0
  6. package/dist/bridge-app-react.cjs +177 -9
  7. package/dist/bridge-app-react.d.cts +15 -3
  8. package/dist/bridge-app-react.d.ts +15 -3
  9. package/dist/bridge-app-react.js +101 -9
  10. package/dist/bridge-app-vue.cjs +138 -12
  11. package/dist/bridge-app-vue.d.cts +20 -5
  12. package/dist/bridge-app-vue.d.ts +20 -5
  13. package/dist/bridge-app-vue.js +62 -12
  14. package/dist/bridge-host-react.d.cts +1 -1
  15. package/dist/bridge-host-react.d.ts +1 -1
  16. package/dist/bridge-host-vue.d.cts +1 -1
  17. package/dist/bridge-host-vue.d.ts +1 -1
  18. package/dist/chunk-6OB47FSR.js +81 -0
  19. package/dist/cli.js +349 -23
  20. package/dist/index.cjs +7 -6
  21. package/dist/index.js +7 -6
  22. package/dist/react-adapter.d.cts +1 -1
  23. package/dist/react-adapter.d.ts +1 -1
  24. package/dist/react.d.ts +29 -4
  25. package/dist/react.js +1 -0
  26. package/dist/{remote-types-xf1B6_pK.d.ts → remote-types-COmBhjRc.d.ts} +1 -1
  27. package/dist/{remote-types-58hdbx6x.d.cts → remote-types-CStGOJwu.d.cts} +1 -1
  28. package/dist/runtime.js +1 -1
  29. package/dist/vue-adapter.d.cts +1 -1
  30. package/dist/vue-adapter.d.ts +1 -1
  31. package/dist/vue-store.cjs +40 -0
  32. package/dist/vue-store.d.cts +4 -0
  33. package/dist/vue-store.d.ts +4 -0
  34. package/dist/vue-store.js +15 -0
  35. package/dist/vue.d.ts +37 -6
  36. package/dist/vue.js +2 -0
  37. package/docs/en/reference/api.md +38 -2
  38. package/docs/en/reference/types.md +27 -0
  39. package/docs/zh/reference/api.md +46 -2
  40. package/docs/zh/reference/types.md +27 -0
  41. package/examples/templates/README.md +3 -0
  42. package/examples/templates/react-host-vue-remote/README.md +24 -0
  43. package/examples/templates/react-host-vue-remote/package.json +2 -1
  44. package/examples/templates/react-host-vue-remote/pnpm-lock.yaml +189 -189
  45. package/examples/templates/react-host-vue-remote/pnpm-workspace.yaml +1 -1
  46. package/examples/templates/react-host-vue-remote/react-host/package.json +1 -1
  47. package/examples/templates/react-host-vue-remote/react-host/src/application.tsx +62 -0
  48. package/examples/templates/react-host-vue-remote/react-host/src/main.tsx +2 -62
  49. package/examples/templates/react-host-vue-remote/scripts/prod.mjs +101 -0
  50. package/examples/templates/react-host-vue-remote/vue-remote/README.md +17 -16
  51. package/examples/templates/react-host-vue-remote/vue-remote/fulgurjs.config.ts +2 -2
  52. package/examples/templates/react-host-vue-remote/vue-remote/package.json +1 -1
  53. package/examples/templates/react-host-vue-remote/vue-remote/src/AboutPage.vue +1 -0
  54. package/examples/templates/react-host-vue-remote/vue-remote/src/App.vue +15 -5
  55. package/examples/templates/react-host-vue-remote/vue-remote/src/HomePage.vue +1 -0
  56. package/examples/templates/react-host-vue-remote/vue-remote/src/application.ts +19 -0
  57. package/examples/templates/react-host-vue-remote/vue-remote/src/main.ts +2 -15
  58. package/examples/templates/react-react/README.md +25 -1
  59. package/examples/templates/react-react/host/package.json +1 -1
  60. package/examples/templates/react-react/host/src/application.tsx +33 -0
  61. package/examples/templates/react-react/host/src/main.tsx +3 -32
  62. package/examples/templates/react-react/package.json +2 -1
  63. package/examples/templates/react-react/pnpm-lock.yaml +123 -123
  64. package/examples/templates/react-react/pnpm-workspace.yaml +1 -1
  65. package/examples/templates/react-react/remote/package.json +1 -1
  66. package/examples/templates/react-react/remote/src/application.tsx +11 -0
  67. package/examples/templates/react-react/remote/src/main.tsx +3 -10
  68. package/examples/templates/react-react/scripts/prod.mjs +101 -0
  69. package/examples/templates/showcase/README.md +35 -7
  70. package/examples/templates/showcase/package.json +2 -1
  71. package/examples/templates/showcase/pnpm-lock.yaml +196 -196
  72. package/examples/templates/showcase/pnpm-workspace.yaml +1 -1
  73. package/examples/templates/showcase/react-host/package.json +1 -1
  74. package/examples/templates/showcase/react-host/src/application.tsx +28 -0
  75. package/examples/templates/showcase/react-host/src/demo-log.ts +5 -8
  76. package/examples/templates/showcase/react-host/src/main.tsx +2 -33
  77. package/examples/templates/showcase/react-host/src/routing.ts +2 -2
  78. package/examples/templates/showcase/react-remote/fulgurjs.config.ts +1 -1
  79. package/examples/templates/showcase/react-remote/package.json +1 -1
  80. package/examples/templates/showcase/react-remote/src/ChildLayout.tsx +3 -2
  81. package/examples/templates/showcase/react-remote/src/{bridge.tsx → application.tsx} +21 -21
  82. package/examples/templates/showcase/react-remote/src/child-bus.ts +23 -23
  83. package/examples/templates/showcase/react-remote/src/main.tsx +2 -18
  84. package/examples/templates/showcase/react-remote/src/pages/Locked.tsx +2 -1
  85. package/examples/templates/showcase/react-remote/src/pages/OrderDetail.tsx +2 -1
  86. package/examples/templates/showcase/react-remote/src/pages/OrderList.tsx +2 -1
  87. package/examples/templates/showcase/scripts/prod.mjs +101 -0
  88. package/examples/templates/showcase/vue-host/package.json +1 -1
  89. package/examples/templates/showcase/vue-host/src/application.ts +28 -0
  90. package/examples/templates/showcase/vue-host/src/demo-log.ts +4 -7
  91. package/examples/templates/showcase/vue-host/src/main.ts +2 -30
  92. package/examples/templates/showcase/vue-host/src/routing.ts +2 -2
  93. package/examples/templates/showcase/vue-remote/fulgurjs.config.ts +1 -1
  94. package/examples/templates/showcase/vue-remote/package.json +1 -1
  95. package/examples/templates/showcase/vue-remote/src/ChildLayout.vue +3 -2
  96. package/examples/templates/showcase/vue-remote/src/{bridge.ts → application.ts} +10 -13
  97. package/examples/templates/showcase/vue-remote/src/child-bus.ts +23 -23
  98. package/examples/templates/showcase/vue-remote/src/main.ts +2 -16
  99. package/examples/templates/showcase/vue-remote/src/pages/Locked.vue +2 -1
  100. package/examples/templates/showcase/vue-remote/src/pages/OrderDetail.vue +2 -1
  101. package/examples/templates/showcase/vue-remote/src/pages/OrderList.vue +2 -1
  102. package/examples/templates/vue-host-react-remote/README.md +24 -0
  103. package/examples/templates/vue-host-react-remote/package.json +2 -1
  104. package/examples/templates/vue-host-react-remote/pnpm-lock.yaml +184 -184
  105. package/examples/templates/vue-host-react-remote/pnpm-workspace.yaml +1 -1
  106. package/examples/templates/vue-host-react-remote/react-remote/README.md +17 -17
  107. package/examples/templates/vue-host-react-remote/react-remote/fulgurjs.config.ts +2 -2
  108. package/examples/templates/vue-host-react-remote/react-remote/package.json +1 -1
  109. package/examples/templates/vue-host-react-remote/react-remote/src/{bridge.tsx → application.tsx} +13 -24
  110. package/examples/templates/vue-host-react-remote/react-remote/src/main.tsx +2 -7
  111. package/examples/templates/vue-host-react-remote/scripts/prod.mjs +101 -0
  112. package/examples/templates/vue-host-react-remote/vue-host/package.json +1 -1
  113. package/examples/templates/vue-host-react-remote/vue-host/src/application.ts +5 -0
  114. package/examples/templates/vue-host-react-remote/vue-host/src/main.ts +2 -4
  115. package/examples/templates/vue-vue/README.md +25 -1
  116. package/examples/templates/vue-vue/host/package.json +1 -1
  117. package/examples/templates/vue-vue/host/src/application.ts +54 -0
  118. package/examples/templates/vue-vue/host/src/main.ts +3 -50
  119. package/examples/templates/vue-vue/package.json +2 -1
  120. package/examples/templates/vue-vue/pnpm-lock.yaml +182 -182
  121. package/examples/templates/vue-vue/pnpm-workspace.yaml +1 -1
  122. package/examples/templates/vue-vue/remote/package.json +1 -1
  123. package/examples/templates/vue-vue/remote/src/application.ts +6 -0
  124. package/examples/templates/vue-vue/remote/src/main.ts +3 -5
  125. package/examples/templates/vue-vue/scripts/prod.mjs +101 -0
  126. package/package.json +14 -9
  127. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote/metadata.json +0 -15
  128. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote/modules.d.ts +0 -14
  129. package/examples/templates/react-host-vue-remote/react-host/src/fulgurjs/types/bridge-vue-remote/registry.d.ts +0 -10
  130. package/examples/templates/react-host-vue-remote/vue-remote/src/bridge.ts +0 -57
  131. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote/metadata.json +0 -16
  132. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote/modules.d.ts +0 -71
  133. package/examples/templates/showcase/react-host/src/fulgurjs/types/vue-remote/registry.d.ts +0 -10
  134. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote/metadata.json +0 -16
  135. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote/modules.d.ts +0 -79
  136. package/examples/templates/showcase/vue-host/src/fulgurjs/types/react-remote/registry.d.ts +0 -10
  137. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote/metadata.json +0 -16
  138. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote/modules.d.ts +0 -10
  139. package/examples/templates/vue-host-react-remote/vue-host/src/fulgurjs/types/bridge-react-remote/registry.d.ts +0 -10
@@ -2,7 +2,7 @@ packages:
2
2
  - host
3
3
  - remote
4
4
  minimumReleaseAgeExclude:
5
- - '@fulgurjs/federation@6.8.5'
5
+ - '@fulgurjs/federation@6.9.0'
6
6
  # pnpm >=12 构建脚本批准(12 起弃用 onlyBuiltDependencies;pnpm 9-11 忽略本键:
7
7
  # esbuild >=0.16 二进制经 optionalDependencies 平台包分发,postinstall 仅校验,不阻塞安装)
8
8
  allowBuilds:
@@ -11,7 +11,7 @@
11
11
  "typecheck": "vue-tsc --noEmit"
12
12
  },
13
13
  "dependencies": {
14
- "@fulgurjs/federation": "6.8.5",
14
+ "@fulgurjs/federation": "6.9.0",
15
15
  "vue": "^3.5.13"
16
16
  },
17
17
  "devDependencies": {
@@ -0,0 +1,6 @@
1
+ import { createApp } from 'vue'
2
+ import { defineApplication } from '@fulgurjs/federation/vue'
3
+ import App from './App.vue'
4
+
5
+ // 普通组件远程不需要额外桥接/路由;独立调试仍由同一应用入口启动。
6
+ export default defineApplication(() => createApp(App))
@@ -1,6 +1,4 @@
1
- import { createApp } from 'vue'
2
- import App from './App.vue'
1
+ import application from './application'
3
2
 
4
- // 独立运行入口:单独开发/调试远程自身时使用。
5
- // 被宿主消费时走的是 fulgurjs-remoteEntry.js 容器入口,与本文件无关。
6
- createApp(App).mount('#app')
3
+ // 独立入口只负责启动;初始化写在 application 中。
4
+ void application.start('#app').catch(console.error)
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ /** Standalone template production launcher. Uses only Node and the existing dev.config.json. */
3
+ import fs from 'node:fs'
4
+ import path from 'node:path'
5
+ import http from 'node:http'
6
+ import { fileURLToPath } from 'node:url'
7
+
8
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
9
+ const { apps } = JSON.parse(fs.readFileSync(path.join(root, 'scripts/dev.config.json'), 'utf8'))
10
+ if (!Array.isArray(apps) || !apps.length) throw new Error('dev.config.json 未登记应用。')
11
+
12
+ const mime = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.woff': 'font/woff', '.woff2': 'font/woff2', '.map': 'application/json' }
13
+ const inside = (file, directory) => file === directory || file.startsWith(directory + path.sep)
14
+ const mounts = apps.map(app => {
15
+ const dir = path.resolve(root, app.dir, 'dist')
16
+ if (!inside(dir, root)) throw new Error(`${app.name}: 构建目录超出模板。`)
17
+ const index = path.join(dir, 'index.html')
18
+ if (!fs.existsSync(index)) throw new Error(`${app.name}: 缺少 dist/index.html,请先 pnpm build。`)
19
+ const html = fs.readFileSync(index, 'utf8')
20
+ const tags = [...html.matchAll(/<script\b[^>]*>/gi)]
21
+ const tag = tags.find(item => /\btype=["']module["']/i.test(item[0]))?.[0]
22
+ const src = tag?.match(/\bsrc=["']([^"']+)["']/i)?.[1]
23
+ if (!src || /^(?:https?:)?\/\//.test(src)) throw new Error(`${app.name}: 无可本地挂载的模块入口。`)
24
+ // Resolve the actual emitted file suffix, rather than guessing base from an app name.
25
+ const pathname = decodeURIComponent(new URL(src, 'http://template.local/').pathname)
26
+ const parts = pathname.split('/').filter(Boolean)
27
+ const bases = []
28
+ for (let i = 0; i < parts.length; i++) {
29
+ const file = path.resolve(dir, ...parts.slice(i))
30
+ if (inside(file, dir) && fs.existsSync(file) && fs.statSync(file).isFile()) bases.push('/' + parts.slice(0, i).join('/') + (i ? '/' : ''))
31
+ }
32
+ if (bases.length !== 1) throw new Error(`${app.name}: 无法唯一对应构建入口 ${src};检查 Vite base 和干净构建输出。`)
33
+ return { ...app, dir, prefix: bases[0] }
34
+ })
35
+ const hosts = mounts.filter(app => app.host)
36
+ if (!hosts.length) throw new Error('dev.config.json 未登记 host:true 的宿主。')
37
+ const ports = new Set()
38
+ const servers = []
39
+ let stopping = false
40
+ function stop(code = 0) {
41
+ if (stopping) return
42
+ stopping = true
43
+ for (const server of servers) server.close()
44
+ const timer = setTimeout(() => {
45
+ for (const server of servers) server.closeAllConnections?.()
46
+ process.exit(code)
47
+ }, 1000)
48
+ timer.unref()
49
+ process.exitCode = code
50
+ }
51
+ process.once('SIGINT', () => stop(0))
52
+ process.once('SIGTERM', () => stop(0))
53
+ process.once('uncaughtException', error => { console.error(error); stop(1) })
54
+
55
+ for (const host of hosts) {
56
+ if (!Number.isInteger(host.port) || host.port < 1 || host.port > 65535 || ports.has(host.port)) throw new Error(`无效或重复宿主端口:${host.port}`)
57
+ ports.add(host.port)
58
+ const site = [host, ...mounts.filter(app => !app.host)].sort((a, b) => b.prefix.length - a.prefix.length)
59
+ const prefixes = new Set()
60
+ for (const app of site) {
61
+ if (prefixes.has(app.prefix)) throw new Error(`${host.name}: 构建 base ${app.prefix} 冲突;宿主和远程不能部署在同一路径。`)
62
+ prefixes.add(app.prefix)
63
+ }
64
+ const server = http.createServer((req, res) => {
65
+ try {
66
+ const url = new URL(req.url, `http://localhost:${host.port}`)
67
+ if (url.pathname === '/' && host.prefix !== '/') {
68
+ res.writeHead(302, { location: host.prefix, 'cache-control': 'no-cache' })
69
+ return res.end()
70
+ }
71
+ const app = site.find(item => url.pathname === item.prefix.slice(0, -1) || url.pathname.startsWith(item.prefix))
72
+ if (!app) { res.writeHead(404); return res.end('未登记此部署路径') }
73
+ const relative = decodeURIComponent(url.pathname.slice(app.prefix.length)) || 'index.html'
74
+ let file = path.resolve(app.dir, relative)
75
+ if (!inside(file, app.dir)) { res.writeHead(403); return res.end() }
76
+ if (!fs.existsSync(file) || fs.statSync(file).isDirectory()) {
77
+ if (path.extname(relative)) { res.writeHead(404); return res.end('资源不存在;不会回退成HTML') }
78
+ file = path.join(app.dir, 'index.html')
79
+ }
80
+ const stable = /(?:^|\/)(?:index\.html|fulgurjs-(?:remoteEntry\.js|manifest\.json)|_app\.config\.js)$/.test(file)
81
+ res.writeHead(200, {
82
+ 'content-type': mime[path.extname(file)] ?? 'application/octet-stream',
83
+ 'cache-control': stable ? 'no-cache' : 'public, max-age=31536000, immutable',
84
+ 'access-control-allow-origin': '*',
85
+ })
86
+ res.end(fs.readFileSync(file))
87
+ } catch (error) {
88
+ console.error(`生产请求失败:${error.message}`)
89
+ if (!res.headersSent) res.writeHead(400)
90
+ res.end('无效请求或资源不可读')
91
+ }
92
+ })
93
+ servers.push(server)
94
+ server.on('error', error => {
95
+ console.error(`${host.name}:${host.port} 启动失败:${error.message};停止本次全部生产服务器,不会按端口杀已有进程。`)
96
+ stop(1)
97
+ })
98
+ server.listen(host.port, '127.0.0.1', () => {
99
+ if (!stopping) console.log(`生产宿主 ${host.name}: http://localhost:${host.port}${host.prefix}(仅dist,无开发服务器)`)
100
+ })
101
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fulgurjs/federation",
3
- "version": "6.8.7",
3
+ "version": "6.9.1",
4
4
  "type": "module",
5
5
  "description": "Vite Module Federation for Vue and React: remote modules, shared dependencies and app bridges.",
6
6
  "license": "MIT",
@@ -81,6 +81,10 @@
81
81
  "./internal/registry.js": {
82
82
  "types": "./types/registry.d.ts",
83
83
  "import": "./types/registry.mjs"
84
+ },
85
+ "./internal/vue-store.js": {
86
+ "types": "./dist/vue-store.d.ts",
87
+ "import": "./dist/vue-store.js"
84
88
  }
85
89
  },
86
90
  "typesVersions": {
@@ -110,15 +114,15 @@
110
114
  "docs/zh/reference/errors.md",
111
115
  "docs/en/reference/api.md",
112
116
  "docs/en/reference/errors.md",
113
- "docs/maintainers/webpack-mf-\u5bf9\u7167\u4e0e\u7f3a\u53e3.md",
114
- "docs/maintainers/\u6c99\u7bb1\u8fb9\u754c\u5ba1\u8ba1.md",
117
+ "docs/maintainers/webpack-mf-对照与缺口.md",
118
+ "docs/maintainers/沙箱边界审计.md",
115
119
  "docs/maintainers/compatibility-testing.md",
116
120
  "docs/zh/reference/types.md",
117
121
  "docs/en/reference/types.md",
118
122
  "types"
119
123
  ],
120
124
  "scripts": {
121
- "build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && mkdir -p docs/zh/reference docs/en/reference docs/maintainers && cp ../../docs/zh/reference/api.md ../../docs/zh/reference/errors.md ../../docs/zh/reference/types.md docs/zh/reference/ && cp ../../docs/en/reference/api.md ../../docs/en/reference/errors.md ../../docs/en/reference/types.md docs/en/reference/ && cp ../../docs/maintainers/webpack-mf-\u5bf9\u7167\u4e0e\u7f3a\u53e3.md ../../docs/maintainers/\u6c99\u7bb1\u8fb9\u754c\u5ba1\u8ba1.md ../../docs/maintainers/compatibility-testing.md docs/maintainers/ && cp ../../CHANGELOG.md CHANGELOG.md && node scripts/sync-package-examples.mjs && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/vue-adapter.ts src/react-adapter.ts src/context.ts src/bridge-core.ts src/bridge-errors.ts src/bridge-session.ts src/bridge-app-vue.ts src/bridge-app-react.ts src/bridge-host-vue.ts src/bridge-host-react.ts --format esm,cjs --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 && tsup src/vue.ts --format esm --dts --external vite,vue,vue-router,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/react.ts --format esm --dts --external vite,react,react-dom,react-router-dom,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/bridge-router-vue.ts --format esm --dts --external vite,vue,vue-router --target node18 && tsup src/bridge-router-react.tsx --format esm --dts --external vite,react,react-dom,react-router-dom --target node18 && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime-entry.mjs && node scripts/check-gzip.mjs && node scripts/check-manual-codes.mjs",
125
+ "build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && mkdir -p docs/zh/reference docs/en/reference docs/maintainers && cp ../../docs/zh/reference/api.md ../../docs/zh/reference/errors.md ../../docs/zh/reference/types.md docs/zh/reference/ && cp ../../docs/en/reference/api.md ../../docs/en/reference/errors.md ../../docs/en/reference/types.md docs/en/reference/ && cp ../../docs/maintainers/webpack-mf-对照与缺口.md ../../docs/maintainers/沙箱边界审计.md ../../docs/maintainers/compatibility-testing.md docs/maintainers/ && cp ../../CHANGELOG.md CHANGELOG.md && node scripts/sync-package-examples.mjs && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/vue-adapter.ts src/react-adapter.ts src/context.ts src/bridge-core.ts src/bridge-errors.ts src/bridge-session.ts src/bridge-app-vue.ts src/bridge-app-react.ts src/vue-store.ts src/bridge-host-vue.ts src/bridge-host-react.ts --format esm,cjs --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 && tsup src/vue.ts --format esm --dts --external vite,vue,vue-router,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/react.ts --format esm --dts --external vite,react,react-dom,react-router-dom,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/bridge-router-vue.ts --format esm --dts --external vite,vue,vue-router --target node18 && tsup src/bridge-router-react.tsx --format esm --dts --external vite,react,react-dom,react-router-dom --target node18 && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime-entry.mjs && node scripts/check-gzip.mjs && node scripts/check-manual-codes.mjs",
122
126
  "dev": "tsup --watch",
123
127
  "test": "vitest run --dir tests",
124
128
  "typecheck": "tsc --noEmit",
@@ -136,23 +140,24 @@
136
140
  "@types/react": "19.3.0",
137
141
  "@types/react-dom": "19.3.0",
138
142
  "jsdom": "^24.0.0",
143
+ "pinia": "3.0.4",
139
144
  "react": "19.3.0",
140
145
  "react-dom": "19.3.0",
146
+ "react-router-dom": "^7.18.4",
141
147
  "tsup": "^8.4.0",
142
148
  "typescript": "^5.8.0",
143
149
  "vitest": "^3.1.0",
144
150
  "vue": "^3.5.22",
145
151
  "vue-router": "^4.6.4",
146
- "react-router-dom": "^7.18.4",
147
152
  "vue-tsc": "^3.3.12"
148
153
  },
149
154
  "peerDependencies": {
150
- "vite": ">=5.1.0",
151
- "vue": ">=3.2.0",
152
155
  "react": ">=18.0.0 <20",
153
156
  "react-dom": ">=18.0.0 <20",
154
- "vue-router": ">=4.1.0 <6",
155
- "react-router-dom": ">=6.11.0 <8"
157
+ "react-router-dom": ">=6.11.0 <8",
158
+ "vite": ">=5.1.0",
159
+ "vue": ">=3.2.0",
160
+ "vue-router": ">=4.1.0 <6"
156
161
  },
157
162
  "pnpm": {
158
163
  "onlyBuiltDependencies": [
@@ -1,15 +0,0 @@
1
- {
2
- "generator": "@fulgurjs/federation",
3
- "ambientFormat": 2,
4
- "alias": "bridge-vue-remote",
5
- "source": "/bridge-vue-remote/fulgurjs-remoteEntry.js",
6
- "revision": "6e2e820a47f98238",
7
- "files": [
8
- "modules.d.ts",
9
- "registry.d.ts"
10
- ],
11
- "externals": [
12
- "@fulgurjs/federation"
13
- ],
14
- "syncedAt": 1791598089894
15
- }
@@ -1,14 +0,0 @@
1
- // 自动生成:fulgurjs-federation 远程类型(remote: bridge-vue-remote,来源: /bridge-vue-remote/fulgurjs-remoteEntry.js,revision: 6e2e820a47f98238)。
2
- // 本文件由插件管理(dev 自动同步 / npx @fulgurjs/federation types),手动修改会被覆盖。
3
- // 外部类型依赖(宿主需可解析):@fulgurjs/federation。
4
- declare module "bridge-vue-remote/bridge" {
5
- /** props 类型:appProps 由宿主传入(label + 稳定回调 onReady) */
6
- export interface BridgeVueProps {
7
- label?: string;
8
- onReady?: () => void;
9
- }
10
- const _default: import("@fulgurjs/federation/vue").BridgeApp & {
11
- __fgBridgeProps?: Record<string, unknown> | undefined;
12
- };
13
- export default _default;
14
- }
@@ -1,10 +0,0 @@
1
- // 自动生成:远程类型注册表(remote: bridge-vue-remote,revision: 6e2e820a47f98238)。
2
- // 向插件共享注册表(internal/registry.js 的 FgRemoteTypes)登记本远程全部公开入口;
3
- // loadRemote / remoteComponent / createVueBridgeApp / createReactBridgeApp 共享该注册表。
4
- import '@fulgurjs/federation/internal/registry.js'
5
-
6
- declare module '@fulgurjs/federation/internal/registry.js' {
7
- interface FgRemoteTypes {
8
- "bridge-vue-remote/bridge": typeof import("bridge-vue-remote/bridge")
9
- }
10
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * Vue 子应用桥接契约(./bridge expose 的默认导出,任务书 §3.3)。
3
- *
4
- * defineBridgeApp 工厂接收 props 快照,返回装配完整的 VueApp——
5
- * 路由、状态库等插件在这里自行装配;挂载/卸载与按容器跟踪由契约负责。
6
- */
7
- import { createApp, defineComponent, h, ref } from 'vue'
8
- import { createMemoryHistory, createRouter, RouterView, useRoute, useRouter } from 'vue-router'
9
- import { defineBridgeApp } from '@fulgurjs/federation/vue'
10
-
11
- /** props 类型:appProps 由宿主传入(label + 稳定回调 onReady) */
12
- export interface BridgeVueProps {
13
- label?: string
14
- onReady?: () => void
15
- }
16
-
17
- const Root = defineComponent({
18
- name: 'BridgeVueRoot',
19
- props: {
20
- label: { type: String, default: '' },
21
- onReady: { type: Function, default: undefined },
22
- },
23
- setup(props) {
24
- const route = useRoute()
25
- const router = useRouter()
26
- const mountTime = ref(new Date().toLocaleTimeString())
27
- props.onReady?.()
28
- return () =>
29
- h('div', { style: 'border:1px solid #42b883;border-radius:8px;padding:12px;font-family:sans-serif' }, [
30
- h('p', { style: 'margin:0 0 6px;font-weight:600;color:#42b883' }, `Vue 子应用(挂载于 ${mountTime.value})`),
31
- h('p', { 'data-testid': 'demo-vue-props', style: 'margin:0 0 6px' }, `appProps.label = ${props.label || '(未传)'}`),
32
- h('p', { 'data-testid': 'demo-vue-route', style: 'margin:0 0 8px' }, `memory 路由:${String(route.path)}`),
33
- h('nav', { style: 'margin-bottom:8px' }, [
34
- h('button', { onClick: () => router.push('/'), style: 'margin-right:8px' }, '首页'),
35
- h('button', { onClick: () => router.push('/about') }, '关于'),
36
- ]),
37
- h(RouterView),
38
- ])
39
- },
40
- })
41
-
42
- const HomePage = defineComponent({ setup: () => () => h('p', { 'data-testid': 'demo-vue-page' }, '页面:首页') })
43
- const AboutPage = defineComponent({ setup: () => () => h('p', { 'data-testid': 'demo-vue-page' }, '页面:关于') })
44
-
45
- export default defineBridgeApp((props) => {
46
- const router = createRouter({
47
- // 子应用内部用 memory 路由(v1 不与宿主 URL 同步,见 README §12)
48
- history: createMemoryHistory(),
49
- routes: [
50
- { path: '/', component: HomePage },
51
- { path: '/about', component: AboutPage },
52
- ],
53
- })
54
- const app = createApp(Root, props)
55
- app.use(router)
56
- return app
57
- })
@@ -1,16 +0,0 @@
1
- {
2
- "generator": "@fulgurjs/federation",
3
- "ambientFormat": 2,
4
- "alias": "vue-remote",
5
- "source": "/vue-remote/fulgurjs-remoteEntry.js",
6
- "revision": "b2f4ac147bf28b93",
7
- "files": [
8
- "modules.d.ts",
9
- "registry.d.ts"
10
- ],
11
- "externals": [
12
- "@fulgurjs/federation",
13
- "vue"
14
- ],
15
- "syncedAt": 1791598119326
16
- }
@@ -1,71 +0,0 @@
1
- // 自动生成:fulgurjs-federation 远程类型(remote: vue-remote,来源: /vue-remote/fulgurjs-remoteEntry.js,revision: b2f4ac147bf28b93)。
2
- // 本文件由插件管理(dev 自动同步 / npx @fulgurjs/federation types),手动修改会被覆盖。
3
- // 外部类型依赖(宿主需可解析):@fulgurjs/federation, vue。
4
- declare module "vue-remote/__internal/src/ChildLayout" {
5
- const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
- export default _default;
7
- }
8
-
9
- declare module "vue-remote/bridge" {
10
- const _default: import("@fulgurjs/federation/vue").BridgeApp & {
11
- __fgBridgeProps?: Record<string, unknown> | undefined;
12
- };
13
- export default _default;
14
- }
15
-
16
- declare module "vue-remote/__internal/src/child-bus" {
17
- /**
18
- * examples/templates/showcase/vue-remote/src/child-bus.ts — 子应用 → 宿主观测台上报总线。
19
- * 宿主经 appProps 传入稳定回调 onChildEvent;本模块持有该引用并维护挂载计数。
20
- * 单页单实例假设:同一宿主页同时只挂一个本子应用实例(路由同步前缀互斥的常规形态)。
21
- */
22
- export type DemoChildNavAction = 'push' | 'replace' | 'go' | 'init';
23
- export type DemoChildEvent = {
24
- type: 'mounted';
25
- mountCount: number;
26
- } | {
27
- type: 'nav';
28
- source: string;
29
- action: DemoChildNavAction;
30
- detail: string;
31
- };
32
- export type DemoChildReporter = (event: DemoChildEvent) => void;
33
- /** 桥接工厂内调用:从 props 快照中取出宿主回调,并上报本次挂载计数 */
34
- export function bindReporter(props: Record<string, unknown> | undefined): void;
35
- /** 导航来源上报(子应用 Link / 子应用 push·replace / 子应用 go / 子应用初始化) */
36
- export function reportNav(source: string, action: DemoChildNavAction, detail: string): void;
37
- export function getMountCount(): number;
38
- }
39
-
40
- declare module "vue-remote/__internal/src/pages/Locked" {
41
- const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
42
- export default _default;
43
- }
44
-
45
- declare module "vue-remote/__internal/src/pages/OrderDetail" {
46
- const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
47
- export default _default;
48
- }
49
-
50
- declare module "vue-remote/__internal/src/pages/OrderList" {
51
- const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
52
- export default _default;
53
- }
54
-
55
- declare module "vue-remote/__internal/src/pages/Settings" {
56
- const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
57
- export default _default;
58
- }
59
-
60
- declare module "vue-remote/__internal/src/settings-store" {
61
- export interface SettingsState {
62
- nickname: string;
63
- notifyEnabled: boolean;
64
- theme: 'light' | 'dark';
65
- }
66
- export const settingsState: {
67
- nickname: string;
68
- notifyEnabled: boolean;
69
- theme: "light" | "dark";
70
- };
71
- }
@@ -1,10 +0,0 @@
1
- // 自动生成:远程类型注册表(remote: vue-remote,revision: b2f4ac147bf28b93)。
2
- // 向插件共享注册表(internal/registry.js 的 FgRemoteTypes)登记本远程全部公开入口;
3
- // loadRemote / remoteComponent / createVueBridgeApp / createReactBridgeApp 共享该注册表。
4
- import '@fulgurjs/federation/internal/registry.js'
5
-
6
- declare module '@fulgurjs/federation/internal/registry.js' {
7
- interface FgRemoteTypes {
8
- "vue-remote/bridge": typeof import("vue-remote/bridge")
9
- }
10
- }
@@ -1,16 +0,0 @@
1
- {
2
- "generator": "@fulgurjs/federation",
3
- "ambientFormat": 2,
4
- "alias": "react-remote",
5
- "source": "/react-remote/fulgurjs-remoteEntry.js",
6
- "revision": "a614927c5da16a52",
7
- "files": [
8
- "modules.d.ts",
9
- "registry.d.ts"
10
- ],
11
- "externals": [
12
- "@fulgurjs/federation",
13
- "react"
14
- ],
15
- "syncedAt": 1791598119923
16
- }
@@ -1,79 +0,0 @@
1
- // 自动生成:fulgurjs-federation 远程类型(remote: react-remote,来源: /react-remote/fulgurjs-remoteEntry.js,revision: a614927c5da16a52)。
2
- // 本文件由插件管理(dev 自动同步 / npx @fulgurjs/federation types),手动修改会被覆盖。
3
- // 外部类型依赖(宿主需可解析):@fulgurjs/federation, react。
4
- declare module "react-remote/__internal/src/ChildLayout" {
5
- import type { ReactElement } from 'react';
6
- export default function ChildLayout(): ReactElement;
7
- }
8
-
9
- declare module "react-remote/bridge" {
10
- const _default: import("@fulgurjs/federation/react").BridgeApp & {
11
- __fgBridgeProps?: Record<string, unknown> | undefined;
12
- };
13
- export default _default;
14
- }
15
-
16
- declare module "react-remote/__internal/src/child-bus" {
17
- /**
18
- * examples/templates/showcase/react-remote/src/child-bus.ts — 子应用 → 宿主观测台上报总线。
19
- * 宿主经 appProps 传入稳定回调 onChildEvent;本模块持有该引用并维护挂载计数。
20
- * 单页单实例假设:同一宿主页同时只挂一个本子应用实例(路由同步前缀互斥的常规形态)。
21
- */
22
- export type DemoChildNavAction = 'push' | 'replace' | 'go' | 'init';
23
- export type DemoChildEvent = {
24
- type: 'mounted';
25
- mountCount: number;
26
- } | {
27
- type: 'nav';
28
- source: string;
29
- action: DemoChildNavAction;
30
- detail: string;
31
- };
32
- export type DemoChildReporter = (event: DemoChildEvent) => void;
33
- /** 桥接工厂内调用:从 props 快照中取出宿主回调,并上报本次挂载计数 */
34
- export function bindReporter(props: Record<string, unknown> | undefined): void;
35
- /** 导航来源上报(子应用 Link / 子应用 push·replace / 子应用 go / 子应用初始化) */
36
- export function reportNav(source: string, action: DemoChildNavAction, detail: string): void;
37
- export function getMountCount(): number;
38
- }
39
-
40
- declare module "react-remote/__internal/src/pages/Locked" {
41
- /**
42
- * examples/templates/showcase/react-remote/src/pages/Locked.tsx — 锁定页(守卫放行后才可见)。
43
- * 前往本页的导航会被宿主守卫(Vue:异步 beforeEach;React:useBlocker)拦截,等待「继续/取消」。
44
- */
45
- import type { ReactElement } from 'react';
46
- export default function Locked(): ReactElement;
47
- }
48
-
49
- declare module "react-remote/__internal/src/pages/OrderDetail" {
50
- /**
51
- * examples/templates/showcase/react-remote/src/pages/OrderDetail.tsx — 工单详情页(路径参数 /orders/:id)。
52
- * 「返回列表」走 go(-1)(委托宿主浏览器历史);「回列表」走 push(经通道写宿主 URL)。
53
- */
54
- import type { ReactElement } from 'react';
55
- export default function OrderDetail(): ReactElement;
56
- }
57
-
58
- declare module "react-remote/__internal/src/pages/OrderList" {
59
- import type { ReactElement } from 'react';
60
- export default function OrderList(): ReactElement;
61
- }
62
-
63
- declare module "react-remote/__internal/src/pages/Settings" {
64
- import type { ReactElement } from 'react';
65
- export default function Settings(): ReactElement;
66
- }
67
-
68
- declare module "react-remote/__internal/src/settings-store" {
69
- /**
70
- * examples/templates/showcase/react-remote/src/settings-store.ts — 设置页本地状态(模块级对象,刻意不写入 URL)。
71
- * 子应用 root 不重挂 → 模块不重建:路由往返后设置仍保留,佐证「内部状态跨路由保留」。
72
- */
73
- export interface SettingsState {
74
- nickname: string;
75
- notifyEnabled: boolean;
76
- theme: 'light' | 'dark';
77
- }
78
- export const settingsState: SettingsState;
79
- }
@@ -1,10 +0,0 @@
1
- // 自动生成:远程类型注册表(remote: react-remote,revision: a614927c5da16a52)。
2
- // 向插件共享注册表(internal/registry.js 的 FgRemoteTypes)登记本远程全部公开入口;
3
- // loadRemote / remoteComponent / createVueBridgeApp / createReactBridgeApp 共享该注册表。
4
- import '@fulgurjs/federation/internal/registry.js'
5
-
6
- declare module '@fulgurjs/federation/internal/registry.js' {
7
- interface FgRemoteTypes {
8
- "react-remote/bridge": typeof import("react-remote/bridge")
9
- }
10
- }
@@ -1,16 +0,0 @@
1
- {
2
- "generator": "@fulgurjs/federation",
3
- "ambientFormat": 2,
4
- "alias": "bridge-react-remote",
5
- "source": "/bridge-react-remote/fulgurjs-remoteEntry.js",
6
- "revision": "7a102c48ed50cb3c",
7
- "files": [
8
- "modules.d.ts",
9
- "registry.d.ts"
10
- ],
11
- "externals": [
12
- "@fulgurjs/federation",
13
- "react"
14
- ],
15
- "syncedAt": 1791598103514
16
- }
@@ -1,10 +0,0 @@
1
- // 自动生成:fulgurjs-federation 远程类型(remote: bridge-react-remote,来源: /bridge-react-remote/fulgurjs-remoteEntry.js,revision: 7a102c48ed50cb3c)。
2
- // 本文件由插件管理(dev 自动同步 / npx @fulgurjs/federation types),手动修改会被覆盖。
3
- // 外部类型依赖(宿主需可解析):@fulgurjs/federation, react。
4
- declare module "bridge-react-remote/bridge" {
5
- export function App(): import("react").JSX.Element;
6
- const _default: import("@fulgurjs/federation/react").BridgeApp & {
7
- __fgBridgeProps?: Record<string, unknown> | undefined;
8
- };
9
- export default _default;
10
- }
@@ -1,10 +0,0 @@
1
- // 自动生成:远程类型注册表(remote: bridge-react-remote,revision: 7a102c48ed50cb3c)。
2
- // 向插件共享注册表(internal/registry.js 的 FgRemoteTypes)登记本远程全部公开入口;
3
- // loadRemote / remoteComponent / createVueBridgeApp / createReactBridgeApp 共享该注册表。
4
- import '@fulgurjs/federation/internal/registry.js'
5
-
6
- declare module '@fulgurjs/federation/internal/registry.js' {
7
- interface FgRemoteTypes {
8
- "bridge-react-remote/bridge": typeof import("bridge-react-remote/bridge")
9
- }
10
- }