Skip to content

开发与调试 ​

本页汇总了编写插件时有用的工具:开发者模式下的测试实例、浏览器包的开发加载方式、日志、检查工具和一致性测试。

开发者模式 ​

注意

在开发者模式之外,Nginx UI 只安装已签名的插件包。开发期间,请在测试实例(切勿在生产实例)上开启 偏好设置 > 插件 > 开发者模式。开发者模式会:

  • 允许从上传、命令行或离线插件包目录安装未签名的插件包;
  • 在 插件 页面显示开发工具。

它永远不会接受签名已损坏的插件包,也不会让未签名的插件参与自动更新。参见签名与信任。

快速重装 ​

服务端进程的每次修改都需要一个新的插件包。有两种方法可以缩短这个循环:

  • 在服务器上先运行 nginx-ui plugin pack <目录> <插件包>,再运行 nginx-ui plugin install <插件包> --enable --approve-permissions,一步替换已安装的版本。
  • 把插件包放进插件目录下的 packages 目录(默认是 <配置目录>/plugins/packages),Nginx UI 下次启动时如果发现它的版本比已安装的新,就会安装它,然后把它移到 packages/installed。

发行版也可以把插件包放在一个只读目录里,用 [plugin] 段的 BundledDir 或环境变量 NGINX_UI_PLUGIN_BUNDLED_DIR 指定。官方 Docker 镜像就是这样内置 DNS-01 插件的。Nginx UI 会把每个内置插件安装并启用一次;内置的插件包版本更新时会升级它;用户卸载后不会再自动装回来。只有用官方插件密钥签名的插件包会从这个目录安装。

开发浏览器包 ​

浏览器包可以从本地开发服务器加载,而不是从已安装的插件包加载,这样重新构建后只需刷新页面:

  1. 在运行浏览器的机器上用开发服务器提供插件目录(包括 plugin.json),例如 vite build --watch 加一个静态文件服务器。
  2. 在 插件 页面打开标签页旁的菜单,选择开发插件地址,输入 plugin.json 的地址,例如 http://localhost:5173/plugin.json。
  3. 刷新页面。

Nginx UI 会相对于该地址加载清单中指定的浏览器包、样式表和页面。由于页面每次访问都会执行这个脚本,只接受 localhost 地址。清空地址即可回到已安装的版本。

浏览器包一页介绍了如何构建浏览器包。

日志 ​

注意

插件把自己的日志写到标准错误。Nginx UI 会捕获这些输出,并在 插件 页面的插件详情中显示。标准输出只能用于协议消息,写入任何其他内容都会破坏连接。SDK 会自动把日志输出到标准错误。

插件还可以通过 host.log 方法发送结构化日志,参见宿主 API。绝不要记录凭据或令牌,参见权限与安全。

检查插件 ​

静态检查 ​

bash
nginx-ui plugin lint <插件目录或插件包>

检查工具读取插件的清单和文件,一次性报告所有问题:清单字段、插件包的结构与限制、签名、能力块、模板和翻译文件。每个问题都有级别(error 或 warning)和规则名称,检查规则解释了每一条规则。

有错误的插件包无法安装。警告也应修复:它们指出的问题会被安装插件的人看到。

一致性测试 ​

bash
nginx-ui plugin conformance <插件目录或插件包> [参数]

一致性测试使用 Nginx UI 自己的进程管理器和宿主 API 启动插件,检查它的行为:握手、健康检查、错误码、并发调用、关闭,以及它声明的每个能力的调用。测试绝不会调用会访问真实服务商或修改真实数据的方法:例如对 DNS-01 插件只会要求它校验一个空配置,而不会发布记录。

参数含义
--capability只测试某一个能力,例如 dns01。
--transportstdio、grpc 或 both。插件提供 gRPC 时默认为 both,否则为 stdio。
--timeout整个测试的时间上限,默认为 90s。

提供 gRPC 的插件会在两种传输方式上分别测试,且结果必须一致。没有服务端进程的插件只进行静态检查。

协议样例 ​

plugin-spec 仓库的 vectors/v1 目录为每个方法提供了请求与响应样例。不使用 SDK 编写插件时,可以在单元测试中使用它们。Go SDK 的 sdk.Run 和 Rust SDK 的 run 可以通过内存管道驱动插件,用途相同。

常见问题 ​

现象原因
插件启动后立即失败。握手前向标准输出写入了内容,或缺少当前平台的可执行文件。请查看插件日志。
握手因能力不匹配而失败。进程报告的能力与清单中的 capabilities 不一致。
进程每隔几秒就被重启。忙碌时没有响应 plugin.ping。应独立于耗时调用处理健康检查,参见生命周期。
宿主调用返回权限错误。清单没有请求该权限,或者用户尚未批准。
浏览器包没有加载。它没有用清单 ID 调用 registerPlugin,或者打包了自己的 Vue。参见浏览器包。

Released under the AGPL-3.0 License. (350eea3f)