主题
从零编写第一个插件
这一页做一个最小的命令插件。它不解析博客、不读取 Core 内部状态,只接收一个命令参数并输出结果。完成后你会理解 luox 的三个关键点:plugin.json 如何注册命令,Host 如何找到插件,插件如何自己解释参数。
第一步:创建目录
在项目外新建插件目录:
hello-plugin/
├── plugin.json
└── hello-plugin.exe
hello-plugin.exe 可以由 Rust、Go、C++、Python 打包程序或其它语言生成。开发阶段可以先用一个已有的可执行程序模拟,发布阶段必须放入真正的编译产物。
第二步:编写清单
plugin.json:
{
"id": "example.hello",
"name": "Hello Plugin",
"version": "1.0.0",
"api_version": 1,
"commands": {
"hello": "hello-plugin.exe"
},
"capabilities": ["example-command"]
}
id 是生态中的稳定身份,不能因为文件名变化就随意改变。commands 的 key 是用户输入的命令,value 是相对于该插件目录的可执行文件。
第三步:理解参数转发
用户执行:
luox hello world
Host 会寻找提供 hello 的插件,然后等价启动:
hello-plugin.exe hello world
Host 不会知道 world 是什么,也不会修改它。插件可以把它当作名字、文件路径、配置选项或自己的子命令。
第四步:编写插件程序
下面是 Rust 形式的最小实现思路:
fn main() {
let mut args = std::env::args().skip(1);
match args.next().as_deref() {
Some("hello") => {
let name = args.next().unwrap_or_else(|| "world".into());
println!("Hello, {name}!");
}
_ => eprintln!("usage: hello hello <name>"),
}
}
编译后只把 hello-plugin.exe 和 plugin.json 放入最终包,不需要把 Rust 源码、Cargo 或 target 目录交给用户。
第五步:测试
从包含 luox.exe、luox_core.dll 和 plugins/ 的项目根目录执行:
luox hello luox
预期输出:
Hello, luox!
如果提示找不到命令,检查 plugin.json 是否位于 plugins/ 的直接子目录,以及 commands 中的入口文件是否存在。
下一步
命令插件只是入门。需要定义文章目录时实现 project-model,需要处理 Markdown 时实现 parser,需要生成 HTML 时实现 theme,需要复制 CSS/JS 时实现 asset-provider,需要发布 GitHub Pages 时实现 deployer。