mcpField
E
electrobun-best-practices

electrobun-best-practices

github.com/alleneubank开发50317 次安装18 周前更新
代码仓库

关于 electrobun-best-practices

Electrobun Best Practices 是使用 TypeScript 和 Bun 构建跨平台桌面应用的指导技能,涵盖安全默认设置、类型化 RPC,以及构建、更新和分发的操作实践。

主要功能

  1. 01指导 Bun 与浏览器上下文架构
  2. 02定义共享的类型化 RPC 模式
  3. 03应用沙箱和导航规则
  4. 04处理关闭流程与应用事件
  5. 05排查构建、更新和会话问题

适用场景

  1. 01搭建 Electrobun 应用结构
  2. 02通过类型化 RPC 连接 Bun 与浏览器上下文
  3. 03隔离不可信内容或用户会话
  4. 04诊断更新器和构建钩子问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alleneubank/claude-code --skill electrobun-best-practices

安装后在 Claude Code 中输入/electrobun-best-practices确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
build-config.md
platform-apis.md
window-and-webview.md

详细介绍

Electrobun 最佳实践

Electrobun 使用 TypeScript 和 Bun 构建跨平台桌面应用。此技能提供安全的默认配置、类型化 RPC 模式,以及构建、更新和分发方面的操作指南。

文档:https://blackboard.sh/electrobun/docs/

与 TypeScript 最佳实践配合使用

始终与此技能一同加载 typescript-best-practices。

版本与时效性

Electrobun API 发展迅速。在依赖高级选项或特定平台行为之前,请先对照最新文档和 CLI 输出进行验证。

架构

Electrobun 应用以 Bun 应用的形式运行:

  • Bun 进程(主进程):从 electrobun/bun 导入
  • 浏览器上下文(视图):从 electrobun/view 导入
  • 共享类型:两个上下文共享的 RPC 架构

Bun 与浏览器上下文之间的 IPC 使用 postMessage、FFI,以及(在某些路径中)加密的 WebSocket。

快速开始

bunx electrobun init
bun install
bun start

推荐脚本:

{
  "scripts": {
    "start": "electrobun run",
    "dev": "electrobun dev",
    "dev:watch": "electrobun dev --watch",
    "build:dev": "bun install && electrobun build",
    "build:canary": "electrobun build --env=canary",
    "build:stable": "electrobun build --env=stable"
  }
}

安全的默认配置

对不受信任或第三方内容使用以下基线配置:

import { BrowserWindow } from "electrobun/bun";

const win = new BrowserWindow({
  title: "External Content",
  url: "https://example.com",
  sandbox: true,                  // disables RPC, events still work
  partition: "persist:external",
});

win.webview.setNavigationRules([
  "^*",                          // block everything by default
  "*://example.com/*",           // allow only trusted domain(s)
  "^http://*",                   // enforce HTTPS
]);

win.webview.on("will-navigate", (e) => {
  console.log("nav", e.data.url, "allowed", e.data.allowed);
});

安全检查清单:

  • 对不受信任的内容使用 sandbox: true。
  • 应用严格的导航允许列表。
  • 使用不同的 partition 值进行隔离。
  • 验证来自 <electrobun-webview> 预加载脚本的所有 host-message 载荷。
  • 不要在运行时写入 PATHS.RESOURCES_FOLDER;请使用 Utils.paths.userData。

类型化 RPC(最简模式)

// src/shared/types.ts
import type { RPCSchema } from "electrobun/bun";

export type MyRPC = {
  bun: RPCSchema<{
    requests: {
      getUser: { params: { id: string }; response: { name: string } };
    };
    messages: {
      logToBun: { msg: string };
    };
  }>;
  webview: RPCSchema<{
    requests: {
      updateUI: { params: { html: string }; response: boolean };
    };
    messages: {
      notify: { text: string };
    };
  }>;
};
// bun side
import { BrowserView, BrowserWindow } from "electrobun/bun";
import type { MyRPC } from "../shared/types";

const rpc = BrowserView.defineRPC<MyRPC>({
  handlers: {
    requests: {
      getUser: ({ id }) => ({ name: `user-${id}` }),
    },
    messages: {
      logToBun: ({ msg }) => console.log(msg),
    },
  },
});

const win = new BrowserWindow({
  title: "App",
  url: "views://mainview/index.html",
  rpc,
});

await win.webview.rpc.updateUI({ html: "<p>Hello</p>" });
// browser side
import { Electroview } from "electrobun/view";
import type { MyRPC } from "../shared/types";

const rpc = Electroview.defineRPC<MyRPC>({
  handlers: {
    requests: {
      updateUI: ({ html }) => {
        document.body.innerHTML = html;
        return true;
      },
    },
    messages: {
      notify: ({ text }) => console.log(text),
    },
  },
});

const electroview = new Electroview({ rpc });
await electroview.rpc.request.getUser({ id: "1" });
electroview.rpc.send.logToBun({ msg: "hello" });

事件与关闭

使用 before-quit 执行关闭清理,而不要依赖 process.on("exit") 处理异步操作。

import Electrobun from "electrobun/bun";

Electrobun.events.on("before-quit", async (e) => {
  await saveState();
  // e.response = { allow: false }; // optional: cancel quit
});

重要注意事项:

  • Linux 目前存在一项限制:某些由系统发起的退出路径(例如 Ctrl+C、窗口管理器或任务栏退出)可能不会触发 before-quit。通过 Utils.quit()/process.exit() 以编程方式退出是可靠的。

常见模式

  • 键盘快捷键(复制/粘贴/撤销):定义带有基于角色的项目的 Edit ApplicationMenu。
  • 仅托盘应用:设置 runtime.exitOnLastWindowClosed: false,然后通过 Tray 驱动用户体验。
  • 多账户隔离:为每个账户使用不同的 partition 值。
  • Chromium 一致性:在平台配置中设置 bundleCEF: true 和 defaultRenderer: "cef"。

故障排除

  • RPC 调用意外失败:
    • 检查目标 webview 是否启用了沙盒(sandbox: true 会禁用 RPC)。
    • 确认共享 RPC 类型与 Bun 和浏览器处理程序中的定义一致。
  • 导航阻止了合法 URL:
    • 检查 setNavigationRules 的顺序;最后匹配的规则优先。
    • 仅在有意启用严格允许列表模式时,才将 ^* 放在首位。
  • 更新器提示没有更新:
    • 验证 release.baseUrl 和已上传的 artifacts/ 命名({channel}-{os}-{arch}-...)。
    • 确认通道与构建环境一致(canary 与 stable)。
  • 用户会话在账户之间泄漏:
    • 为每个账户使用明确的独立分区,并通过 Session.fromPartition(...) 管理 Cookie。
  • 构建钩子未运行:
    • 确保钩子路径正确,且可通过 Bun 执行。
    • 检查钩子环境变量(例如 ELECTROBUN_BUILD_ENV、ELECTROBUN_OS、ELECTROBUN_ARCH)。

参考文件

评论

支持 Markdown