打包与分发
约 671 字大约 2 分钟
2026-09-15
插件包结构
my-plugin/
├─ package.json 有依赖时才需要
├─ index.js 入口(指向下面的 apps)
├─ apps/ 每个命令一个文件
├─ model/ 业务逻辑
├─ resources/ 渲染模板与静态资源
└─ defSet/ 默认配置(可选)index.js 汇总 apps/:
import { readdirSync } from 'node:fs'
const apps = {}
for (const file of readdirSync('./plugins/my-plugin/apps')) {
if (!file.endsWith('.js')) continue
const mod = await import(`./apps/${file}`)
apps[file.replace('.js', '')] = mod[Object.keys(mod)[0]]
}
export { apps }不想拆文件也行:plugins/example/一个文件.js 就是最简单的插件。
package.json 与依赖
{
"name": "my-plugin",
"version": "1.0.0",
"type": "module",
"dependencies": {
"axios": "^1.7.0",
"jiuli": "link:../.."
}
}两点注意:
- 插件目录里有
package.json时,它就成了模块解析边界。要import 'jiuli'就必须声明"jiuli": "link:../..",否则会报Cannot find package 'jiuli'。框架检测到这种情况会直接提示你加这一行。 - 装依赖用根目录
pnpm install(workspace 会一起装)。单独装用cd plugins/my-plugin && pnpm add xxx。
安装与更新
node jiuli a https://gitee.com/you/my-plugin.git # 克隆到 plugins/ 并自动装依赖手动安装:把目录复制进 plugins/(不要复制 node_modules,交给 pnpm),然后 pnpm install,最后 #重启 或 #重载。
插件自己提供更新指令的话(云崽生态常见),记得它一般依赖 git pull,所以复制时要保留 .git 目录,否则更新命令会失败。
移植云崽插件
大部分插件复制进 plugins/ 就能用。移植时通常只需要处理这几件事:
| 情况 | 处理 |
|---|---|
引用 ../../other/xxx.js | 改成 ../../system/xxx.js(JiuLi 把 other/ 并进了 system/) |
| 从内置插件具名导入 | system/update.js 导出 update、system/restart.js 导出 Restart |
| 缺依赖 | pnpm install,或看框架打印的缺失清单 |
import 阶段有同步外部调用 | 惰性化。Windows 上调 systeminformation(PowerShell 查 WMI)单次可到 10 秒,会拖慢整个启动 |
资源仓库目录(如 HMeme/memes) | 用 git clone 建立,不要只复制文件——插件靠 .git 判断能否更新 |
miao-plugin 的 #miao / #miao.models 别名已由根 package.json#imports 提供。 已实机验证的插件清单与逐文件适配记录见兼容性与仓库里的 docs/ported-plugin-patches.md。
分发建议
- 仓库带上
README.md(装什么、怎么装、依赖哪些指令)与LICENSE - 打 tag 便于回滚,插件内的更新命令一般按分支或 tag 拉取
- 不要把
config/*.yaml、账号凭据、node_modules提交进仓库 - 引用框架 API 时优先
import ... from 'jiuli',不要require框架内部文件——内部结构不保证稳定,只有兼容层的公开路径才是契约
许可
JiuLi 本体是 AGPL-3.0。移植别人的插件时保留原作者的著作权声明与许可, 并在 README 里写清来源仓库。
