使用原生能力
扩展向渲染器提供可复用的宿主操作。capability 会安装扩展后端处理器,并授予特定范围的访问权限。本教程在最小应用中加入文件读取功能:后端授权一个目录,页面请求读取其中的文本文件。
添加文件系统扩展
在 minimal 项目的 moon.mod 中,将以下依赖加入 import { ... }:
"moonbit-community/proton_ext@0.4.0",
在 app/moon.pkg 中使用以下导入,然后执行 moon update:
import {
"moonbitlang/async",
"moonbit-community/proton",
"moonbit-community/proton_ext/fs",
}
supported_targets = "native"
pkgtype(kind: "executable")
准备文件
在项目根目录创建 workspace 目录,并在其中创建 message.txt,内容为:
Hello from the filesystem.
将 app/main.mbt 替换为:
///|
async fn main {
let html =
#|<!doctype html>
#|<html lang="en">
#|<meta charset="utf-8">
#|<title>Read a file</title>
#|<button id="read">Read message.txt</button>
#|<pre id="result" role="status"></pre>
#|<script>
#| document.querySelector("#read").onclick = async () => {
#| const result = document.querySelector("#result");
#| try {
#| const reply = await window.__MoonBit__.core.invokeOp(
#| "ext:fs/read_file", { path: "./workspace/message.txt" }
#| );
#| result.textContent = reply.content;
#| } catch (error) {
#| result.textContent = String(error);
#| }
#| };
#|</script>
#|</html>
@proton.html("Read a file", html)
..config(@proton.load_config())
..capability(
@fs.capability([
@fs.PermissionRoot("./workspace", ["read_file"]),
]),
)
.run_or_abort()
}
执行 proton_cli dev,点击 Read message.txt,页面应显示文件内容。这是真正的宿主文件读取,不是浏览器文件选择器。
理解授权内容
这个 capability 包含三个相关选择:
- 操作: 只允许
read_file,页面不能利用此授权写入或删除文件。 - 根目录: 只允许访问
./workspace内的路径。 - 目标: 未显式传入
targets时,授权给主窗口入口。
底层路由 ext:fs/read_file 属于文件系统扩展,应用命令则使用独立的 app: 路由空间。无需自行注册文件系统处理器。
相对根目录和请求路径以 CLI 为应用设置的 @proton.resource_dir() 为基准,不应假定它们相对于任意终端工作目录。
主动检查失败情况
将请求路径改为 workspace 中不存在的文件,调用应失败,catch 分支会显示错误。再改为允许根目录之外的文件,此授权应拒绝访问。
删除 ..capability(...) 不会阻止应用启动,但路由变得不可用。仅添加扩展依赖并不等于授予权限。
多窗口与持久化文件
为第二个窗口添加能力时,通过 RendererTarget::entry(window="...") 或 RendererTarget::bundled(window="...") 显式选择目标,只授予页面功能真正需要的权限。
本地 workspace 目录适合这个开发练习。安装资源目录可能只读,持久化文件应放在合适的可写应用数据目录或用户选择的位置。需要随应用分发的文件通过资源配置打包。
其他能力
对话框、剪贴板、shell、托盘等扩展也采用显式安装和授权的方式,但各自定义作用范围与平台支持。此版本的通知扩展面向 macOS,不能从框架的平台列表推断每个扩展都支持全部平台。
需要某项能力时,查阅扩展 API中的 capability 构建器及请求、响应类型。