web-extend-plugin-vue2 0.2.3 → 0.3.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.
package/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export type InterceptRegisterRoutesFn = (ctx: {
37
37
  pluginId: string
38
38
  router: unknown
39
39
  routes: ReadonlyArray<VueRouteConfig>
40
- /** 与默认 `registerRoutes` 相同的包装 + `addRoute` / `addRoutes` */
40
+ /** 与默认 `registerRoutes` 相同的包装 + `router.addRoute` */
41
41
  applyInternalRegister: (routes: VueRouteConfig[]) => void
42
42
  }) => void
43
43
 
@@ -48,7 +48,38 @@ export type AdaptRouteDeclarationsFn = (ctx: {
48
48
  declarations: ReadonlyArray<RouteDeclaration>
49
49
  }) => VueRouteConfig[]
50
50
 
51
+ /** 宿主在 `resolveRuntimeOptions({ hostContext })` 中注入;经浅冻结后由 `hostApi.hostContext` 只读暴露 */
52
+ export type HostContext = Readonly<Record<string, unknown>>
53
+
54
+ export type OnBeforePluginActivateFn = (ctx: {
55
+ pluginId: string
56
+ router: unknown
57
+ pluginRecord: Readonly<Record<string, unknown>>
58
+ }) => void | Promise<void>
59
+
60
+ export type OnAfterPluginActivateFn = (ctx: {
61
+ pluginId: string
62
+ router: unknown
63
+ pluginRecord: Readonly<Record<string, unknown>>
64
+ hostApi: unknown
65
+ }) => void | Promise<void>
66
+
67
+ export type OnPluginActivateErrorFn = (ctx: {
68
+ pluginId: string
69
+ error: unknown
70
+ pluginRecord: Readonly<Record<string, unknown>>
71
+ hostApi: unknown
72
+ }) => void | Promise<void>
73
+
51
74
  /** 宿主传入 `createHostApi` 的 `hostKit`(及 `resolveRuntimeOptions` 中同类字段) */
75
+ /** {@link createVueCliAxiosQuickInstallOptions} / {@link installVueCliAxiosWebPlugins} 的宿主侧依赖 */
76
+ export type VueCliAxiosQuickDeps = {
77
+ request: (config: Record<string, unknown>) => Promise<unknown>
78
+ hostLayoutComponent: unknown
79
+ store?: unknown
80
+ hostContext?: Record<string, unknown>
81
+ }
82
+
52
83
  export type HostKitOptions = {
53
84
  /** `getBridge().request` 允许的URL路径前缀,须以 `/` 开头 */
54
85
  bridgeAllowedPathPrefixes?: string[]
@@ -57,6 +88,8 @@ export type HostKitOptions = {
57
88
  transformRoutes?: TransformRoutesFn
58
89
  interceptRegisterRoutes?: InterceptRegisterRoutesFn
59
90
  adaptRouteDeclarations?: AdaptRouteDeclarationsFn
91
+ /** 由引导流程浅冻结后传入各插件的 `hostApi.hostContext` */
92
+ hostContext?: HostContext
60
93
  }
61
94
 
62
95
  /** `resolveRuntimeOptions` 全量运行时选项(在默认字段基础上的扩展;未列字段见 README) */
@@ -64,7 +97,23 @@ export type WebExtendPluginRuntimeOptions = HostKitOptions &
64
97
  Record<string, unknown> & {
65
98
  manifestBase?: string
66
99
  manifestListPath?: string
100
+ /** 默认 `api`;`static` 时用 `staticManifestUrl` 拉取聚合 JSON,不请求 Java 清单接口 */
101
+ manifestMode?: 'api' | 'static'
102
+ /** 静态清单 URL(绝对或站点内路径),`manifestMode: 'static'` 时必填(或配置环境变量) */
103
+ staticManifestUrl?: string
104
+ /** `manifestMode=api` 且开发环境:API 失败或 `plugins` 为空时是否尝试 `devFallbackStaticManifestUrl`(默认 true) */
105
+ devManifestFallback?: boolean
106
+ /** 开发回退静态清单路径,默认 `/web-plugins/plugins.manifest.json` */
107
+ devFallbackStaticManifestUrl?: string
67
108
  manifestFetchCredentials?: RequestCredentials
109
+ /** 宿主 Layout,传入后自动注册 `pluginMountPath` 壳路由 */
110
+ hostLayoutComponent?: unknown
111
+ /** 插件 URL 前缀,默认 `/plugin` */
112
+ pluginMountPath?: string
113
+ /** 壳路由 meta */
114
+ pluginHostRouteMeta?: Record<string, unknown>
115
+ /** 为 true 时且配置了 `pluginRoutesParentName` + `hostLayoutComponent` 才自动注册壳路由;默认 false */
116
+ ensurePluginHostRoute?: boolean
68
117
  isDev?: boolean
69
118
  webPluginDevOrigin?: string
70
119
  webPluginDevIds?: string
@@ -77,19 +126,27 @@ export type WebExtendPluginRuntimeOptions = HostKitOptions &
77
126
  allowedScriptHosts?: string[]
78
127
  bootstrapSummary?: boolean
79
128
  fetchManifest?: ManifestFetchFn
129
+ /** 插件通过 `hostApi.hostContext` 只读访问(浅冻结拷贝);如 `{ store, i18n }` */
130
+ hostContext?: Record<string, unknown>
131
+ /** 调用 `activator` 之前;抛出异常将跳过该插件并计入失败 */
132
+ onBeforePluginActivate?: OnBeforePluginActivateFn
133
+ /** `activator` 成功返回后 */
134
+ onAfterPluginActivate?: OnAfterPluginActivateFn
135
+ /** `activator` 抛错后;用于埋点/降级,不应再抛错(再抛仅记录 warn) */
136
+ onPluginActivateError?: OnPluginActivateErrorFn
80
137
  }
81
138
 
82
139
  /** 插件 `activator` 收到的宿主 API */
83
140
  export interface HostApi {
84
141
  /** 宿主实现的 Host API 协议版本,与清单 `hostPluginApiVersion` 对齐 */
85
142
  readonly hostPluginApiVersion: string
143
+ /** 宿主注入上下文(`resolveRuntimeOptions.hostContext` 的浅冻结快照);无则 `{}` */
144
+ readonly hostContext: HostContext
86
145
  /**
87
146
  * 动态注册路由。含 PRD 时使用 `componentRef` 树;否则传入 `RouteConfig` 数组。
88
147
  * 流水线:`adaptRouteDeclarations` → `transformRoutes` → `interceptRegisterRoutes` 或默认注册。
89
148
  */
90
149
  registerRoutes(routes: VueRouteConfig[] | RouteDeclaration[]): void
91
- /** 写入全局菜单注册表,按 `order` 升序 */
92
- registerMenuItems(items: Record<string, unknown>[]): void
93
150
  registerSlotComponents(
94
151
  pointId: string,
95
152
  components: Array<{ component: unknown; priority?: number }>
@@ -124,6 +181,29 @@ export type ManifestFetchCacheOptions = {
124
181
  now?: () => number
125
182
  }
126
183
 
184
+ /** 从路由 meta 推导的菜单节点(供宿主侧栏;与 `buildMenuDescriptorsFromRoutes` 配套) */
185
+ export type PluginMenuDescriptor = {
186
+ path: string
187
+ name?: string | symbol
188
+ title: string
189
+ order: number
190
+ pluginId?: string
191
+ icon?: unknown
192
+ permission?: unknown
193
+ hidden?: boolean
194
+ external?: boolean
195
+ children?: PluginMenuDescriptor[]
196
+ }
197
+
198
+ /** 由插件 `RouteConfig` 树生成菜单描述(不含 component) */
199
+ export function buildMenuDescriptorsFromRoutes(
200
+ routes: VueRouteConfig[],
201
+ pluginId?: string
202
+ ): PluginMenuDescriptor[]
203
+
204
+ /** 调试:返回 `registerRoutes` 为该插件登记的顶层 route name */
205
+ export function getRegisteredTopRouteNamesForPlugin(pluginId: string): string[]
206
+
127
207
  /** 命名空间聚合对象,按领域分组 */
128
208
  export const WebExtendPluginVue2: Readonly<{
129
209
  install: (Vue: unknown, router: unknown, options?: WebExtendPluginRuntimeOptions) => Promise<void>
@@ -135,6 +215,7 @@ export const WebExtendPluginVue2: Readonly<{
135
215
  runtimeOptions?: WebExtendPluginRuntimeOptions
136
216
  ) => Promise<void>
137
217
  resolveRuntimeOptions: (user?: WebExtendPluginRuntimeOptions) => WebExtendPluginRuntimeOptions
218
+ ensurePluginHostRoute: (router: unknown, opts: WebExtendPluginRuntimeOptions) => void
138
219
  defaultFetchWebPluginManifest: (ctx: {
139
220
  manifestUrl: string
140
221
  credentials: RequestCredentials
@@ -153,10 +234,17 @@ export const WebExtendPluginVue2: Readonly<{
153
234
  request: (path: string, init?: RequestInit) => Promise<Response>
154
235
  }
155
236
  registries: unknown
237
+ buildMenuDescriptorsFromRoutes: typeof buildMenuDescriptorsFromRoutes
238
+ getRegisteredTopRouteNamesForPlugin: typeof getRegisteredTopRouteNamesForPlugin
156
239
  }>
157
240
  config: Readonly<{
158
241
  defaultWebExtendPluginRuntime: Record<string, unknown>
159
242
  setWebExtendPluginEnv: (env: Record<string, unknown> | null | undefined) => void
243
+ webExtendPluginEnvKeys: Readonly<Record<string, string>>
244
+ defaultManifestFetchCache: Readonly<{ storageKeyPrefix: string; maxEntries: number }>
245
+ defaultManifestMode: string
246
+ routeSynthNamePrefix: string
247
+ peerMinimumVersions: Readonly<{ vue: string; vueRouter: string }>
160
248
  }>
161
249
  constants: Readonly<{ HOST_PLUGIN_API_VERSION: string; RUNTIME_CONSOLE_LABEL: string }>
162
250
  components: Readonly<{ ExtensionPoint: unknown }>
@@ -168,6 +256,12 @@ export const WebExtendPluginVue2: Readonly<{
168
256
  deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
169
257
  extra?: Record<string, unknown>
170
258
  ) => Record<string, unknown>
259
+ createQuickInstallOptions: (
260
+ router: unknown,
261
+ deps: VueCliAxiosQuickDeps,
262
+ extra?: Record<string, unknown>
263
+ ) => Record<string, unknown>
264
+ defaultJavaManifestListPath: string
171
265
  manifestPathForApiBase: (manifestUrl: string, apiBase?: string) => string
172
266
  unwrapManifestBody: (body: unknown) => object | null
173
267
  }>
@@ -176,6 +270,19 @@ export const WebExtendPluginVue2: Readonly<{
176
270
 
177
271
  export const defaultWebExtendPluginRuntime: Record<string, unknown>
178
272
 
273
+ /** 与 `resolveRuntimeOptions` / `build-env` 读取逻辑一致的环境变量键(文档与宿主检索用) */
274
+ export const webExtendPluginEnvKeys: Readonly<Record<string, string>>
275
+
276
+ export const defaultManifestFetchCache: Readonly<{ storageKeyPrefix: string; maxEntries: number }>
277
+
278
+ export const defaultManifestMode: 'api'
279
+
280
+ /** 无 name 的路由由 `createHostApi` 合成的名称前缀 */
281
+ export const routeSynthNamePrefix: string
282
+
283
+ /** 与 package.json peer 下限一致,供 CI / `test:peer-min` 对齐 */
284
+ export const peerMinimumVersions: Readonly<{ vue: string; vueRouter: string }>
285
+
179
286
  /** 拉取清单并依次激活插件;浏览器环境执行 */
180
287
  export function bootstrapPlugins(
181
288
  router: unknown,
@@ -186,6 +293,8 @@ export function bootstrapPlugins(
186
293
  /** 合并默认配置、环境变量与显式传入字段 */
187
294
  export function resolveRuntimeOptions(user?: WebExtendPluginRuntimeOptions): WebExtendPluginRuntimeOptions
188
295
 
296
+ export function ensurePluginHostRoute(router: unknown, opts: WebExtendPluginRuntimeOptions): void
297
+
189
298
  export function defaultFetchWebPluginManifest(ctx: {
190
299
  manifestUrl: string
191
300
  credentials: RequestCredentials
@@ -213,8 +322,25 @@ export function installWebExtendPluginVue2(
213
322
  options?: WebExtendPluginRuntimeOptions
214
323
  ): Promise<void>
215
324
 
325
+ /** Vue CLI + axios 一键安装;默认 `exposeGlobalVue: true` 写入 `window.Vue` */
326
+ export function installVueCliAxiosWebPlugins(
327
+ Vue: unknown,
328
+ router: unknown,
329
+ deps: VueCliAxiosQuickDeps,
330
+ extra?: WebExtendPluginRuntimeOptions & { exposeGlobalVue?: boolean }
331
+ ): Promise<void>
332
+
216
333
  export const ExtensionPoint: unknown
217
334
 
335
+ /** 常见 Java 清单路径段,与 `manifestBase` 拼接 */
336
+ export const defaultVueCliJavaManifestListPath: string
337
+
338
+ export function createVueCliAxiosQuickInstallOptions(
339
+ router: unknown,
340
+ deps: VueCliAxiosQuickDeps,
341
+ extra?: Record<string, unknown>
342
+ ): Record<string, unknown>
343
+
218
344
  export function createVueCliAxiosInstallOptions(
219
345
  deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
220
346
  extra?: Record<string, unknown>
@@ -227,6 +353,8 @@ export const presetVueCliAxios: Readonly<{
227
353
  id: string
228
354
  description: string
229
355
  createInstallOptions: typeof createVueCliAxiosInstallOptions
356
+ createQuickInstallOptions: typeof createVueCliAxiosQuickInstallOptions
357
+ defaultJavaManifestListPath: typeof defaultVueCliJavaManifestListPath
230
358
  manifestPathForApiBase: typeof resolveManifestPathUnderApiBase
231
359
  unwrapManifestBody: typeof unwrapNestedManifestBody
232
360
  }>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-extend-plugin-vue2",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "peerDependencies": {
24
24
  "vue": ">=2.6.14 <3.0.0",
25
- "vue-router": ">=3.2.0 <4.0.0"
25
+ "vue-router": ">=3.5.0 <4.0.0"
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "^7.6.3"
@@ -30,12 +30,19 @@
30
30
  "devDependencies": {
31
31
  "@rollup/plugin-commonjs": "^29.0.2",
32
32
  "@rollup/plugin-node-resolve": "^15.3.0",
33
+ "@rollup/plugin-typescript": "^12.1.2",
34
+ "@types/node": "^22.10.2",
33
35
  "rollup": "^4.28.0",
34
- "vitest": "^2.1.9"
36
+ "tslib": "^2.8.1",
37
+ "typescript": "^5.7.2",
38
+ "vitest": "^2.1.9",
39
+ "vue": "^2.7.16",
40
+ "vue-router": "^3.6.5"
35
41
  },
36
42
  "scripts": {
37
43
  "build": "rollup -c rollup.config.mjs",
38
44
  "test": "vitest run",
45
+ "test:peer-min": "npm install --no-save vue@2.6.14 vue-router@3.5.4 && npm run build && npm test && npm install",
39
46
  "prepublishOnly": "npm run build && npm run test"
40
47
  },
41
48
  "license": "Apache-2.0",