DBX 前端插件开发实战:基于 frontend 模板创建、调试、打包与发布 universal 插件
【免费下载链接】dbx20 MB lightweight cross-platform database client for 90+ databases, including MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, SQL Server, and Dameng. Built-in AI, MCP Server, CLI, desktop and Docker. | 轻量级跨平台数据库管理工具,支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、达梦等 90+ 数据库,提供桌面端、Docker、CLI、内置 AI 助手和 MCP Server。项目地址: https://gitcode.com/gh_mirrors/dbx7/dbx
DBX(轻量级跨平台数据库客户端,支持 90+ 数据库)提供了一套插件机制,允许开发者在不改动主程序的前提下,以.dbxp可选安装包的形式扩展工作台 UI 与宿主能力。本指南以dbx-plugin create --template frontend生成的模板项目(模板 README)为核心,完整讲解纯前端插件从创建、开发调试、打包到发布进 DBX 插件商店的完整链路,并深入剖析模板中的manifest.json、ui/index.html、dbx-plugin.toml与 GitHub Release 工作流等真实源码文件。读完本文,你将掌握如何零后端地构建一个可调用 DBX Host API 的沙箱工作台,并将其以universal.dbxp形式交付给 DBX 用户。
一、frontend 模板是什么
frontend是dbx-pluginCLI 提供的四种项目模板之一,也是唯一一种**完全不需要原生后端(Sidecar)**的模板:
| 模板 | 组成 | 产物 | 适用场景 |
|---|---|---|---|
frontend | 沙箱前端,无原生后端 | 一个universal.dbxp | 纯 UI、信息面板、调用 Host API 的轻量工具 |
svelte | Svelte + Vite 沙箱前端,无原生后端 | 一个universal.dbxp | 使用 Svelte 编写的自定义工作台 |
rust | 沙箱前端 + Rust Sidecar | 每个平台一个.dbxp | SSH、终端、复杂协议、系统能力、高性能任务 |
go | 沙箱前端 + Go Sidecar | 每个平台一个.dbxp | 已有 Go 生态、网络服务、协议客户端 |
模板生成的 README 开篇即明确:"This project has no native backend and produces one cross-platformuniversalpackage."这意味着前端插件的产物不依赖操作系统与 CPU 架构,一个包即可覆盖 macOS、Windows、Linux 全平台。不需要后端时应当直接选择frontend,不要为了"像完整插件"而强行添加 Sidecar——只有浏览器沙箱无法完成的能力(如 SSH、文件系统、复杂协议)才需要 Rust 或 Go 后端(见 插件开发快速开始)。
二、生成模板项目结构与各文件职责
使用交互式向导或一次性参数即可生成项目:
dbx-plugin create ~/Desktop/dbx-plugin-demo --template frontend # 或一次性传入全部参数 dbx-plugin create ~/Desktop/dbx-plugin-demo \ --template frontend \ --id com.example.dbx-plugin-demo \ --name "DBX Plugin Demo" \ --publisher example \ --description "A small DBX frontend plugin." \ --version 0.1.0 \ --yes生成的目录结构(对应仓库中的 templates/frontend):
dbx-plugin-demo/ ├── .github/workflows/plugin-release.yml # GitHub Release 构建工作流 ├── assets/plugin.svg # 插件图标 ├── ui/index.html # 沙箱前端入口 ├── dbx-plugin.toml # 开发与打包配置 ├── manifest.json # DBX 运行时读取的插件契约 └── README.md # 生成的项目说明(即本指南主体文档)各文件职责:
manifest.json:DBX 运行时读取的插件契约,声明名称、图标、引擎版本、入口、国际化与贡献点,是插件的"身份证";dbx-plugin.toml:开发与打包配置,决定打包时包含哪些目录、是否需要构建原生后端;ui/index.html:沙箱前端入口,可以替换为 Vue、React、Svelte 等框架构建后的静态资源;assets/plugin.svg:插件图标;未提供可用图标时 DBX 才使用默认图标。
三、manifest.json 插件契约详解
模板生成的 manifest.json 是 Manifest v1 的完整示例,包含{{PLACEHOLDER}}占位符,由 CLI 在创建时替换为实际值:
{ "$schema": "https://raw.githubusercontent.com/t8y2/dbx/plugin-sdk-v1/plugins/manifest.schema.json", "manifest_version": 1, "id": "{{PLUGIN_ID}}", "name": "{{PLUGIN_NAME_JSON}}", "version": "{{VERSION}}", "publisher": "{{PUBLISHER_JSON}}", "description": "{{DESCRIPTION_JSON}}", "icon": "assets/plugin.svg", "engines": { "dbx": ">=0.5.68", "host_api": "1" }, "entrypoints": { "ui": { "root": "ui", "entry": "ui/index.html" } }, "contributions": [ { "type": "workbench", "id": "{{PLUGIN_ID}}.workbench", "label": "{{PLUGIN_NAME_JSON}}", "description": "Sandboxed frontend workbench contributed by {{PLUGIN_NAME_JSON}}.", "icon": "assets/plugin.svg" } ], "localizations": { "zh-CN": { "name": "{{PLUGIN_NAME_JSON}}", "description": "{{DESCRIPTION_JSON}}", "contributions": { "{{PLUGIN_ID}}.workbench": { "label": "{{PLUGIN_NAME_JSON}}", "description": "由插件提供的沙箱前端工作台。" } } } } }关键字段解读:
| 字段 | 含义 |
|---|---|
manifest_version | 清单版本,当前为1(v1 契约由 manifest v1 + Host API 1.x + Sidecar Protocol v1 组成,详见 插件平台总述) |
engines.dbx | 约束宿主 DBX 的最低版本,模板默认为>=0.5.68 |
engines.host_api | 约束 Host API 兼容版本,前端模板声明为1 |
entrypoints.ui | 声明 UI 入口:root为包内ui/目录,entry指向ui/index.html |
contributions | 插件贡献点。前端模板贡献一个workbench(工作台),用户在 DBX 中以独立 Tab 打开 |
localizations | 国际化声明,DBX 会按当前语言精确匹配(如zh-CN),再回退到基础语言,最后回退到 manifest 默认文案 |
模板还附带了官方manifest.schema.json的$schema引用,便于在编辑器中获得字段校验。需要注意的是:JSON Schema 只是改善编写体验,并非安全边界,运行时仍会独立校验语义版本、引擎范围、ID、贡献点引用、字段类型与绑定、入口包含关系、当前平台二进制以及必需的 UI 入口(见 插件平台总述)。
四、沙箱前端与 Host API:模板自带的调用示例
模板中的 ui/index.html 是一个可直接运行的完整示例,展示了前端插件与 DBX 宿主的通信方式。核心代码如下:
<script> const result = document.querySelector("#result"); const button = document.querySelector("#context"); let text = copy.en; // 等待 DBX 完成宿主桥接初始化 window.dbxPlugin.ready.then((context) => { // 读取当前 DBX 界面语言,切换中英文文案 text = window.dbxPlugin.locale.toLowerCase().startsWith("zh") ? copy.zh : copy.en; // 打印初始化上下文 result.textContent = context && Object.keys(context).length ? JSON.stringify(context, null, 2) : text.ready; }); // 点击按钮时调用宿主方法 button.addEventListener("click", async () => { button.disabled = true; try { result.textContent = JSON.stringify(await window.dbxPlugin.request("host.getContext"), null, 2); } catch (error) { result.textContent = `${text.error}: ${error.message}`; } finally { button.disabled = false; } }); </script>这段代码演示了前端插件最常用的两个 Host API 对象:
window.dbxPlugin.ready:一个 Promise,等待 DBX 完成宿主桥接初始化,.then回调会收到初始化上下文;window.dbxPlugin.locale:当前 DBX 界面语言(如en、zh-CN),模板据此在英文/中文文案间切换;window.dbxPlugin.request(...):调用宿主提供的方法,这里通过host.getContext获取当前工作台的上下文。
除ready、locale、request之外,Host API 1.x 还提供context(读取工作台允许访问的上下文)、invoke(调用插件自己的原生 Sidecar 方法)、onContext(listener)(上下文变更实时推送,iframe 不重载,插件 UI 状态在导航后保留)等能力(见 插件平台总述)。
沙箱边界必须牢记:插件前端运行在sandbox="allow-scripts"的 iframe 中,配有严格的 CSP,没有 Tauri 对象、不能访问父页面 DOM、默认没有任何网络访问权限。前端不能直接导入 DBX 内部 Vue 组件,也不能直接访问 Tauri、Node.js 或任意本地文件。插件 UI 需要的外部网络请求,必须在 manifest 中显式声明逐来源权限,如host.network:https://api.vendor.com(仅限 HTTPS、不含路径、最多 8 个来源),这些声明会被加入沙箱的connect-src,让审核者能清楚看到插件 UI 可以访问哪些服务。所有后端调用都会被宿主重绑到所属插件 ID,一个插件 UI 无法调用另一个插件。
五、本地开发:dbx-plugin dev 独立调试环境
模板 README 明确指出,开发前端插件不需要启动 DBX 主程序,也无需后端。使用浏览器开发宿主即可:
dbx-plugin dev --path . --port 5190要点(结合 开发运行时说明):
- Node.js 22+:
dev子命令是唯一要求 Node.js 22+ 的命令; --path指定插件目录,默认当前目录;--port指定端口,占用时自动选择空闲端口;- 启动后打开终端输出的本地地址即可看到插件工作台,按
Ctrl+C停止; .dbx-dev/目录:存放本地开发数据(连接配置与凭据以明文保存),模板 README 特别强调该目录不得提交进 Git,也不得被打包;- 编辑
ui/index.html后重载页面即可看到改动;页面也可配置ui_watch实现构建后自动重载; - 最终集成测试仍需在真实 DBX 宿主中进行,开发环境不替代真实宿主的安装、Secret Store 或生命周期验收;
- 调试时可通过只读诊断接口获取日志:
curl -sS 'http://127.0.0.1:5190/api/diagnostics?after=0&limit=100'。
模板中前端构建监听的可选配置(写在dbx-plugin.toml中):
[dev] ui_build = ["npm", "run", "build"] ui_watch = ["npm", "run", "build:watch"]六、打包:dbx-plugin package 与 universal 产物
开发完成后,在插件目录执行打包:
dbx-plugin package .前端模板的打包行为在 dbx-plugin.toml 中定义:
schema_version = 1 [package] include = ["assets", "ui"]打包命令会按include清单将manifest.json、assets/、ui/暂存,然后生成未签名的 universal.dbxp候选包,以及配套的.artifact.json元数据,写入dist/目录:
dist/ ├── com.example.dbx-plugin-demo-0.1.0-universal.dbxp └── com.example.dbx-plugin-demo-0.1.0-universal.artifact.json.dbxp是交给 DBX 安装的包文件。它是规则更严格的 ZIP 容器:除checksums.json和signature.json外每个文件都必须被 SHA-256 校验和恰好覆盖一次;拒绝绝对路径、父目录穿越、重复条目、符号链接、超大条目与解压炸弹(见 插件平台总述);.artifact.json包含目标平台、URL、SHA-256 和文件大小;签名构建还会写入signingKeyId;- 本地开发默认不签名。未签名包只能用于本地安装测试,不能直接进入插件商店目录——商店条目必须包含
signingKeyId,安装前 DBX 会同时比对包内 Manifest 的 ID、版本、发布者、权限与签名 Key ID。
七、本地安装测试
未签名开发包用于自建环境验证,步骤如下(详见 插件开发快速开始):
- 打开 DBX 顶部工具栏的"插件中心";
- 切换到"设置";
- 展开"第三方与开发者选项";
- 开启"允许安装未签名开发包";
- 点击"安装
.dbxp",选择dist/中的文件; - 安装完成后切换到"已安装",打开插件提供的工作台。
本地开发包允许用相同版本重复安装(DBX 会替换当前开发版本并重启对应插件运行时),而正式签名包不允许覆盖同版本。测试结束后建议关闭该开关——它只影响手动本地安装,不会放宽官方插件商店的签名校验。
八、发布:GitHub Release、候选 PR 与 DBX Store 签名
模板 README 描述的发布流程是整个插件生态的核心,共三步:
第 1 步:发布 GitHub Release。生成的项目自带 .github/workflows/plugin-release.yml,监听release事件的published类型,调用 DBX 官方可复用工作流构建未签名 universal 候选包:
name: Release DBX plugin on: release: types: [published] permissions: contents: write jobs: release: uses: t8y2/dbx/.github/workflows/plugin-release-reusable.yml@plugin-cli-v{{CLI_VERSION}} with: release-tag: ${{ github.event.release.tag_name }} package-command: {{PACKAGE_COMMAND}} package-path: dist/*.dbxp metadata-path: dist/*.artifact.json plugin-cli-version: {{CLI_VERSION}} go-version: "" rust-toolchain: "" build-matrix: '{"include":[{"runner":"ubuntu-24.04","target":"universal"}]}'注意前端模板的构建矩阵只有target: universal一项——这正是纯前端插件"一个包覆盖全平台"的体现。官方插件作者不需要配置任何签名 Secret 或 Key ID。
第 2 步:提交候选 PR。工作流构建并上传未签名universal.dbxp候选包、对应的.artifact.json与合并后的release-candidates.json。若插件仓库已登记autoUpdate: true,DBX Store 会在 Release 发布后自动创建或更新候选 PR;否则开发者手动向t8y2/dbx-store:main提交一个候选 PR(README 特别说明:提交候选 PR 不需要先创建 Issue)。
第 3 步:DBX Store 审核并签名。审核通过后,DBX Store 的受保护工作流使用官方仓库密钥(Ed25519)对审核通过的候选包签名,并在同一个 PR 流程中更新出可安装的资产与签名元数据。最终:
- 源码与未签名候选包保留在插件作者自己的 Git 仓库;
- DBX 用户安装的是 DBX Store 签名后的资产(由官方目录暴露);
t8y2/dbx-store仓库只保存商店元数据、最终下载地址、哈希、大小、仓库公钥和审核信息,不接收私钥,也不把大型二进制提交进 Git 历史。
模板 README 最后强调仓库归属边界:普通插件源码不要提交到t8y2/dbx——该仓库只接收插件宿主、SDK、CLI、Schema、文档与官方示例的变更(见 插件平台总述)。
九、签名与信任模型补充
发布流程中反复出现"签名",其信任模型值得理解(详见 插件平台总述 与 插件开发快速开始):
- 人工审核决定插件能否进入策展目录;
- 目录 SHA-256证明下载到的 Release 资产正是审核目录选中的那个产物;
- Ed25519 仓库签名证明安装的包正是该仓库审核并发布的字节;
- 运行时权限与宿主边界限制插件 UI 安装后能请求什么。
publisher表示作者和商店归属,不代表签名密钥所有者;当前 v1 不要求开发者签名,也不做双签名。Key ID 是仓库签名公钥的稳定公开标识(最长 128 字符,可含字母、数字、点、横线、下划线和冒号),建议采用"仓库 + 用途 + 轮换版本"的命名,如company.plugins.release。只有自定义/私有仓库运营方才需要执行dbx-plugin keygen company.plugins.release生成密钥,并在 DBX 插件中心的"自定义仓库信任"中登记 Key ID 与 Base64 公钥。
十、常见问题
- 我只想写前端,为什么还要装 Rust?不需要。
@dbx-app/plugin-cli安装的是 CI 预编译二进制;生成的frontend插件不含 Rust 后端,最终.dbxp是跨平台universal包。只有插件自身选择 Rust 后端或开发 CLI 源码时才需要 Rust。 .dbxp会增加 DBX 主安装包体积吗?不会。可选插件不打进 DBX 基础安装包,只有用户安装后该插件才占用本机插件存储空间。- 开发者提交源码还是
.dbxp?两者都需要但用途不同:源码保留在开发者仓库供审查与协作;CI 生成未签名候选.dbxp;审核通过后由 DBX Store 发布最终签名.dbxp。 dbx-plugin: command not found?确认 npm 全局命令目录已加入PATH,或直接使用npx @dbx-app/plugin-cli --help。
延伸阅读
- DBX 插件开发快速开始(中文):CLI 安装、四模板选择、Host API、本地调试、签名与发布的完整中文向导
- 插件平台总述:Manifest v1 全字段、Host API 方法、安全模型、包格式与市场目录机制
- manifest 校验 Schema:Manifest v1 的编辑器/CI 校验定义
- 前端模板源码目录:
manifest.json、ui/index.html、dbx-plugin.toml与github/plugin-release.yml的真实模板文件
【免费下载链接】dbx20 MB lightweight cross-platform database client for 90+ databases, including MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, SQL Server, and Dameng. Built-in AI, MCP Server, CLI, desktop and Docker. | 轻量级跨平台数据库管理工具,支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、达梦等 90+ 数据库,提供桌面端、Docker、CLI、内置 AI 助手和 MCP Server。项目地址: https://gitcode.com/gh_mirrors/dbx7/dbx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考