# Halo 黑暗模式插件 — 调查文档 > 调查日期:2026-08-06 > 调查范围:Halo 核心仓库、plugin-starter、create-halo-plugin、dev-skills、theme-vite-starter、插件生态系统 > 目的:为开发 Halo 后台管理面板黑暗模式插件提供技术基础 --- ## 0. 补充调查:create-halo-plugin / dev-skills / theme-vite-starter > 本节为第二轮调查补充(2026-08-06),基于对三个额外仓库的分析。**本节内容优先于第 1-6 节中过时的信息。** ### 0.1 create-halo-plugin — 官方推荐的脚手架工具 **仓库**:https://github.com/halo-dev/create-halo-plugin 这是 Halo 官方推荐的插件创建方式,取代了旧的 `plugin-starter`: ```bash pnpm create halo-plugin pnpm create halo-plugin my-plugin ``` **交互式 CLI 特性**: - 插件名称(遵循 `[a-z0-9][a-z0-9.-]*[a-z0-9]` 规则) - 域名 → 自动生成 Java 包名 - 作者姓名 - 是否包含 UI 项目 - **UI 构建工具选择:Vite 或 Rsbuild** **与 plugin-starter 的关键差异**: | 项目 | plugin-starter (旧) | create-halo-plugin (新) | |------|---------------------|------------------------| | `definePlugin` 导入源 | `@halo-dev/console-shared` | `@halo-dev/ui-shared` | | UI 构建产物目录 | `resources/main/console/` | `resources/main/ui/` | | BOM 版本 | `2.23.0-SNAPSHOT` | `2.25.0` | | DevTools 版本 | `0.6.2` | `0.8.0` | | `halo.version` | `2.23.0-beta.2` | `2.25` | | Maven 仓库 | 含 `Central Portal Snapshots` | 仅 `mavenCentral()` | | 路由导入 | 静态 import | 懒加载 `() => import(...)` | | 代码格式化 | Prettier | ESLint | | SNAPSHOT 依赖 | 是 | **否(仅稳定版)** | ### 0.2 dev-skills — AI Agent 开发技能库 **仓库**:https://github.com/halo-dev/dev-skills 这是 Halo 官方的 Agent Skills 集合,为 AI Agent 提供结构化的领域知识。 **`halo-plugin-dev` 技能** — 涵盖 20+ 参考文档: | 参考文档 | 用途 | |----------|------| | `plugin-structure.md` | 目录结构、前后端布局 | | `plugin-manifest.md` | plugin.yaml 字段、版本约束、依赖 | | `server-lifecycle.md` | BasePlugin start/stop/delete 生命周期 | | `server-extension.md` | 自定义 GVK 扩展、CRUD API | | `server-api.md` | CustomEndpoint、Controller | | `server-shared-beans.md` | 注入 Halo 核心服务 | | `server-security.md` | RBAC 角色模板 | | `ui-entry.md` | definePlugin、routes、菜单配置 | | `ui-build.md` | bundler-kit (Vite/Rsbuild)、产物目录 | | `ui-shared.md` | stores (currentUser, globalInfo)、utils | | `ui-extension-points.md` | Console UI 扩展点(编辑器、附件选择器等) | | `ui-components.md` | @halo-dev/components 组件库 | | `ui-forms.md` | FormKit schema、自定义输入组件 | | `ui-api-request.md` | API client 调用、OpenAPI 客户端生成 | | `ui-tooling.md` | unplugin-icons、UnoCSS 工具链 | | `devtools.md` | haloServer、reload、watch、调试 | | `api-changelog.md` | 各版本 API 变更记录 | | `theme-head-processor.md` | 注入脚本/样式到主题 `
` | | `theme-content-handler.md` | 修改渲染后的 HTML | | `theme-integration.md` | 主题 Finder API、反向代理 | > **实施时**:开发过程中应加载 `halo-plugin-dev` 技能以获取精确的 API 参考。 ### 0.3 theme-vite-starter — 主题开发参考 **仓库**:https://github.com/halo-dev/theme-vite-starter 这是 Halo 主题脚手架,与插件开发不直接相关,但展示了 Halo 生态的以下约定: - 使用 `vite-plus`(Vite 超集,集成 format/lint) - 使用 `@halo-dev/vite-plugin-halo-theme` 构建主题 - `theme.yaml` manifest 格式(`apiVersion: theme.halo.run/v1alpha1`) - `settings.yaml` 用于控制台表单配置 - Agent Skills 嵌入在 `.agents/skills/` 目录 ### 0.4 对设计文档的影响 基于以上新发现,设计文档需要做以下修正: 1. **脚手架工具**:使用 `pnpm create halo-plugin` 而非手动克隆 plugin-starter 2. **`definePlugin` 导入**:从 `@halo-dev/ui-shared` 导入(非 `@halo-dev/console-shared`) 3. **版本目标**:BOM `2.25.0`,DevTools `0.8.0`,Halo `2.25` 4. **UI 产物路径**:`resources/main/ui/`(非 `resources/main/console/`) 5. **路由懒加载**:使用 `() => import(...)` 动态导入 6. **不需要 SNAPSHOT 仓库**:仅 `mavenCentral()` 即可 7. **开发时参考**:善用 `halo-plugin-dev` skill 的参考文档 --- ## 1. Halo 项目概览 ### 1.1 基本信息 | 属性 | 值 | |------|-----| | 仓库 | https://github.com/halo-dev/halo | | 许可 | GPL-3.0 | | 类型 | 全栈 monorepo | | 最新稳定版 | 2.25 | | 当前开发版 | 2.23.0-beta.2(plugin-starter 依赖版本) | ### 1.2 技术栈总览 ``` ┌─────────────────────────────────────────────────────┐ │ HALO 架构图 │ ├─────────────────────────────────────────────────────┤ │ 前端 (ui/) │ │ ├─ console-src/ → 后台管理面板 (Vue 3 + TS) │ │ ├─ uc-src/ → 用户中心 (Vue 3 + TS) │ │ ├─ src/ → 共享代码 (locales/styles/setup) │ │ └─ packages/ → 共享工作空间包 │ │ ├─ api-client → 后端 API 客户端 (生成) │ │ ├─ components → UI 组件库 (Storybook) │ │ ├─ console-shared → definePlugin API │ │ ├─ editor → 富文本编辑器 │ │ ├─ shared → 共享工具 │ │ └─ ui-plugin-bundler-kit → 插件打包工具链 │ ├─────────────────────────────────────────────────────┤ │ 后端 │ │ ├─ api/ → 扩展模型/合约/安全 API │ │ ├─ application/ → 服务/路由/数据迁移 │ │ └─ platform/ → BOM (依赖版本约束) │ │ ├─ application/ → 应用 BOM │ │ └─ plugin/ → 插件 BOM (插件可用的依赖) │ └─────────────────────────────────────────────────────┘ ``` **核心依赖版本:** | 层 | 技术 | 版本 | |----|------|------| | 后端 | Java | 21 | | 后端 | Spring Boot (WebFlux) | 3.x | | 后端 | Gradle | 8.x | | 前端 | Vue | 3.x | | 前端 | TypeScript | 5.x | | 前端 | TailwindCSS | 3.x (含 tailwindcss-themer) | | 前端 | Vite | 6.x | | 前端 | pnpm | 9.x | | 前端 | Pinia | 2.x (状态管理) | | 前端 | Vue Router | 4.x | | 前端 | FormKit | 1.x (表单) | --- ## 2. 插件系统深度分析 ### 2.1 插件生命周期 ```java // 每个插件只有一个主类继承 BasePlugin @Component public class PluginMain extends BasePlugin { public PluginMain(PluginContext pluginContext) { super(pluginContext); } @Override public void start() { // 插件启动 → 注册扩展点、创建资源 } @Override public void stop() { // 插件停止 → 清理资源、取消注册 } } ``` **关键点:** - 插件以 Spring `@Component` 的形式存在 - 通过 `PluginContext` 可以访问 Halo 运行时上下文 - `start()` / `stop()` 是主要的生命周期钩子 - 只允许一个类继承 `BasePlugin` ### 2.2 plugin.yaml 清单 ```yaml apiVersion: plugin.halo.run/v1alpha1 kind: Plugin metadata: name: PluginName # 唯一标识符,后续无法修改 spec: enabled: true requires: ">=2.23.0" # Halo 版本要求 author: name: 作者名 website: https://example.com logo: logo.png homepage: https://github.com/... repo: https://github.com/... issues: https://github.com/.../issues displayName: "插件显示名称" description: "插件描述" license: - name: "GPL-3.0" ``` **关键约束:** - `metadata.name` 设置后不能修改(作为标识符绑定到 API 路由和资源路径) - `spec.requires` 定义最低 Halo 版本 - 版本约束由 `platform/plugin/` BOM 管理 ### 2.3 插件 Gradle 构建系统 ```groovy plugins { id 'java' id "io.freefair.lombok" version "9.2.0" id "run.halo.plugin.devtools" version "0.6.2" // 热重载开发工具 } dependencies { implementation platform('run.halo.tools.platform:plugin:2.23.0-SNAPSHOT') compileOnly 'run.halo.app:api' // 编译时 API testImplementation 'run.halo.app:api' // 测试时可用 } // 前端资源复制到后端 classpath tasks.register('processUiResources', Copy) { from project(':ui').layout.buildDirectory.dir('dist') into layout.buildDirectory.dir('resources/main/console') dependsOn project(':ui').tasks.named('assemble') } ``` **关键点:** - `run.halo.app:api` 是 `compileOnly` — 运行时由 Halo 提供 - 前端构建产物(JS/CSS)被复制到 `resources/main/console/` - DevTools 插件支持 Docker 热重载开发 ### 2.4 插件前端入口系统 ```typescript // ui/src/index.ts — 插件前端唯一入口 import { definePlugin } from '@halo-dev/console-shared' import HomeView from './views/HomeView.vue' import { IconPlug } from '@halo-dev/components' import { markRaw } from 'vue' export default definePlugin({ components: {}, // { [name: string]: Component } — 全局注册组件 routes: [...], // 路由定义(可追加到父路由) extensionPoints: {}, // 扩展点(当前生态尚不成熟) ucRoutes: [...], // 用户中心路由(可选) }) ``` **`definePlugin` 的本质:** 源码显示它是一个**身份函数**(identity function),即 `(x) => x`。这意味着插件配置对象直接传递给 Halo 运行时,没有额外的转换层。这简化了调试但也意味着没有类型强制。 ### 2.5 插件资源加载机制(核心发现) ``` 浏览器加载流程: 1. Halo 后端生成 bundle URL: /apis/api.console.halo.run/v1alpha1/ui-plugins/-/bundle.js?t=