web-extend-plugin-vue2 0.2.3 → 0.2.5

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/README.md CHANGED
@@ -1,105 +1,223 @@
1
- # web-extend-plugin-vue2
2
-
3
- 面向 **Vue 2.6+** 与 **Vue Router 3** 的 Web 插件运行时:浏览器中拉取**插件清单**、加载入口脚本、执行 `activator(hostApi)`,并提供 **`ExtensionPoint`**、菜单/路由注册表与受控 **`getBridge()`**。发布物为预构建的 **`dist/`**(CJS/ESM),类型见根目录 **`index.d.ts`**。
4
-
5
- **Peer:`vue` ^2.6.14 \<3,`vue-router` ^3.2 \<4。**
6
-
7
- ---
8
-
9
- ## 如何使用
10
-
11
- **一键接入**(注册全局 `ExtensionPoint` 并异步拉清单):
12
-
13
- ```js
14
- import { installWebExtendPluginVue2 } from 'web-extend-plugin-vue2'
15
-
16
- installWebExtendPluginVue2(Vue, router, {
17
- manifestBase: '/fp-api', // 或与网关一致的前缀
18
- env: import.meta.env // Vite:可选,便于读取 VITE_*
19
- }).catch(console.warn)
20
- ```
21
-
22
- **Vue CLI + 已有 axios `request`**(清单走宿主登录态):
23
-
24
- ```js
25
- import { installWebExtendPluginVue2, createVueCliAxiosInstallOptions } from 'web-extend-plugin-vue2'
26
- import request from '@/utils/request'
27
-
28
- installWebExtendPluginVue2(Vue, router, createVueCliAxiosInstallOptions({ request })).catch(console.warn)
29
- ```
30
-
31
- **按需组合**(自行注册 `ExtensionPoint`、控制引导时机):
32
-
33
- ```js
34
- import {
35
- bootstrapPlugins,
36
- createHostApi,
37
- resolveRuntimeOptions,
38
- ExtensionPoint
39
- } from 'web-extend-plugin-vue2'
40
-
41
- Vue.component('ExtensionPoint', ExtensionPoint)
42
- const runtime = resolveRuntimeOptions({ manifestBase: '/fp-api' })
43
- bootstrapPlugins(router, (id, r, kit) => createHostApi(id, r, kit), runtime).catch(console.warn)
44
- ```
45
-
46
- 清单请求地址:**`manifestBase` + `manifestListPath`**(默认路径段为 `/api/frontend-plugins`)。工厂请使用 **`(id, r, kit) => createHostApi(id, r, kit)`**,以便 `bridgeAllowedPathPrefixes` 等传入 `hostApi`。
47
-
48
- ---
49
-
50
- ## 主要配置(`resolveRuntimeOptions` / `install` 同源字段)
51
-
52
- | 字段 | 作用 |
53
- |------|------|
54
- | `manifestBase` | 清单服务 URL 前缀(无尾 `/`),默认 `/fp-api` |
55
- | `manifestListPath` | 清单路径段(以 `/` 开头),拼在 `manifestBase` 后 |
56
- | `manifestFetchCredentials` | 拉清单时 `fetch` 的 `credentials`,默认 `include` |
57
- | `fetchManifest` | 自定义清单请求 `(ctx) => Promise<{ ok, data?, error? }>` |
58
- | `bridgeAllowedPathPrefixes` | `hostApi.getBridge().request(path)` 允许的 path 前缀 |
59
- | `allowedScriptHosts` | 允许加载插件脚本的主机名白名单 |
60
- | `isDev` / `webPluginDevOrigin` 等 | 开发态隐式 dev 入口与 SSE,见类型定义 |
61
- | `pluginRoutesParentName` | 插件子路由挂到的**已有**命名父路由 |
62
- | `adaptRouteDeclarations` / `transformRoutes` / `interceptRegisterRoutes` | 路由 PRD 适配与宿主扩展流水线 |
63
-
64
- 环境:Vite 可在入口调用 **`setWebExtendPluginEnv(import.meta.env)`**,或在 options 里传 **`env`**。键名支持 **`VITE_*`** 与等价 **`PLUGIN_*`**(实现内会解析)。
65
-
66
- ---
67
-
68
- ## 功能示例)
69
-
70
- **布局里开槽**(插件通过 `hostApi.registerSlotComponents('your.point.id', [...])` 注入组件):
71
-
72
- ```vue
73
- <ExtensionPoint point-id="app.toolbar.demo" />
74
- ```
75
-
76
- **读全局菜单**(插件 `registerMenuItems` 写入响应式表):
77
-
78
- ```js
79
- import { registries } from 'web-extend-plugin-vue2'
80
- // computed: { menus() { return registries.menus } }
81
- ```
82
-
83
- **路由扩展(宿主)**:在 `resolveRuntimeOptions` 里提供 `transformRoutes` 或 `adaptRouteDeclarations`,插件在 `activator` 第二个参数中取冻结的 **`pluginRecord`**(可含清单里的 `routeDeclarations`)。
84
-
85
- **卸载插件**:
86
-
87
- ```js
88
- import { disposeWebPlugin } from 'web-extend-plugin-vue2'
89
- disposeWebPlugin('com.your.plugin.id')
90
- ```
91
-
92
- ---
93
-
94
- ## API 浏览
95
-
96
- - **具名导出**:与下述命名空间指向同一实现,便于 tree-shaking。
97
- - **`WebExtendPluginVue2`**:`install`、`runtime`(含 `bootstrapPlugins`、`resolveRuntimeOptions`、`wrapManifestFetchWithCache` 等)、`host`、`config`、`constants`、`components`、`presets`(`vueCliAxios`)。
98
-
99
- 更细的签名与说明以 **`index.d.ts`** 为准。
100
-
101
- ---
102
-
103
- ## 仓库
104
-
105
- <https://github.com/xtemplus/extend-plugin-framework/tree/master/web-extend-plugin-vue2> · Apache-2.0
1
+ # web-extend-plugin-vue2
2
+
3
+ 面向 **Vue 2.6+** 与 **Vue Router 3** 的 Web 插件运行时:浏览器中拉取**插件清单**、加载入口脚本、执行 `activator(hostApi)`,并提供 **`ExtensionPoint`**、菜单/路由注册表与受控 **`getBridge()`**。发布物为预构建的 **`dist/`**(CJS/ESM),类型见根目录 **`index.d.ts`**。
4
+
5
+ **Peer:`vue` ^2.6.14 \<3,`vue-router` ^3.5 \<4**(依赖 `router.addRoute`)。**
6
+
7
+ ### 本包 `devDependencies` 里的 `vue` / `vue-router` 会不会和宿主冲突?
8
+
9
+ **不会误入发布物。** 二者在 **`peerDependencies`** 中声明,由**宿主工程安装并解析版本**;本仓库的 **`devDependencies`** 仅用于在本项目内跑 **TypeScript 检查、Vitest、 contributors 本地开发**。打包时 Rollup 将 `peerDependencies` 全部标为 **external**,**不会**把 Vue / Vue Router 打进 `dist/`,运行时使用的仍是宿主 `node_modules` 里那一份。
10
+
11
+ 若仍有顾虑,可这样理解:
12
+
13
+ | 场景 | 说明 |
14
+ |------|------|
15
+ | **宿主正常 npm/yarn/pnpm 安装** | 安装器会按 peer 范围校验/提升,与单一 Vue 实例一致 |
16
+ | **Monorepo / `npm link` / workspace** | 确保工作区根只解析出 **一个** `vue`(避免「双 Vue」);可用包管理器的 `overrides` / `resolutions` 钉版本 |
17
+ | **版本下限** | 本库源码按 peer 下限(Vue 2.6+、Router 3.5+)编写;dev 使用较新 2.7 / 3.6 仅便于类型与本地调试,**不要求**宿主与 dev 完全一致,只要在 peer 范围内即可 |
18
+
19
+ **本地验证 peer 下限**:在本包目录执行 **`npm run test:peer-min`**(临时将 `node_modules` 中的 `vue` / `vue-router` 换为与 `peerMinimumVersions` 一致的版本并执行 build+test,最后 `npm install` 恢复)。仓库已含 **GitHub Actions**(`.github/workflows/WEB_EXTEND_PLUGIN_VUE2.yml`)对 default / min 双矩阵跑 CI。
20
+
21
+ ---
22
+
23
+ ## 如何使用
24
+
25
+ **一键接入**(注册全局 `ExtensionPoint` 并异步拉清单):
26
+
27
+ ```js
28
+ import { installWebExtendPluginVue2 } from 'web-extend-plugin-vue2'
29
+
30
+ installWebExtendPluginVue2(Vue, router, {
31
+ manifestBase: '/fp-api', // 或与网关一致的前缀
32
+ env: import.meta.env // Vite:可选,便于读取 VITE_*
33
+ }).catch(console.warn)
34
+ ```
35
+
36
+ **Vue CLI + 已有 axios `request`**(开箱:`/plugin` 壳路由 + Layout 由框架注册;清单可走 Java,开发态可自动回退 `public/web-plugins/plugins.manifest.json`):
37
+
38
+ **更少样板(推荐)**:自动写入 `window.Vue`(IIFE 插件与 build-kit 约定)、合并 `hostContext`(`router` + 可选 `store`)、默认 `manifestListPath` 为 **`/frontend-plugins`**(与 `VUE_APP_BASE_API` 拼接;若后端为 `/api/frontend-plugins` 请在第 4 参数传 `manifestListPath: '/api/frontend-plugins'`)、`isDev` 与构建环境一致。按需关闭全局 Vue:`{ exposeGlobalVue: false }`。
39
+
40
+ ```js
41
+ import { installVueCliAxiosWebPlugins } from 'web-extend-plugin-vue2'
42
+ import request from '@/utils/request'
43
+ import Layout from '@/layout'
44
+ import store from '@/store'
45
+
46
+ installVueCliAxiosWebPlugins(
47
+ Vue,
48
+ router,
49
+ {
50
+ request,
51
+ hostLayoutComponent: Layout,
52
+ store,
53
+ applyPluginMenuItems: ({ pluginId, items }) => {
54
+ /* 并入宿主侧栏 */
55
+ },
56
+ revokePluginMenuItems: (pluginId) => {
57
+ /* 撤销该插件菜单 */
58
+ }
59
+ },
60
+ { manifestBase: process.env.VUE_APP_BASE_API }
61
+ ).catch((e) => console.warn('[web-plugin] bootstrap failed', e))
62
+ ```
63
+
64
+ 等价于自行组合 `createVueCliAxiosQuickInstallOptions` + `installWebExtendPluginVue2`;仅选项、不要一键安装时:
65
+
66
+ ```js
67
+ import { installWebExtendPluginVue2, createVueCliAxiosQuickInstallOptions } from 'web-extend-plugin-vue2'
68
+
69
+ installWebExtendPluginVue2(
70
+ Vue,
71
+ router,
72
+ createVueCliAxiosQuickInstallOptions(router, { request, hostLayoutComponent: Layout, store }, { manifestBase: process.env.VUE_APP_BASE_API })
73
+ ).catch(console.warn)
74
+ ```
75
+
76
+ **显式逐字段**(与旧版一致,清单路径默认来自 `defaultWebExtendPluginRuntime` / 环境变量):
77
+
78
+ ```js
79
+ import { installWebExtendPluginVue2, createVueCliAxiosInstallOptions } from 'web-extend-plugin-vue2'
80
+ import request from '@/utils/request'
81
+ import Layout from '@/layout'
82
+
83
+ installWebExtendPluginVue2(
84
+ Vue,
85
+ router,
86
+ createVueCliAxiosInstallOptions({ request }, { hostLayoutComponent: Layout })
87
+ ).catch(console.warn)
88
+ ```
89
+
90
+ 默认插件父路由 **`name`** 为 **`__wepPluginHost`**,路径 **`/plugin`**;插件内 `registerRoutes` 使用相对 `path`(如 `plugin-b-sample`)即可,全路径为 `/plugin/...`。自定义:`pluginRoutesParentName`、`pluginMountPath`。
91
+
92
+ **静态清单模式**(无需 Java `frontend-plugins`,将聚合 JSON 放入宿主 `public` 等静态目录):
93
+
94
+ ```js
95
+ installWebExtendPluginVue2(
96
+ Vue,
97
+ router,
98
+ createVueCliAxiosInstallOptions({ request }, {
99
+ manifestMode: 'static',
100
+ staticManifestUrl: '/web-plugins/plugins.manifest.json'
101
+ })
102
+ ).catch(console.warn)
103
+ ```
104
+
105
+ JSON 体与 Java 清单接口一致(含 `hostPluginApiVersion`、`plugins[].id` / `entryUrl` 等),参见设计文档或示例 `plugins.manifest.json`。
106
+
107
+ ### 开发态开箱即用(默认 API + 静态回退)
108
+
109
+ 保持 **`manifestMode` 默认 `api`**、宿主仍只写 `createVueCliAxiosInstallOptions({ request }, { manifestBase, manifestListPath, ... })` 即可。当 **`isDev === true`** 时,若后端清单**请求失败**或 **`plugins` 为空**,框架会**自动**再拉取 **`devFallbackStaticManifestUrl`**(默认 **`/web-plugins/plugins.manifest.json`**)。把该文件放在宿主 **`public/web-plugins/`** 下即可与「不打后端 / 后端无插件」场景联调,无需在业务里切换 `manifestMode`。
110
+
111
+ 插件源码热更新:配置 **`PLUGIN_WEB_PLUGIN_DEV_ORIGIN`**(Vue CLI 推荐 `PLUGIN_*` 进 `process.env`)与 **`PLUGIN_WEB_PLUGIN_DEV_IDS`**(或与 **`VITE_*`** 等价键),与原先隐式 dev 映射行为一致。关闭回退:`devManifestFallback: false` 或环境变量 **`VITE_WEB_PLUGIN_DEV_MANIFEST_FALLBACK=0`**。
112
+
113
+ **按需组合**(自行注册 `ExtensionPoint`、控制引导时机):
114
+
115
+ ```js
116
+ import {
117
+ bootstrapPlugins,
118
+ createHostApi,
119
+ resolveRuntimeOptions,
120
+ ExtensionPoint
121
+ } from 'web-extend-plugin-vue2'
122
+
123
+ Vue.component('ExtensionPoint', ExtensionPoint)
124
+ const runtime = resolveRuntimeOptions({ manifestBase: '/fp-api' })
125
+ bootstrapPlugins(router, (id, r, kit) => createHostApi(id, r, kit), runtime).catch(console.warn)
126
+ ```
127
+
128
+ 清单请求地址:**`manifestBase` + `manifestListPath`**(默认路径段为 `/api/frontend-plugins`)。工厂请使用 **`(id, r, kit) => createHostApi(id, r, kit)`**,以便 `bridgeAllowedPathPrefixes` 等传入 `hostApi`。
129
+
130
+ ---
131
+
132
+ ## 主要配置(`resolveRuntimeOptions` / `install` 同源字段)
133
+
134
+ | 字段 | 作用 |
135
+ |------|------|
136
+ | `manifestBase` | 清单服务 URL 前缀(无尾 `/`),默认 `/fp-api` |
137
+ | `manifestListPath` | 清单路径段(以 `/` 开头),拼在 `manifestBase` 后 |
138
+ | `manifestMode` | 默认 `api`;设为 `static` 时从 `staticManifestUrl` 用浏览器 `fetch` 拉取聚合 JSON(不经后端 list)。环境变量:`VITE_WEB_PLUGIN_MANIFEST_MODE` / `PLUGIN_WEB_PLUGIN_MANIFEST_MODE` |
139
+ | `staticManifestUrl` | 静态聚合清单地址,如 `/web-plugins/plugins.manifest.json`。环境变量:`VITE_WEB_PLUGIN_STATIC_MANIFEST_URL` / `PLUGIN_WEB_PLUGIN_STATIC_MANIFEST_URL` |
140
+ | `devManifestFallback` | 开发态 API 失败或空列表时是否回退静态 JSON(`manifestMode=api` 时默认开启)。`VITE_WEB_PLUGIN_DEV_MANIFEST_FALLBACK` |
141
+ | `devFallbackStaticManifestUrl` | 回退地址,默认 `/web-plugins/plugins.manifest.json`。`VITE_WEB_PLUGIN_DEV_FALLBACK_MANIFEST_URL` |
142
+ | `manifestFetchCredentials` | 拉清单时 `fetch` 的 `credentials`,默认 `include` |
143
+ | `fetchManifest` | 自定义清单请求 `(ctx) => Promise<{ ok, data?, error? }>` |
144
+ | `bridgeAllowedPathPrefixes` | `hostApi.getBridge().request(path)` 允许的 path 前缀 |
145
+ | `allowedScriptHosts` | 允许加载插件脚本的主机名白名单 |
146
+ | `isDev` / `webPluginDevOrigin` 等 | 开发态隐式 dev 入口与 SSE,见类型定义 |
147
+ | `hostLayoutComponent` | 传入后自动注册 `/plugin` + Layout 壳(`addRoute`),无需在宿主路由表手写 `/plugin` |
148
+ | `pluginMountPath` / `pluginHostRouteMeta` / `ensurePluginHostRoute` | 壳路径(默认 `/plugin`)、meta、是否自动注册(默认 true) |
149
+ | `pluginRoutesParentName` | 壳路由的 **name**,插件子项挂在其下;未传且传入 `hostLayoutComponent` 时默认为 **`__wepPluginHost`** |
150
+ | `adaptRouteDeclarations` / `transformRoutes` / `interceptRegisterRoutes` | 路由 PRD 适配与宿主扩展流水线 |
151
+ | `applyPluginMenuItems` / `revokePluginMenuItems` | **菜单**:插件 `registerMenuItems` 仅触发回调,由宿主并入自己的侧栏/权限路由等数据结构;卸载时撤销 |
152
+ | `hostContext` | **依赖注入(推荐)**:普通对象,引导时做**浅拷贝并浅冻结**后挂到 **`hostApi.hostContext`**,插件只读使用 `store` / `router` / 宿主开放 API 等,不污染 `HostApi` 顶层方法名 |
153
+ | `onBeforePluginActivate` / `onAfterPluginActivate` / `onPluginActivateError` | **生命周期**:激活前(可 `throw` 跳过该插件)、成功后、抛错后;便于埋点、门禁、监控,各宿主同一套签名即可接入 |
154
+
155
+ 环境:Vite 可在入口调用 **`setWebExtendPluginEnv(import.meta.env)`**,或在 options 里传 **`env`**。键名支持 **`VITE_*`** 与等价 **`PLUGIN_*`**(实现内会解析)。
156
+
157
+ ### 宿主接入约定(跨项目统一)
158
+
159
+ 1. **菜单**:实现 `applyPluginMenuItems` + `revokePluginMenuItems`,菜单字段→本地侧栏结构的映射留在宿主。
160
+ 2. **宿主能力**:通过 **`hostContext`** 注入(如 `{ store, router, getDict }`),插件内使用 **`hostApi.hostContext.store`**,避免 `Vue.prototype` 魔法与命名冲突。
161
+ 3. **拦截激活**:在 **`onBeforePluginActivate`** 中做权限/租户校验,不通过则 **`throw`**;错误用 **`onPluginActivateError`** 上报,勿在 error 钩子里再抛异常。
162
+
163
+ ---
164
+
165
+ ## 功能示例)
166
+
167
+ **布局里开槽**(插件通过 `hostApi.registerSlotComponents('your.point.id', [...])` 注入组件):
168
+
169
+ ```vue
170
+ <ExtensionPoint point-id="app.toolbar.demo" />
171
+ ```
172
+
173
+ **侧栏菜单**(框架不维护菜单列表;`registries` 仅含扩展点 `slots`):
174
+
175
+ ```js
176
+ // resolveRuntimeOptions / install options 中提供:
177
+ applyPluginMenuItems: ({ pluginId, items }) => {
178
+ // 将 items 映射为宿主侧栏数据结构(如 Vuex、与后端路由同形的树等)
179
+ },
180
+ revokePluginMenuItems: (pluginId) => {
181
+ // 从宿主 state 移除该插件贡献的菜单项
182
+ }
183
+ ```
184
+
185
+ 插件侧仍为 `hostApi.registerMenuItems([{ path, title, order, ... }])`;是否显示、图标、层级样式全部由宿主决定。
186
+
187
+ **宿主上下文(插件读宿主能力)**:
188
+
189
+ ```js
190
+ // install / resolveRuntimeOptions
191
+ hostContext: {
192
+ store,
193
+ router,
194
+ // 仅暴露你愿意让插件调用的键;勿放入密钥
195
+ }
196
+ // 插件 activator 内:hostApi.hostContext.store / .router
197
+ ```
198
+
199
+ **路由扩展(宿主)**:在 `resolveRuntimeOptions` 里提供 `transformRoutes` 或 `adaptRouteDeclarations`,插件在 `activator` 第二个参数中取冻结的 **`pluginRecord`**(可含清单里的 `routeDeclarations`)。
200
+
201
+ **卸载插件**:
202
+
203
+ ```js
204
+ import { disposeWebPlugin } from 'web-extend-plugin-vue2'
205
+ disposeWebPlugin('com.your.plugin.id')
206
+ ```
207
+
208
+ ---
209
+
210
+ ## API 浏览
211
+
212
+ - **具名导出**:与下述命名空间指向同一实现,便于 tree-shaking。
213
+ - **`WebExtendPluginVue2`**:`install`、`runtime`(含 `bootstrapPlugins`、`resolveRuntimeOptions`、`wrapManifestFetchWithCache` 等)、`host`、`config`、`constants`、`components`、`presets`(`vueCliAxios`,含 `createQuickInstallOptions`、`defaultJavaManifestListPath`)。另导出 **`installVueCliAxiosWebPlugins`**(一键安装)。
214
+
215
+ 更细的签名与说明以 **`index.d.ts`** 为准。
216
+
217
+ **默认运行时常量与环境键名**统一在源码 **`src/core/public-config-defaults.ts`**(打包后通过 `defaultWebExtendPluginRuntime`、`webExtendPluginEnvKeys`、`WebExtendPluginVue2.config` 暴露),修改默认值或对照 `VITE_*` 时请只改该文件。
218
+
219
+ ---
220
+
221
+ ## 仓库
222
+
223
+ <https://github.com/xtemplus/extend-plugin-framework/tree/master/web-extend-plugin-vue2> · Apache-2.0