# daoos-workbench **Repository Path**: daoos_admin/daoos-workbench ## Basic Information - **Project Name**: daoos-workbench - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-10 - **Last Updated**: 2026-10-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Daoos Workbench 一个不绑定 Vue 和 React 的前端「编译后插件组装管理平台」:输入是各框架编译出的插件产物,平台统一完成发现(registry)、装载(懒激活/级联)、治理(semver 服务契约)、组装(布局+贡献点)与卸载。本仓库提供 Vue 宿主示例(demo)、React 壳宿主示例(demo-react)与完整的 TypeScript 工具链。 > **注意** > 核心通过 `ILayoutEngine` 契约与具体渲染/布局实现解耦;Dockview 只是默认引擎之一,可按需替换。 > **安全说明(务必阅读)** > 平台**不做沙箱**:插件与宿主**同源同权同线程**,插件代码可访问宿主 DOM、`localStorage` > 与全局对象(审计实测 `install` 内可写 `globalThis`)。信任模型 = **仅安装受信插件**; > 插件作用域、`global:` 数据命名空间、API 代理都是**便利层而非权限边界**。攻击面清单、 > 缓解措施当前状态、CSP 指引与漏洞报告方式见 [SECURITY.md](SECURITY.md)。不受信第三方 > 插件生态需要真沙箱(iframe/Worker/ShadowRealm),**当前版本明确不支持**。 ## ✨ 核心特性 - **🔌 动态插件系统**: 支持运行时通过URL动态加载/卸载插件,卸载时自动级联处理依赖方 - **⚡ 懒激活机制**: 参考 VSCode 的 `activationEvents` 设计,插件声明触发条件(命令/视图/布局/事件),命中前不加载任何代码 - **🔗 服务依赖管理**: 插件间通过 `service`/`inject` 声明服务契约,支持 semver 版本校验(`VERSION_MISMATCH` 快速失败)与缺失依赖的自动级联加载 - **🎛️ 可视化面板**: 基于中立布局引擎契约的多容器拖拽式面板布局系统,默认使用 Dockview 实现,支持声明式布局定义与运行时切换 - **🧩 声明式贡献点**: 清单中声明组件/命令/视图/菜单,由核心在激活时自动注册 - **🧱 框架中立渲染层**: 内核不依赖任何前端框架,组件经 `RendererAdapter` 契约由 `@daoos/renderer-*` 适配包解释(已含 Vue 3 与 React 适配器;同框架走原生快路径,异框架面板经适配器桥接渲染;新增框架只需新写适配器) - **🔄 事件通信**: 基于 mitt 的轻量级事件总线,支持作用域隔离与通配监听(作用域缺省按插件名限定,是便利机制而非权限边界,见 [SECURITY.md](SECURITY.md)) - **🎨 UI 服务与设计令牌**: 组件库(TinyVue)封装为 `ui` 服务提供者插件,官方多套主题经设置面板统一切换;`--vpa-*` 设计令牌映射组件库变量,任意插件的视觉随主题自动跟随 - **🛡️ 类型安全**: 完整的 TypeScript 类型系统 - **📦 ImportMap机制**: 统一开发和生产环境的模块解析,支持远程插件加载 ## 📁 项目架构 ``` daoos-workbench/ ├── docs/ # 项目文档 ├── packages/ # 平台代码(按层分层) │ ├── foundation/ # 📁 基础层(纯契约/纯实现,零框架依赖) │ │ ├── types/ # 共享类型定义包(纯契约,零框架依赖) │ │ └── layout-dockview/ # 布局引擎实现(ILayoutEngine 的 dockview 实现) │ │ │ ├── framework/ # 📁 框架层(平台运行时与构建工具链) │ │ ├── core/ # 核心运行时包(零框架依赖) │ │ │ └── src/ │ │ │ ├── plugin/ # 插件管理器 │ │ │ ├── layout/ # 布局管理器 │ │ │ ├── renderer/ # 渲染适配器注册表(按 framework 解析) │ │ │ ├── event/ # 事件总线 │ │ │ ├── data/ # 数据服务 │ │ │ ├── proxy/ # 服务代理 │ │ │ └── error/ # 错误处理 │ │ │ │ │ ├── renderer-vue/ # 📁 Vue 3 渲染适配层(实现 RendererAdapter 契约) │ │ │ │ │ ├── renderer-react/ # 📁 React 渲染适配层(实现 RendererAdapter 契约) │ │ │ │ │ ├── vite-plugin/ # 📁 Vite 构建插件 │ │ │ └── src/ │ │ │ └── index.ts # 插件主入口(扫描/注册表服务/importMap注入) │ │ │ │ │ └── create-plugin/ # 📁 插件脚手架 CLI(尚未发布到 npm,本地 workspace 使用:pnpm daoos:plugin ) │ │ │ └── plugins/ # 📁 内置插件目录(随平台装配的 5 个) │ ├── plugin-admin/ # 通用模块:插件管理/设置/命令面板(bootstrap 插件) │ ├── plugin-workbench-layout/# 工作台骨架(根布局组件) │ ├── plugin-workbench-views/ # 内置视图(explorer/output/problems等) │ ├── plugin-workbench-ui/ # 菜单/状态栏/主题切换等UI元素 │ └── plugin-ui-tinyvue/ # UI服务提供者(TinyVue封装+官方主题统一切换+设计令牌) │ ├── examples/ # 📁 示例(不参与平台发布) │ ├── hosts/ # 宿主示例应用 │ │ ├── demo/ # 📁 示例应用(Vue 宿主) │ │ │ └── src/ │ │ │ ├── main.ts # 应用入口 │ │ │ ├── App.vue # 主应用组件 │ │ │ ├── storage/ # 内存存储实现(MemoryPluginStorage) │ │ │ └── views/ # 页面视图(仅首页;设置/插件管理已抽为 @daoos/plugin-admin) │ │ │ │ │ ├── demo-react/ # 📁 React 壳宿主页(主适配器 React + Vue 插件桥接) │ │ │ └── src/ │ │ │ ├── main.tsx # 入口:createPluginManager(React 主适配器) │ │ │ ├── App.tsx # 壳骨架 + bootstrap 引导序列 │ │ │ ├── dockview-content.ts # dockview-core createComponent → 适配器 mount 桥 │ │ │ └── vue-adapter.ts # Vue 附带适配器(i18n 垫片) │ │ │ │ │ ├── demo-mixed-vue/ # 📁 Vue 壳混载 demo(同屏 Vue + React 面板,端口 5715/5718) │ │ │ │ │ └── demo-mixed-react/ # 📁 React 壳混载 demo(同屏 React + Vue 面板,端口 5716) │ │ │ └── plugins/ # 📁 示例插件目录(教程/演示向的 8 个) │ ├── plugin-helloworld/ # 服务提供示例(被依赖时级联加载) │ ├── plugin-greeter/ # 懒激活+服务消费示例 │ ├── plugin-react-demo/ # React插件演示(framework:react,中心面板+custom zone 视图,react不打进产物) │ ├── plugin-layout-standard/ # 标准布局方案 │ ├── plugin-layout-minimal/ # 极简布局方案 │ ├── plugin-layout-ribbon/ # Ribbon 功能区布局方案 │ ├── plugin-layout-collab/ # 协作功能演示 │ └── plugin-layout-admin/ # 管理面板演示 │ ├── e2e/ # Playwright e2e(端到端验收) ├── scripts/ # 构建/验收/变体脚本 ├── pnpm-workspace.yaml # pnpm 工作空间配置(分层 glob) └── package.json # 根目录包配置 ``` ### 结构说明 | 包名 | 所在目录 | 描述 | 主要功能 | | ------------------------- | -------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------- | | `@daoos/types` | `packages/foundation/types` | 类型定义包 | 共享 TypeScript 类型定义与 `RendererAdapter` 渲染契约、`PluginManifest`(含 `framework` 字段) | | `@daoos/renderer-vue` | `packages/framework/renderer-vue` | Vue 适配包 | 实现 `RendererAdapter`:DynamicPanel(同/异框架双分支)、懒激活占位、异步组件映射、DOM 挂载 | | `@daoos/renderer-react` | `packages/framework/renderer-react` | React 适配包 | 实现 `RendererAdapter`:ReactDynamicPanel、懒激活占位、`React.lazy` 映射、`createRoot` 挂载 | | `@daoos/core` | `packages/framework/core` | 核心运行时包 | 插件管理、懒激活、依赖级联、布局管理、事件通信、数据服务(零框架依赖) | | `@daoos/layout-dockview` | `packages/foundation/layout-dockview` | 布局引擎实现 | `ILayoutEngine` 的 dockview 实现:`createDockviewLayoutEngine()`,经 `options.layoutEngine` 注入 | | `@daoos/vite-plugin` | `packages/framework/vite-plugin` | Vite 构建插件 | 插件扫描(透传 `framework` 等字段)、注册表服务、importMap 注入、热更新支持 | | `@daoos/demo` | `examples/hosts/demo` | 示例应用 | 完整的工作台式插件系统集成示例(Vue 宿主 + React 附加适配器) | | `@daoos/demo-react` | `examples/hosts/demo-react` | React 壳示例 | React 主适配器宿主页:自建 dockview-core 容器装配平台,渲染 Vue 插件(异框架桥)与 React 插件 | | `@daoos/demo-mixed-vue` | `examples/hosts/demo-mixed-vue` | Vue 壳混载示例 | 同屏渲染 Vue + React 面板的 Vue 壳(e2e 端口 5715 / 生产 preview 5718) | | `@daoos/demo-mixed-react` | `examples/hosts/demo-mixed-react` | React 壳混载示例 | 同屏渲染 React + Vue 面板的 React 壳(e2e 端口 5716) | | `@daoos/plugin-*` | `packages/plugins/*`
`examples/plugins/*` | 内置 + 示例插件集 | 工作台骨架、多种布局方案、菜单/Ribbon、插件管理/设置/命令面板(`plugin-admin`)、服务契约与懒激活、React 演示 | > **manifest `framework` 字段**:插件可在 `package.json` 声明 `framework`(如 `"react"`), > 由 vite-plugin 透传进 registry JSON;缺省为 `'vue'`——存量 Vue 插件零改动。宿主在插件激活前 > 按该字段在渲染适配器注册表解析,解析不到即抛 `RENDERER_MISSING` 快速失败。 ## 🚀 快速开始 ### 环境要求 - **Node.js**: >= 20.19.0 (Vite 7 要求) - **包管理器**: pnpm >= 10.0.0 ### 主要命令 ```bash # 开发 pnpm dev # 启动 demo 应用开发服务器 pnpm dev:react # 启动 React 壳宿主页开发服务器(examples/hosts/demo-react) pnpm type-check # 全项目类型检查 pnpm lint # 代码检查 pnpm format # 代码格式化 # 测试与质量门禁(与 CI 同一套) pnpm test # 核心包单元测试(node:test) pnpm test:coverage # 单元测试 + 覆盖率门禁(阈值 69/79/69/58,见 packages/framework/core/package.json) pnpm exec playwright test # E2E(6 个 webServer: 5713-5718 = 4 个 dev + 2 个生产 preview;6 个 project,条数以 `--list` 输出为准) # 构建 pnpm build # 构建所有核心包(含 React 壳) pnpm build:demo # 构建 demo 应用 pnpm build:all # 构建所有包 (包括 demo) # 其他 pnpm daoos:plugin my-feature # 生成插件骨架到 packages/plugins/plugin-my-feature pnpm preview # 预览构建后的 demo 应用 pnpm clean # 清理所有构建产物 ``` ### 示例应用功能 Demo 应用展示了一个 VSCode 风格的工作台: - 🏠 **工作台骨架**: 由 `plugin-workbench-layout` 提供根布局,活动栏/侧栏/底部面板/状态栏齐备 - 🔀 **多布局切换**: 标准 / 极简 / Ribbon 功能区 / 协作 / 管理五种布局方案随时切换 - 🧭 **菜单与命令**: 数据驱动的顶级菜单 + 命令面板(Ctrl+K,mac 为 ⌘K;由 core `KeybindingService` 裁决,见 [docs/keybindings.md](docs/keybindings.md)),命令可触发懒激活插件的动态加载 - 👋 **懒激活演示**: greeter 插件声明 `activationEvents`,点击视图图标或执行命令时才真正加载 - 🔗 **服务契约演示**: greeter 依赖 helloworld 服务(`inject ^1.0.0`),加载 greeter 时自动级联加载 helloworld;版本不匹配则快速失败并在 ProblemsView 报错 - 🎨 **界面主题统一切换**: `plugin-ui-tinyvue` 将 TinyVue 封装为 `ui` 服务(message/alert/confirm + 主题 API),默认/欧若拉/深色/经典四套官方主题在设置面板与 UI 主题视图切换,菜单栏/工具栏/面板经 `--vpa-*` 令牌层即时跟随 - 🔧 **插件管理器**: 运行时查看/加载/卸载插件,观察 pending 等待与反向卸载行为 - ⚛️ **React 插件演示**: `plugin-react-demo` 声明 `framework: react`,经异框架渲染桥在 Vue 宿主渲染——中心面板(`DynamicPanel` 异框架分支)与「React 演示布局」顶部 custom zone 视图(`RendererHost` 异框架分支)均有 e2e 断言(`e2e/dual-framework.spec.ts`:fiber 根 + 计数器交互、生命周期零泄漏、react 运行时单实例);react 运行时经宿主 external/importMap 保证单实例 - 📋 **问题面板**: ProblemsView 汇总展示插件加载错误 ### React 壳示例应用(demo-react) `examples/hosts/demo-react` 是最小 React 宿主页:**主渲染适配器换成 React**,平台装配与插件 加载链路完全不变,证明平台与宿主框架解耦(双向异框架): - ⚙️ **接线**: `createReactRenderer()` 主适配器 + `createDockviewLayoutEngine()` 布局引擎 + `renderers: [Vue 附带适配器]`;引导序列与 demo 相同(registry → `bootstrapOrder` 加载 → `activationEvents` 懒登记),宿主不感知插件名 - 🧩 **自建 dockview 容器**: 壳直接用 `dockview-core` 的 `createDockview` 建中心面板区, `createComponent` 回调把引擎请求转成 `RendererAdapter.mount`(见 `dockview-content.ts`), ready 后 `attachLayout('center', api)` 交回 core - 🔀 **双向桥接**: React 插件(`plugin-react-demo`)同框架直渲;Vue 插件 (`plugin-helloworld`)经 `ReactDynamicPanel` 异框架分支挂载,`.daoos-foreign-panel` 断言进 e2e(`e2e/demo-react.spec.ts`,端口 5714) - 📦 **单实例**: react/dockview-core 走与 demo 同款的 external + staticTargets + importMap paths(`scripts/build-react-libs.mjs` 先把 CJS react 打成 ESM) ## 📖 使用指南 ### 在现有项目中集成 #### 1. 安装依赖 > **发布状态(如实说明)**:`@daoos/*` **当前未发布至公共 npm**——`registry.npmjs.org` 上 > `@daoos/types` / `core` / `renderer-vue` / `renderer-react` / `layout-dockview` / > `vite-plugin` / `create-plugin` 7 个包实测均为 **404**,所以下面的 `pnpm add @daoos/*` > **今天执行会失败**。发布通道(公共 npm 或自建私有源)**待定**。当前可用方式:本仓库是 > pnpm workspace,包之间以 `workspace:*` 互引;外部项目可先用 git 依赖 / 本地 `link:` > 接入。通道确定后本节会同步更新。 ```bash # 以下为发布通道可用后的写法(当前未上线,先不要执行) # 核心依赖(渲染适配层与布局引擎按宿主选择, Vue 宿主如下) pnpm add @daoos/types @daoos/core @daoos/vite-plugin @daoos/renderer-vue @daoos/layout-dockview # 必需的第三方依赖 pnpm add dockview-vue mitt vue # 可选: 宿主要装载 React 插件时追加 pnpm add @daoos/renderer-react react react-dom ``` > **(若重新启用)私有源说明**: `@daoos/*` 曾发布于内部 Nexus 的 `npm-hosted` 仓库,该源 > **已下线**(根目录 `.npmrc`:「私有源已下线,统一使用公网官方源」)。若重新启用,团队 > 成员在用户级 `~/.npmrc` 中配置该源的 scope 映射与访问凭据后即可安装;仓库文件本身不 > 包含任何 registry 地址或密钥。 #### 2. 配置 Vite 插件 ```typescript // vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { vuePluginArch, VuePluginArchOptions } from '@daoos/vite-plugin' const createVuePluginArchConfig = (isDev: boolean): VuePluginArchOptions => { const options: VuePluginArchOptions = { workspace: { root: path.resolve(__dirname, '../..'), pluginsDir: ['packages/plugins', 'examples/plugins'], }, registry: { endpoint: '/api/plugin-registry.json', staticPath: 'public/api/plugin-registry.json', }, build: { copyPluginDist: !isDev, enableImportMap: !isDev, }, } // 仅在构建模式下配置外部依赖和 importMap if (!isDev) { options.external = { deps: ['vue', 'vue-i18n'], staticTargets: [ { src: 'node_modules/vue/dist/vue.esm-browser.prod.js', dest: 'libs', rename: 'vue.js', }, { src: 'node_modules/vue-i18n/dist/vue-i18n.esm-browser.prod.js', dest: 'libs', rename: 'vue-i18n.js', }, ], paths: { vue: '/libs/vue.js', 'vue-i18n': '/libs/vue-i18n.js', }, } } return options } export default defineConfig(({ command }) => ({ plugins: [ vue(), ...vuePluginArch(createVuePluginArchConfig(command === 'serve')), ], })) ``` > 装载 React 插件时,需把 `react` / `react-dom` 等一并加入 `external.deps`、`staticTargets` > 与 `paths`(与 `vue` 同构,保证跨入口单实例),参考 `examples/hosts/demo/vite.config.ts`。 #### 3. 初始化插件系统 (main.ts) 在你的应用入口文件 (例如 `main.ts`) 中,创建并提供插件管理器。 ```typescript // src/main.ts import 'dockview-vue/dist/styles/dockview.css' // 引入 Dockview 样式 import { createApp } from 'vue' import App from './App.vue' import { createPluginManager } from '@daoos/core' import { createVueRenderer } from '@daoos/renderer-vue' import { createDockviewLayoutEngine } from '@daoos/layout-dockview' import type { IPluginStorage } from '@daoos/types' // 创建一个插件存储实现 (示例:基于内存的存储) class MemoryPluginStorage implements IPluginStorage { private data = new Map>() async get(name: string, key: string): Promise { const pluginData = this.data.get(name) return pluginData?.get(key) } async set(name: string, key: string, value: unknown): Promise { if (!this.data.has(name)) { this.data.set(name, new Map()) } this.data.get(name)!.set(key, value) } async getAll(name: string): Promise> { const pluginData = this.data.get(name) if (!pluginData) { return {} } return Object.fromEntries(pluginData.entries()) } async remove(name: string, key: string): Promise { const pluginData = this.data.get(name) if (pluginData) { pluginData.delete(key) } } async removeAll(name: string): Promise { this.data.delete(name) } async clear(): Promise { this.data.clear() } } const app = createApp(App) // 创建存储实现 const storage = new MemoryPluginStorage() // 可选: 构建服务目录(服务名 → 提供者清单), 供依赖自动级联加载 const serviceDirectory = new Map() fetch('/api/plugin-registry.json') .then(res => res.json()) .then((registry: PluginRegistryManifest) => { for (const plugin of registry.plugins) { for (const service of plugin.services ?? []) { const name = typeof service === 'string' ? service : service.name serviceDirectory.set(name, plugin) } } }) // 创建插件管理器: 第一参必须是 RendererAdapter(裸 Vue App 直传已不再支持) const pluginManager = createPluginManager(createVueRenderer(app), storage, { // 布局引擎必填注入, 例如 dockview 实现(由 @daoos/layout-dockview 提供) layoutEngine: createDockviewLayoutEngine(), // 可选: 附加渲染适配器; 插件按 manifest.framework(缺省 'vue')解析, // 解析不到在激活前抛 RENDERER_MISSING // renderers: [createReactRenderer()], // 生产模式下给动态 import 的模块 URL 追加时间戳, 规避缓存 enableModuleCacheBust: !import.meta.env.DEV, // 服务目录: inject 声明的服务缺失时, 据此找到提供者并级联加载 resolveProvider: service => serviceDirectory.get(service), }) // 将插件管理器提供给整个应用 app.provide('pluginManager', pluginManager) app.mount('#app') ``` > **从旧版迁移**: > > 1. `createPluginManager(app, ...)`(直传 Vue App)已不再支持——先显式创建适配器: > `createPluginManager(createVueRenderer(app), storage, options)`;直传裸 App 会抛出带迁移指引的错误。 > 2. `options.layoutEngine` 改为**必填**——注入布局引擎,例如 `createDockviewLayoutEngine()`。 > 3. 装载异框架插件时,经 `options.renderers` 注册附加适配器(如 `[createReactRenderer()]`)。 #### 4. 搭建工作台骨架 推荐像 demo 一样,把页面骨架交给一个布局插件(`plugin-workbench-layout`)提供:宿主启动时按 `bootstrapOrder` 加载 bootstrap 插件,再从组件注册表取出根布局组件渲染。 ```vue ``` 骨架内部通过 `layoutManager.attachLayout(slot, source)` / `detachLayout(slot)` 接入多个布局容器(中央编辑区 + 左/右/底停靠区),各区域由当前激活布局的 zones 定义驱动渲染。若想最小化集成,也可以只渲染一个 `` 并在 `@ready` 中调用 `pluginManager.layoutManager.attachLayout('center', event.api)`。 ## 🔧 ImportMap 机制详解 ### 工作原理 ImportMap 机制是本系统实现统一插件加载的核心技术,它解决了开发和生产环境下模块解析不一致的问题。 #### 开发模式流程 ```mermaid graph LR A[插件请求] --> B[Vite 开发服务器] B --> C[/@fs/ URL 解析] C --> D[本地文件系统] D --> E[TypeScript/Vue 源码] E --> F[实时编译] F --> G[热重载支持] ``` 1. **插件扫描**: Vite 插件自动扫描 `packages/plugins/`(内置)与 `examples/plugins/`(示例)两个目录 2. **URL 生成**: 为每个插件生成 `/@fs/` 格式的开发 URL 3. **注册表服务**: 提供 `/api/plugin-registry.json` 端点 4. **热重载**: 支持插件源码的实时更新 #### 构建模式流程 ```mermaid graph LR A[构建开始] --> B[外部化依赖] B --> C[复制静态资源] C --> D[生成 importMap] D --> E[注入 HTML] E --> F[插件注册表] F --> G[远程加载支持] ``` 1. **依赖外部化**: 将 Vue 等共享依赖标记为 external 2. **静态资源复制**: 复制外部依赖到 `/libs/` 目录 3. **ImportMap 注入**: 在 HTML 中注入模块路径映射 4. **插件构建**: 复制插件构建产物到 `/plugins/` 目录 5. **注册表生成**: 生成静态插件注册表文件 ### 配置示例 #### HTML 模板配置 ```html Daoos Workbench
``` #### 构建后的 ImportMap ```html ``` ### 插件 URL 格式 #### 开发模式 ```javascript // 本地插件 URL 示例 '/@fs/C:/project/examples/plugins/plugin-helloworld/src/index.ts' ``` #### 构建模式 ```javascript // 本地插件 '/plugins/plugin-helloworld/index.js' // 远程插件 'https://cdn.example.com/plugins/plugin-advanced/v1.2.0/index.js' ``` ### 最佳实践 #### 1. 版本管理 ```javascript // 推荐:包含版本号的远程插件 URL 'https://cdn.example.com/plugins/plugin-name/v1.2.0/index.js' // 避免:无版本号的 URL(缓存问题) 'https://cdn.example.com/plugins/plugin-name/latest/index.js' ``` #### 2. 错误处理 ```javascript // 插件加载错误处理 try { await pluginManager.loadPlugin(manifest) // manifest 含插件 url } catch (error) { console.error(`Failed to load plugin: ${manifest.url}`, error) // 提供降级方案或用户提示; 错误同时会进入 ProblemsView } ``` #### 3. 性能优化 ```javascript // 预加载关键插件 const criticalPlugins = [ '/plugins/plugin-core/index.js', '/plugins/plugin-ui/index.js', ] // 使用 Promise.all 并行加载 await Promise.all(criticalPlugins.map(url => import(url))) ``` ### 插件开发 #### 1. 创建插件包 > 插件可以存在于项目 `packages/plugins`(内置)或 `examples/plugins`(示例)目录中,也可以是独立的仓库,通过 npm/pnpm 安装后即可被识别。 以下是在本仓库中创建插件的示例: ```bash # 一键生成插件骨架(推荐,自动创建 package.json/入口/面板组件) pnpm daoos:plugin my-feature # 或手动创建 mkdir packages/plugins/plugin-my-feature cd packages/plugins/plugin-my-feature ``` > 脚手架可作为 `@daoos/create-plugin` 独立发布——**(若重新启用)** 曾发布至内部 Nexus,其他项目可直接 `pnpm create @daoos/plugin my-feature` 生成同款骨架,依赖声明会自动在 workspace 与 registry 版本间切换。**当前该包未发布至公共 npm(实测 404)**,外部使用请克隆本仓库后 `node packages/framework/create-plugin/index.mjs `。 #### 2. 配置插件清单 (package.json) ```jsonc { "name": "@daoos/plugin-my-feature", "version": "0.1.0", "description": "My awesome feature plugin", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", "icon": "🚀", // 声明式组件: 带 defaultPosition 的组件在激活时自动注册为面板/视图 "components": [ { "name": "MyFeaturePanel", "path": "./components/MyFeaturePanel.vue", "title": "My Feature", "defaultPosition": "center", }, ], // 可选: 插件 UI 框架标识, 缺省 'vue'(存量插件零改动); // React 插件声明 "framework": "react", 激活前宿主据此校验渲染适配器 // "framework": "react", // 可选: 随宿主启动 / 懒激活触发条件 / 服务契约 / 贡献点 // "bootstrap": true, // "activationEvents": ["onCommand:my-feature.run"], // "services": [{ "name": "my-feature", "version": "0.1.0" }], // "contributes": { "commands": [{ "command": "my-feature.run", "title": "Run Feature", "icon": "🚀" }] }, "devDependencies": { "@daoos/types": "workspace:*", }, } ``` #### 3. 实现插件入口 ```typescript // src/index.ts import type { IPluginServiceProxy, PluginAPI, PluginModule } from '@daoos/types' import MyFeaturePanel from './components/MyFeaturePanel.vue' export const install = (proxy: IPluginServiceProxy): PluginAPI => { // 注册面板 const panelId = proxy.layoutApi.registerPanel({ id: 'my-feature-panel', component: MyFeaturePanel, // 组件实例或已注册的组件名 title: 'My Feature', position: 'center', }) return { teardown: async () => { proxy.layoutApi.removePanel(panelId) await proxy.dataApi.removeAll() }, } } export const pluginModule: PluginModule = { install } export default pluginModule ``` #### 4. 创建插件组件 ```vue ``` ## 🌐 兼容性说明 ### ImportMap 机制兼容性 本系统的核心特性 ImportMap 机制在不同环境下的兼容性: #### 浏览器支持 「最低版本」= 本系统**同时**依赖的两项平台能力的下限取高者:**ImportMap**(插件模块解析)与 **`inert`**(命令面板打开时隔离背景,见 `PaletteOverlay`)。只满足其中一项不够。 | 浏览器 | ImportMap 支持 | Dynamic Import | `inert` 支持 | **最低版本** | 备注 | | ------- | -------------- | -------------- | ------------ | ------------ | ----------------------- | | Chrome | ✅ 89+ | ✅ 63+ | ✅ 102+ | **102+** | 推荐使用,CI e2e 覆盖 | | Edge | ✅ 89+ | ✅ 79+ | ✅ 102+ | **102+** | 基于 Chromium | | Firefox | ✅ 108+ | ✅ 67+ | ✅ 112+ | **112+** | 可用,未纳入 CI e2e | | Safari | ✅ 16.4+ | ✅ 11.1+ | ✅ 15.5+ | **16.4+** | 需要较新版本,未纳入 CI | > ⚠️ **验证范围**: CI 仅在 **Chromium** 上执行 Playwright e2e;Firefox / Safari 的版本结论来自 > 平台能力的支持矩阵(下附来源),**没有**经过本仓库的自动化回归验证。跨浏览器问题请先在 > Chromium 复现排除。 来源(2026-03 核实): - ImportMap / Dynamic Import:、 - `inert`: MDN `
` 兼容表(Chrome/Edge 102、Firefox 112、Safari 15.5,Baseline 2023-04) #### 降级策略 对于不支持 ImportMap 的旧版浏览器,可以使用 polyfill: ```html ``` #### 开发环境要求 - **Node.js**: >= 20.19.0 (与 engines 声明一致,Vite 7 要求) - **pnpm**: >= 10.0.0 - **现代浏览器**: 支持 ES2020+ 语法 ### 插件加载模式 #### 开发模式 (Development) - 使用 `/@fs/` URL 直接访问本地文件系统 - 支持 TypeScript 和 Vue 文件的热重载 - 无需 importMap,直接通过 Vite 开发服务器解析 #### 构建模式 (Production) - 注入 importMap 配置到 HTML - 外部依赖复制到 `/libs/` 目录 - 支持远程插件通过 CDN 或外部服务器加载 ### 部署兼容性 #### 静态部署 - 支持 Nginx、Apache 等静态文件服务器 - 需要配置正确的 MIME 类型:`application/javascript` for `.js` files - 建议启用 gzip 压缩以优化加载性能 #### CDN 部署 - 支持将插件部署到 CDN - 需要配置 CORS 头以允许跨域加载 - 建议使用版本化 URL 进行缓存管理 #### 容器化部署 - 支持 Docker 容器化部署 - 兼容 Kubernetes 等容器编排平台 - 支持多实例负载均衡 ## 📦 构建 ```bash # 构建所有核心包 (按依赖顺序) pnpm build # 构建特定包 (等价于 pnpm build) pnpm build:types # 构建类型定义包 pnpm build:core # 构建核心运行时包 pnpm build:vite-plugin # 构建 Vite 插件包 pnpm build:plugins # 构建所有插件包 # 构建示例应用 pnpm build:demo # 构建 demo 应用 pnpm build:all # 构建所有包 (包括 demo) # 清理构建产物 pnpm clean ``` ## 📄 许可证 本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 ## 🔗 相关链接 ### 技术文档 - [Vue 3 文档](https://vuejs.org/) - 前端框架 - [Vite 文档](https://vitejs.dev/) - 构建工具 - [TypeScript 文档](https://www.typescriptlang.org/) - 类型系统 - [pnpm 文档](https://pnpm.io/) - 包管理器 - [Dockview 文档](https://dockview.dev/) - 面板布局系统 - [mitt 文档](https://github.com/developit/mitt) - 事件总线 ### 项目文档 - [📘 使用说明](docs/user-guide.md) - 平台完整使用说明(宿主接入 / 插件开发 / 构建部署 / 混合装载 / 迁移 / 故障排查) - [🔒 安全与信任模型](SECURITY.md) - [🗂️ 仓库布局](docs/repository-layout.md) - 分层目录结构(foundation / framework / plugins / examples)与包归属裁决 - 威胁模型、攻击面清单、缓解措施状态、CSP 指引与漏洞报告 #### 核心架构 - [📋 架构总览](docs/architecture-overview.md) - 系统整体架构设计、核心模块组成和工作流程详解 - [🔌 插件系统](docs/plugin-system.md) - 插件生命周期管理、状态机制和加载流程 - [🎛️ 布局管理](docs/layout-management.md) - 动态面板系统、组件注册机制和渲染流程 #### 开发指南 - [🚀 插件开发指南](docs/plugin-development-guide.md) - 从零开始创建插件的完整教程和最佳实践 - [📚 插件API参考](docs/plugin-api-reference.md) - 插件服务代理接口的详细API文档 - [⚡ Vite插件用法](docs/vite-plugin-usage.md) - 构建工具配置、ImportMap机制和部署策略 #### 核心服务 - [🔄 事件总线](docs/event-bus.md) - 插件间通信机制、作用域管理和事件API - [💾 插件数据服务](docs/plugin-data-service.md) - 数据持久化、作用域隔离和存储适配器 - [⌨️ 快捷键](docs/keybindings.md) - 键串语法、KeybindingService 裁决链、限额与命令面板开合键改轨 #### 无障碍与专项 - [🧩 渲染适配层](docs/renderer-adapter.md) - 实现自己的 `RendererAdapter` / 多适配器解析 - [📐 resize 手柄 a11y](docs/resize-handles-a11y.md) - 命中区(WCAG 2.5.8)与 `aria-valuenow` 口径的两个裁决 ---
**Daoos Workbench** - 让你的应用具备跨框架插件扩展能力 基于开源项目 [vue-plugin-architecture](https://github.com/hllshiro/vue-plugin-architecture) 构建 · Made with ❤️ by hllshiro & daoos_admin