扩展预加载
可运行 SQL 块可以按块声明扩展(见可运行 SQL 块),但一个只文档化
单一扩展的站点,不该让每个示例都写一遍扩展名。dfkExtensions 插件改为接收一条有序
预加载列表:
- dev/build 启动时,把列表里每个 GitHub release 来源拉进站点的静态目录——本地缓存, 仅在 release 资产变化时重新下载;
- 把解析后的列表注入每个页面;
- kit 的运行时在 DuckDB 初始化期间按序加载——页面打开(只要页上有可运行块)就在后台 开始,所以第一次点 执行 很快。
块里直接调用扩展即可,无需声明:
SELECT version() AS engine, double_it5(21) AS doubled;
接入方式
import {dfkExtensions} from 'duckfn-docs-kit/sql/extensions';
plugins: [
dfkExtensions({
// CI 构建的 release 资产没有 DuckDB 的签名密钥——与本地开发用
// `duckdb -unsigned` 是同一个原因。
allowUnsignedExtensions: true,
preload: [
// 本站文档化的扩展:同源提供。带 release 时构建期去该仓库的最新 release 取资产;
// 去掉 release 就是直接用 static/ 下放好的文件。
{
url: 'duckdb-extensions/duckfn.duckdb_extension.wasm',
release: {
repository: 'shijianjs/duckfn',
asset: 'duckfn-wasm_eh.duckdb_extension.wasm',
},
},
],
}),
],
拉取在 npm start 与生产构建时都会发生 —— 但只针对带 release 的条目。只写 {url} 的条目会被
原样放过,所以一个站点可以本地用自己的构建产物、只在部署时才切到 release:duckfn 自己的站点就是
这么做(用 DOCS_EXTENSION_FROM_RELEASE 区分,见它的 docs/README.md),因此本地跑文档从不接触
release。
三种来源
- 扩展名——
'json':运行时对官方仓库执行LOAD json。 - 名字 + 仓库——
{name: 'h3', repository: 'community'}:仓库可以是community、core或 URL。运行时先用INSTALL … FROM记录来源,再LOAD名字。在 WebAssembly 上INSTALL不落盘——没有可安装的持久存储——它只记录LOAD该从哪里取;也正因如此, 这条记录只附着在这一个扩展上,不会污染之后的加载。 - 文件——
{url: …, release?: …}:由站点自己分发 wasm 文件。带release时,构建期 从该 GitHub 仓库的最新 release 拉取资产到static/<url>(与运行时加载的路径同一个); 不带release时,文件由手工放在static/<url>,构建只检查它在不在。url也可以是 绝对http(s)URL。
GitHub release 来源
对 {url, release} 条目,插件会:
- 调 GitHub API 取仓库最新 release,按名字找资产(找不到会报错并列出可用名字);
- 用资产的 sha256——GitHub 自带的
digest字段——与本地缓存比对,只有不同才下载; - 下载后按该 digest 校验,写入
<siteDir>/.cache/duckfn-docs-kit/并拷贝到static/<url>; - 网络不可用时降级为使用缓存并给出警告,离线开发不中断(CI 每次全新环境、无缓存, 会直接失败)。
GITHUB_TOKEN(或插件的 token 选项)可以解除匿名 API 的速率限制;公开仓库在普通
开发机上不需要它。
文件名的契约
文件名第一个 . 之前的文字就是 DuckDB 查入口符号用的名字——duckfn.duckdb_extension.wasm
经 duckfn_init_c_api 加载。release 资产带平台后缀(duckfn-wasm_eh.duckdb_extension.wasm),
所以落盘时要改名:url 里的目标文件名说了算;插件与运行时都会校验“首个 . 之前”必须是
合法的扩展标识符。
版本与签名
- 平台:预加载的文件必须与运行时 bundle 的 WebAssembly 平台一致。让
selectBundle()自动选择的站点提供wasm_eh资产;本站就是这样。 - DuckDB 版本:WebAssembly 扩展只能被 C API 兼容的 DuckDB-Wasm 构建加载。站点把
@duckdb/duckdb-wasm固定在精确版本,其内置引擎与 CI 构建扩展所用的duckdb_version一致;任何一侧变动时,回到这些页面重新跑一遍可运行块即可验证。 - 签名:第三方 release 资产没有用 DuckDB 的密钥签名,因此预加载它的站点需要
allowUnsignedExtensions: true(相当于 CLI 的-unsigned)。社区扩展是签过名的, 无需打开。
它落在页面的哪里
插件把解析后的列表作为唯一一个 JSON <script> 标签注入每个页面:
{"allowUnsignedExtensions":true,"preload":[{"url":"/duckdb-extensions/duckfn.duckdb_extension.wasm"}]}
标签的 id="dfk-sql-runtime" 保持不变,调试时可以直接在页面源码里查看。列表格式不对时,
最先运行查询的块会以可读错误呈现 DuckDB 初始化失败。