概述
系统分两层。核心模块是主宿主:发现模块、按依赖顺序加载,并提供认证、安全、DI、路由、内置数据、菜单与 SPA 核心等基础能力。插件是你编写的应用——库存、POS、HR 等领域的后端 API、数据表与 React 界面。
- 核心 = 模块加载 + 基础平台能力
- 插件 = 写在 plugins/<name>/ 下的应用
- 加载发生在启动 / 浏览器侧,而非编译期单体
- 禁止导入其他插件的 src/
1. 结构示意
运行时产品 = 核心 + 已安装插件。源码在 plugins/,构建在 available-plugins/,核心只加载 installed-plugins/。
- 源码 — plugins/<name>/
- 可用 — base/available-plugins/<name>/<version>/
- 已安装 — base/backend/installed-plugins/<name>/
- 目录名、metadata.name、包身份必须一致
SHproject layout
1base/ # core runtime (Docker)
2├── backend/ # core host process
3│ └── installed-plugins/<name>/ # active plugin copies
4├── frontend/ # SPA core (menus, chrome)
5└── available-plugins/<name>/<ver>/# staged builds
6
7plugins/<name>/ # your plugin app (edit here)
8├── backend/
9├── frontend/
10└── module.metadata.json # identity + dependencies2. module.metadata.json
每个插件根目录都有 module.metadata.json。核心用它读取名称、版本、所需 base 线,以及必须先存在的其他插件。
- name 用于安装行、DI 与依赖映射
- requiredBasedVersion 须对齐运行中的核心
- 重命名或升版本时同步元数据
- 构建产物会带上同一份元数据
| 字段 | 用途 |
|---|---|
| name | 稳定插件 id — 须与目录名 / 安装身份一致 |
| pluginVersion | 本插件 semver |
| description | 模块 / 安装界面说明 |
| moduleEntryObject | 后端入口导出名(通常为 "Module") |
| requiredBasedVersion | 兼容的核心 / @quan-erp/* 版本线 |
| pluginDependencies | 其他插件名 → 须先加载的 semver 范围 |
JSONplugins/inventory/module.metadata.json
1{
2 "name": "inventory",
3 "type": "",
4 "pluginVersion": "1.0.0",
5 "description": "Inventory management",
6 "moduleEntryObject": "Module",
7 "requiredBasedVersion": "1.0.0",
8 "pluginDependencies": {
9 "products": "^1.0.0",
10 "accounting": "^1.0.0"
11 }
12}3. 模块依赖
pluginDependencies 声明本模块需要的其他插件及其版本范围。核心按拓扑顺序先启动依赖方,再启动依赖者;缺失或不兼容会阻断正常启动。
- 键是提供者的 metadata.name
- 值是提供者 pluginVersion 的 semver 范围
- 使用 @Inject(Service, "other-plugin") 或导出 API 时必须声明
- {} 表示无插件依赖 — 仍可使用核心内置能力
- 禁止 src 互导 — 用导出 / 注入
TSdependency map shape
"pluginDependencies": {
"products": "^1.0.0", // provider name → semver of its pluginVersion
"accounting": "^1.0.0"
}4. 核心如何加载模块
启动时合并文件系统构建与 module 表;仅已安装行会被激活。按依赖顺序加载后端,再在浏览器加载前端入口并 register(AppRegistry)。
- available-plugins 在安装前不会生效
- 仅属性 @Inject — 不支持构造函数注入
- 详见模块生命周期与前端插件生命周期 Doc
- 01
发现
读取 installed-plugins 元数据并匹配 module 表。
- 02
排序
由 pluginDependencies 构图,提供者先于消费者。
- 03
后端
IPlugin → @Module → DI → @OnInit / @OnAllModuleLoaded。
- 04
前端
提供资源 → 动态导入 → 调用一次 register(AppRegistry)。
5. 下一步
运行核心栈,创建插件,并用 CLI watch / 安装循环迭代。
- 禁止导入其他插件 src/
- 对齐 @quan-erp/* 与 requiredBasedVersion
- 目录名 = metadata.name
- 跨插件注入前先写 pluginDependencies