Wujies 无界平台
插件开发

插件开发

本文是 1.x 的归档文档(冻结于 1.x)。该分支只接收勘误修正, 内容基本不再变动;文中的源码路径、配置项与版本号均以 1.x 为准,不建议用于新项目。

新项目请查看 5.x 最新文档。已在 1.x 上运行的项目,本文仍是可靠依据。

在 Wujies 无界平台上,一个业务应用就是一个插件。 平台本身不包含业务代码,只负责把插件装进来、跑起来、卸下去。

这一章从「新建一个插件」讲到「打出一个能安装的包」。读完之后,你应该能独立完成: 新建骨架 → 写后端 → 写页面 → 热加载调试 → 打包发布。

只想先跑一遍?

直接看 快速开始,10 分钟做出第一个能调通的插件。 已经装好平台、只想换个方式开发的,看 可视化开发台。

为什么是插件

  • 平台极小,应用外置。 新增业务模块不需要改平台一行 Java 代码,也不需要在平台里新建 *-api 契约模块。
  • 一个应用就是一个自包含工程。 实体、Mapper、Service、Controller、建表脚本、app.json、前端页面, 全在插件仓库自己的目录里。
  • 运行期装载。 宿主用独立的 PluginClassLoader 和子 Spring 上下文加载插件,支持热加载与卸载; 装卸全程不重启宿主。

一个插件由四部分组成

wujies/wujies-plugins/
├── wujies-demo/                       ① 后端工程(Maven 模块)
│   ├── app.json                       ② 应用清单:编码、版本、产物、菜单
│   ├── migrations/                    ③ 数据库迁移:建表 / 种子数据
│   │   └── 01-create-demo-item.sql
│   └── src/main/java/cn/wujies/demo/
│       ├── controller/                HTTP 接口,挂在 /demo/**
│       ├── domain/ + bo/ + vo/        实体与出入参
│       ├── mapper/                    Mapper 接口(XML 随 jar 走)
│       └── service/ + impl/           业务逻辑
└── frontend/demo-app/                 ④ 前端远程应用(pnpm 工程)
    ├── vite.config.ts                 defineRemoteApp({ appCode: 'demo' })
    ├── app.json                       前端侧清单(构建用;菜单以 ② 为准)
    └── src/
        ├── index.ts                   入口契约:install(runtime) → { manifest, views }
        └── views/                     页面组件
部分事实来源说明
后端wujies-<code>/pom.xml依赖平台构件时一律 provided,不要打进 jar
清单wujies-<code>/app.json版本、产物路径、菜单与权限的唯一权威描述
迁移wujies-<code>/migrations/*.sql文件名排序即执行顺序,已执行的脚本不要修改
前端frontend/<code>-app/src/index.ts构建成 ESM,由宿主在运行期 import()

命名只有一条规则:目录名、app.json.code、vite.config.ts 的 appCode、菜单里的 remote:<code>/<viewKey>,四处必须是同一个 <code>。

从零到可安装:五步

#做什么从哪开始
1新建插件骨架(后端 + 前端 + 清单 + 迁移)可视化开发台 或 new-plugin.ps1
2补业务:改实体、接口、迁移脚本后端工程 · 数据库迁移
3写页面:在 views/ 下加 Vue 页面,登记视图键前端远程应用
4联调:后端热加载、前端重建产物快速开始 · 本地联调
5打包:开发包用于联调,正式包用于上架打包应用
热加载不负责「首次安装」

POST /app/dev/reload 只替换后端代码。它不建表、不同步菜单、不部署前端产物。

新插件的表、菜单、权限和前端入口,第一次仍需走一次安装(安装 会执行 migrations/ 并写入 app.json 里的菜单)。装过一次之后,日常迭代就只剩「构建 → 热加载 → 刷新」。 详见开发与安装的边界。

三种创建方式

方式一:可视化开发台(推荐)

宿主后台 「应用上架 → 插件开发」 里点「新建插件」,填编码、名称、版本即可。 服务端会调用插件仓库的 scripts/new-plugin.mjs,自动完成:复制模板、改包名 / 类名 / 表名 / 权限前缀、写 app.json、把模块登记进仓库根 pom.xml。

适合第一次接触、或者不想记命令的人。见可视化开发台。

方式二:命令行

在插件仓库根执行:

# 生成前后端完整骨架
powershell -File new-plugin.ps1 -Code demo -Name "演示应用"

# 只要后端
powershell -File new-plugin.ps1 -Code demo -Name "演示应用" -NoFrontend

生成后的下一步、构建命令和目录说明会直接打印在终端里。

方式三:复制 hello 模板

想照着现成代码改,就把 wujies-hello 复制成 wujies-<code>,再改四处: pom.xml 的 artifactId、app.json 的 code/name/version/menus、Java 包名、表名前缀。 这条路的对照索引见跟着 hello 读源码。

三种方式产物结构一致。不要从业务插件(mall / im / exam)复制——它们带了很多历史包袱, 新应用用 hello 或生成器即可。

日常开发循环

改了什么怎么做怎么生效耗时
后端 Javamvn -pl wujies-<code> -am package -DskipTests开发台「热加载」或 POST /app/dev/reload秒级
前端 Vue构建到宿主 app-market-dist/remote-apps/<code>/刷新浏览器秒级
表结构新增 migrations/NN-*.sql安装 / 升级时执行;开发期可手动执行一次分钟级
菜单 / 权限改 app.json 的 menus安装 / 升级时同步;热加载不碰菜单分钟级
版本 / 产物路径改 app.json重新打包分钟级

热加载只对开了 dev-mode 的宿主可用,并且绕过签名与包校验。它解决的是「改一行代码不想重新上架」, 不是「第一次怎么装」。完整的四条联调路径见本地开发与联调方案。

先记住四条

  1. 平台依赖一律 provided。 Spring、MyBatis、wujies-common-*、兄弟插件构件都不要打进插件 jar, 否则会出现同一个接口两个 Class 对象。
  2. 菜单只能写在 app.json 里。 不要手写 INSERT INTO sys_menu;type: "F" 的按钮也必须声明。 见菜单与权限。
  3. 迁移脚本只增不改。 文件名排序即执行顺序,必须幂等;执行过的脚本内容再改会被摘要校验拒绝。 见数据库迁移。
  4. 宿主看不到插件。 插件能注入宿主,宿主不能注入插件;宿主侧要用插件能力只能走 SPI 或服务定位器。

其余不能违反的细节,见必须遵守的不变量。

本章地图

我想…看这里
10 分钟做出第一个插件快速开始
用后台页面新建、热加载、打开发包可视化开发台
搞清 app.json 每个字段应用清单 app.json
写后端工程后端工程
写前端页面并构建成 ESM前端远程应用
声明菜单与按钮权限菜单与权限
加表 / 改表 / 种子数据数据库迁移 · 种子数据与站点配置
本地跑起来、打断点本地联调
不想每次改一行就打包上传本地开发与联调方案
照着真实源码写跟着 hello 读源码
查某个能力怎么调插件能力速查
把宿主模块抽成插件从宿主模块抽成应用
打包、签名、上架打包应用 · 密钥与签名

相关阅读

目录