Wujies 无界平台
插件开发advanced

开发指南(贡献者)

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

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

这一页解决的是改平台代码时最容易反复踩的几件事:

你遇到的问题这一页给什么
命令抄了跑不通(路径是旧名)一份逐条核对过的命令清单
测试"全绿"其实一条没跑profile 标签纪律
改了后端但行为没变"改完必须重建 jar"的原因与做法
前端远程应用构建全绿、浏览器里炸五个守门脚本,谁管哪一类
提交前不知道要自检什么一份清单

只要写应用、不改平台代码,看 插件开发 与 跟着 hello 读源码 就够了 —— 本页针对的是平台侧改动 (wujies-admin / wujies-common-* / wujies-modules/* / 插件加载与市场逻辑)。

三个仓库

没有共同 git 根,各自分支、各自提交、各自推送。改一个功能经常要两边都提交。

仓库目录内容当前分支
后端wujies-platform/Java / Spring Boot + 平台 SQL 脚本feature/app-market
宿主前端plus-ui/Vue 3 / Vite,应用市场与远程应用运行时(远程产物落 app-market-dist/)feature/app-market
插件与打包器wujies/wujies-plugins/各应用本体 + 插件前端工程(frontend/<code>-app)+ package.ps1master
两个命名陷阱
  1. wujies-admin 在不同位置指不同东西:wujies-platform/wujies-admin/ 是后端启动模块 (有 pom.xml、产物 wujies-admin.jar);工作区顶层那个 wujies-admin/ 里 只有 app-market-dist/(没有 package.json、没有 src/)。
  2. plus-ui/ 的 package.json 里 name 写的是 wujies-admin —— 这是历史遗留, 它指的是宿主前端,不是那个 Java 模块。判据:有 vite.config.ts / src/ 的就是 plus-ui/, 凡是指向 src/plugins/**、src/views/** 的路径都在这里。

分支名以实际仓库配置为准(上表是核对过的当前值),别照抄旧文档里的 my-main / my-ts —— 那两个名字在仓库里已经不存在。

环境与常用命令

本机没有把 JDK / Maven 加进 PATH,所以先设两个变量。下面的命令都在 wujies-platform/ 下执行(它是 Maven 根)。

$env:JAVA_HOME = "C:\Users\<you>\.jdks\corretto-23.0.2"   # 目标字节码是 JDK 17
$mvn = "C:\Program Files\JetBrains\IntelliJ IDEA 2025.3.3\plugins\maven\lib\maven3\bin\mvn.cmd"

# 全反应堆编译
& $mvn -B -q compile -DskipTests

# 跑应用市场模块的测试(根 pom 默认 skipTests=true,必须显式打开并指定 profile)
& $mvn -pl wujies-modules/wujies-app-market -B test "-DskipTests=false" "-Dprofiles.active=dev"

# 打可运行 jar(改了后端代码必须做这步才生效)
& $mvn -pl wujies-admin -am -B install -DskipTests

# 启动宿主(手工命令;-D 参数的引号不能省 —— PowerShell 会把 -Dloader.path=x 拆成 /path=x)
java "-Dloader.path=plugins-dist" "-Dspring.profiles.active=dev" -jar "wujies-admin\target\wujies-admin.jar"

# 清残留插件 jar(先加 -DryRun 看它准备删什么)
powershell -NoProfile -ExecutionPolicy Bypass -File script\prune\prune-plugins.ps1 -PluginDir plugins-dist
script/prune/start-host.ps1 的路径推断待修,先别直接跑它

脚本在 script/prune/ 下,却用 $root = Split-Path $PSScriptRoot -Parent 推工程根 —— 推出来是 wujies-platform/script,于是去 script\wujies-admin\target\ 找 jar(那里不存在), 转去打包又因为没有 pom.xml 而失败。同目录的 prune-plugins.ps1 不带 -PluginDir 时 去 script\plugins-dist 找,同样找不到(它会静默打印「目录不存在,无需清理」)。 修好后可以恢复推荐 start-host.ps1(它会把上面的清理与启动串起来)。 推导与完整说明见本地联调。

插件侧(在插件仓库根 wujies/wujies-plugins/ 下执行):

# 只构建某个插件的 jar
& $mvn -pl wujies-hello package -DskipTests

# 打完整应用包(自动构建前后端 + 可选签名),这是发布路径
.\package.ps1 -Plugin wujies-hello -SigningKey keys\private.pem
.\package.ps1 -Keygen                      # 只生成密钥对,落到 keys\
只 compile 不会更新 wujies-admin.jar

改了后端代码后只跑 mvn compile(哪怕成功)不会重建那个 fat jar, 于是你测的是旧代码,很容易得出「功能没生效」的错误结论, 然后去改本来是对的实现。下结论前先确认 jar 是新的。

⚠️ 两种直觉做法都会骗你:在 fat jar 顶层找 cn/wujies/...class 找不到 (模块类是嵌套在 BOOT-INF/lib/wujies-<模块>.jar 里的,得到的是假阴性); 看嵌套条目的 LastWriteTime 也见过与内部 class 时间不一致。 可靠做法是把嵌套 jar 抽出来看里面那个 class。

不要在正在运行的 JVM 上跑 mvn install

maven-compiler-plugin 的增量检查会先清空输出目录再全编, 正在运行、按需懒解析类的 JVM 会抛 NoClassDefFoundError。真实发生过。

测试纪律

新增测试必须打标签

根 pom 的 surefire 用 <groups>${profiles.active}</groups> 过滤测试。 没打 @Tag("dev") / @Tag("local") / @Tag("prod") 的测试根本不会被执行。

症状很好认:Tests run 总数没变,但 BUILD SUCCESS —— 看着全绿,其实你的测试没跑。

照抄 wujies-modules/wujies-app-market 下现有测试的写法:三个标签一起打 (例如 PluginMapperRegistrarTest),并且新增后核对一下总数。

要点说明
只用 -pl <模块> 跑相关模块全反应堆 test 很慢,且和本机环境耦合
必须显式 -Dprofiles.active=dev它同时是 Spring profile 与 surefire 的 groups 值
改了注解 / 常量 / 静态初始化 → 先 clean install增量编译按时间戳判"是否需要重编",同一秒内会判定"已是最新"
验证前确认 jar 是新的见上一节

前端守门脚本

改了宿主前端或任一远程应用工程之后跑这几条(在 plus-ui/ 下)。它们都是静态检查, 不需要起服务:

命令管什么
npm run check:remote模板组件能否解析三条路 + 白名单名字是否真在宿主 SDK 里 + 已构建产物的 process.env 残留
npm run check:globals产物里未绑定的自动导入标识符(ESLint no-undef)
npm run check:runtime产物 import 的裸模块名与运行期垫片导出对账
npm run audit:menusC 菜单的 component 能否落到真实页面(按 loadView 的三条路逐条判)
npm run test:market应用市场相关的 vitest 单测(src/plugins/appmarket)

npm run gen:runtime 生成运行期垫片,已挂在 predev / prebuild:dev / prebuild:prod 上自动执行。

构建配置改完必须重新构建

远程产物不进版本库(宿主前端的 .gitignore 里有 app-market-dist/)。 改了 vite.config.ts / 白名单不等于部署里那份 ESM 变了; 单工程构建在插件仓库里执行:pnpm --filter ./frontend/<code>-app run build。

本地联调时产物要让宿主 dev server 能取到 —— 它只从 plus-ui/app-market-dist/remote-apps/ 提供 /remote-apps/**, 所以构建前设 $env:WUJIES_FRONTEND_DIST="<宿主根>\app-market-dist\remote-apps" (不设就落到工程自己的 dist/,自己看得到、宿主看不到)。

提交前的自检清单

  • 新增测试都打了三个 profile 标签,并核对过 Tests run 总数
  • 改了后端 → 重建过 wujies-admin.jar(mvn -pl wujies-admin -am -B install -DskipTests),且确认 jar 里是新的 class
  • 改了某个应用 → 用 package.ps1 重新打过包,并带了 -SigningKey(宿主 security.mode=enforce,未签名的包会被拒绝)
  • 改了前端远程应用 → 重新构建了产物,且五个守门脚本都过
  • 动了菜单 → npm run audit:menus 没有新增死菜单
  • 动了 migrations/ → 没有修改已执行过的脚本(改了摘要会被拒;要变更就新增脚本,见下)
  • 改了 .ps1 → 确认仍是 UTF-8 with BOM(编辑工具写完常常把 BOM 丢掉,PS 5.1 会按 ANSI 解析导致中文乱码)
  • 改了 app.json → 用无 BOM UTF-8 写(带 BOM 会让 Jackson 解析失败)
  • 没有把真实凭据、私钥、线上地址提交进仓库
  • 一个主题一个 commit(历史里有过 12 个文件混在一个 commit 的情况,回溯很痛苦)
  • git status 里没有构建产物:后端仓库的 plugins-dist/ 与插件仓库的 target/、keys/ 都已 gitignore。 两个 dist-packages/(平台仓库与插件仓库各一个)都已是历史目录,保留在 .gitignore 里以防误提交旧二进制; 应用包现在的默认落点在仓库外的 <插件仓库的上一级>\.plugin-dist\<appCode>\<版本>\,git 看不到它 —— 所以一旦 git status 里出现 dist-packages/ 或 .plugin-dist/,说明产物被生成到了别处
已执行过的迁移脚本不能改

平台按 script 名比对 checksum,不一致直接报错拒绝执行。 有存量部署时,「把 01-*.sql 里的数据拆出去」这类改动的正确路径是: 先让存量部署跑对应的修复脚本(删掉那几行账本记录),再升级该应用。 迁移脚本只在 install / upgrade 里跑 —— 光把包传上去不会有任何变化。

文档在哪

位置内容纳入版本管理
website/本站(官方文档站与官网)是
wujies-platform/AGENTS.md约束与「已知坑」清单,权威来源,改代码前扫是
wujies-platform/docs/平台侧设计与方案文档是
wujies/wujies-plugins/docs/人读版开发指南、打包部署教程、AI 操作手册是
工作区外层 docs/松散副本与过程记录(含踩坑总记录 开发问题与解决方案.md)不在任何仓库里
外层 docs/ 没有版本历史

它是三个仓库的共同父目录,本身不是 git 仓库 —— 写进去的东西没人知道、也回溯不了。 要长期保留的内容请放进 wujies-platform/docs/ 或 wujies/wujies-plugins/docs/。

本站的「设计与决策存档」一节列出了这些文档各自什么时候看,见 设计与决策存档。

相关阅读

目录