☰
Beaker Browser 应用源码结构解析:Electron 入口、进程架构与构建调试指南
2026/10/7 16:12:51 网站建设 项目流程
  • 前端

【免费下载链接】beaker

An experimental peer-to-peer Web browser

项目地址:https://gitcode.com/gh_mirrors/be/beaker
点击查看免费下载

本文以仓库根目录 app/README.md 为骨架,结合app目录下实际源码,系统梳理 Beaker Browser(实验性点对点 Web 浏览器)的应用源码布局:从 Electron 主进程入口main.js出发,拆解bg(后台)、fg(前台 UI)、userland(用户态应用)三大代码域的分工与协作方式,并给出从源码构建、调试到环境变量调优的完整实战方案。读完本文,你将掌握 Beaker 的进程模型与模块组织原则,能够定位任意功能模块所在的源码目录,并能在本地环境从零构建运行这个项目。

项目背景:一个已归档的实验性 P2P 浏览器

Beaker Browser 是一个实验性的点对点(peer-to-peer)Web 浏览器,其核心目标是在保持与 Web 其余部分兼容的前提下,为构建无主机(hostless)应用提供新的 API。项目根目录 README.md 中明确标注了项目现已归档(见 archive-notice.md),当前仓库即其最终源码快照,版本号为1.1.0(见 app/package.json)。这意味着:

  • 本文描述的构建、运行与调试方式,均基于该归档版本的真实代码,可直接对照验证;
  • 项目采用 MIT 许可证,版权归属于 Blue Link Labs(Copyright (c) 2018 Blue Link Labs);
  • 作为归档项目,社区已停止活跃维护,遇到问题时应优先参考代码本身而非寻求在线支持。

从 app/package.json 的依赖清单可以看到 Beaker 的技术底座:electron(由 scripts/package.json 固定为11.0.0-beta.18)、hyperdrive-daemon-client、hyperspace、dat-dns、discovery-swarm、knex+sqlite3(本地数据库)、winston(日志)等。这套依赖组合决定了app目录必然被拆分成“主进程 / 渲染进程 / 用户态沙箱”三个层次来组织。

App 目录总览:一份五行的架构地图

仓库根目录 app/README.md 用 5 个条目精确概括了整个应用源码的布局:

路径职责
/main.jsElectron 入口点(entrypoint)
/assets静态资源,如图片、字体等
/bgElectron 主进程代码(background,后台)
/fgBeaker 的前端/UI 代码(foreground,前台)
/userland在用户态(userland)环境中运行的前端代码

下面的章节会逐一展开这五个部分,并补充 bg/README.md、fg/README.md、userland/README.md 三个子 README 中的细节,让这张地图从“文件名列表”升级为“可导航的架构图”。

assets:静态资源目录

assets下集中存放了应用运行所需的静态文件,app/README.md 指出它包含 images、fonts 等资源。具体包括:

  • css/:fa-all.min.css(Font Awesome 图标字体)、syntax-highlight.css(代码高亮样式);
  • favicons/:数十种.ico站点图标(如book.ico、terminal.ico、cloud.ico、home-house.ico等),用于在地址栏/标签页展示不同类型站点的图标;
  • fonts/:fa-*(Font Awesome 字体族)与source-sans-pro字体;
  • img/:各类图片素材,如drive-types/(不同 drive 类型的图标)、favicons/、frontends/(前端应用截图)、search-engines/(搜索引擎图标)、onboarding/(首次启动引导插画)、default-cover.jpg、logo.png等。

该目录本身不包含任何业务逻辑,是纯静态资源层。

main.js:Electron 主进程入口如何运转

main.js是整个应用的启动原点。app/README.md 称其为 “Electron entrypoint”,而源码注释进一步说明它是 Electron 的主进程脚本,“在应用启动时最先被执行,并在整个应用生命周期内持续运行,不拥有任何可见窗口,但可以从这里打开窗口”。

结合 app/main.js 的完整代码,主进程的初始化流程可以归纳为以下顺序:

  1. 环境变量预处理:读取BEAKER_USER_DATA_PATH覆盖用户数据目录(见下文“环境变量”章节);读取BEAKER_TEST_DRIVER启动测试驱动;关闭 Electron 安全警告。
  2. 安全与性能开关:app.enableSandbox()启用渲染进程沙箱;allowRendererProcessReuse = true开启渲染进程复用以加速导航;追加disable-features=OutOfBlinkCors修复自定义协议下的 CORS 问题。
  3. 注册特权协议:通过protocol.registerSchemesAsPrivileged将dat、hyper、beaker三个自定义 scheme 注册为standard + secure,并开启 Service Worker、Fetch API、CORS 支持(hyper额外开启stream)——这是 Beaker 能承载 P2P 网页的基础设施。
  4. 处理操作系统事件:监听open-url与open-file,将系统级 URL/文件打开请求转发给bg/open-url.js处理;非 macOS 平台则在 argv 中查找带://的参数作为 URL 打开。
  5. ready事件后的子系统启动(顺序即依赖顺序):初始化日志(写入userData/beaker.log)→ 注册beaker协议 → 初始化 Web APIs → 打开初始化窗口 → 启动 NAT 端口转发 → 初始化全部 SQLite 数据库(bg/dbs/*)→ 启动 hyperdrive(bg/hyper)→ 初始化 hyperdrive 文件系统(bg/filesystem)→ 初始化浏览器核心(bg/browser)→ 启动广告拦截与统计 → 初始化书签/固定项 → 注册asset、hyper、dat协议 → 运行首次启动引导流程(setup flow)→ 初始化窗口菜单、右键菜单、托盘图标、浏览器窗口、下载管理与权限管理器。
  6. 单实例锁:app.requestSingleInstanceLock()保证只运行一个实例,第二个实例启动时会把 argv 转发给已有实例并聚焦窗口。
  7. 优雅退出:will-quit时若 hyperdrive daemon 需要关闭,则先shutdown()再退出;quit时关闭 NAT 端口转发。

从源码结构看,main.js扮演的是“编排者”角色——它本身不实现业务逻辑,而是把 bg 下的各个模块按依赖顺序装配起来。这也解释了为什么bg是整份代码中最大的目录。

bg:Electron 主进程的后台代码域

bg/README.md 开宗明义:本目录包含驱动 Beaker Electron 主进程的后端代码。其 Notable folders 给出了 7 个功能分区:

子目录职责(摘自 bg/README.md)
lib后端专用的可复用代码
dat管理 dat daemon 及 dat 专属行为
dbs全部 SQLite 数据库及持久化数据管理
filesystem管理用户主 hyperdrive 及其持久化数据(含 dats 库与用户)
protocols自定义 URL scheme 处理器
rpc-manifests供/app/fg组件调用的内部 RPC 清单
ui管理窗口、标签页、子窗口及一切 UI 相关逻辑
web-apis通过 RPC 暴露给 userland 环境的所有接口(同时包含 fg 与 bg 代码)

下面选取其中最能体现 Beaker 技术特色的几个模块做源码级展开。

dbs:版本化迁移的 SQLite 数据库层

dbs是 Beaker 的本地数据层,全部基于 SQLite,目录内最引人注目的是schemas/下从profile-data.v1.sql.js到profile-data.v52.sql.js共 52 个版本化 schema 文件。这种“每版本一个 SQL 文件”的组织方式(配合 bg/dbs 下的profile-data-db.js、settings.js、history.js、sitedata.js、watchlist.js等数据访问模块)让数据库迁移清晰可追踪:从 v1 到 v52 的演进史几乎就是 Beaker 功能演进的缩影。

在 app/main.js 的启动流程中,所有dbs模块会被统一遍历并调用各自的setup(commonOpts)完成建库/迁移,其中commonOpts携带了userDataPath与homePath。日志系统则把运行日志写入userData/beaker.log(见 bg/logger.js)。

protocols:四个自定义 URL scheme

bg/protocols下存放着 Beaker 全部的自定义协议处理器:

  • asset.js:asset:协议,用于加载打包资源;
  • beaker.js:beaker:协议,承载beaker://内部页面与用户态应用(见下文userland);
  • hyper.js:hyper:协议,对应新式 hyperdrive 地址;
  • dat.js:dat:协议,对应旧式 dat 地址。

这些处理器在 app/main.js 的ready流程中被逐一register(protocol)注册,并与启动早期registerSchemesAsPrivileged声明的特权相匹配。与之呼应,scripts/package.json 的build.protocols配置还声明了http、https、hyper、dat四类系统级 URL scheme 处理器,使 Beaker 可以被操作系统注册为这些链接的默认打开程序。

web-apis:暴露给网页的 RPC 接口层

web-apis是 Beaker“无主机应用”理念的核心载体。目录结构分为bg/(后台实现)与fg/(前台封装)两块,其中bg/下包含beaker-filesystem.js、capabilities.js、contacts.js、drives.js、history.js、hyperdrive.js、peersockets.js、shell.js、watchlist.js等模块——这些正是网页通过beaker://或超驱页面可调用的浏览器能力 API 的后台实现。

bg/README.md对此有一个意味深长的注释:“它目前同时包含 fg 和 bg 代码(这或许应该改变)”,暗示该模块的职责边界在项目演进中仍在调整。

ui:窗口与界面管理

bg/ui负责所有窗口级 UI 状态,与fg中的界面组件一一对应。fg/README.md 明确指出:“许多文件夹与/app/bg/ui/subwindows/*中的文件存在 1:1 关联,如perm-prompt、prompts、shell-menus”。bg/ui下还包含tabs/(标签页管理器、窗格布局、窗格、缩放)、windows.js、context-menu.js、downloads.js、permissions.js、tray-icon.js、window-menu.js、keybindings.js、setup-flow.js等。

fg:前台 UI 代码域

fg/README.md 说明:本目录包含驱动 Beaker UI 的前端代码,每个文件夹都是一个自包含的 UI 组件,许多组件与bg/ui/subwindows/*中的文件 1:1 对应。两个 Notable 条目:

  • lib:前端专用的可复用代码;
  • shell-window:Beaker 的主 shell UI。

fg目录实际包含的组件(与子 README 相互印证):location-bar/(地址栏)、modals/(各类模态框:add-drive、create-drive、drive-properties、prompt、user-editor 等)、perm-prompt/(权限询问弹窗)、prompts/(提示框)、shell-menus/(shell 菜单:bookmark、share、peers、site、create 等)、shell-window/(主窗口与 navbar)、tab-switcher/、webview-preload/(webview 预加载脚本)、json-renderer/与syntax-highlighter/。

RPC 约定:bg-process-rpc.js模式

fg/README.md特别强调了一个关键约束:

Beaker 的 Web API 在这些组件中不可用,因此与 Electron 进程的所有 RPC 都需要手动建立(这就是bg-process-rpc.js模式)。

这意味着fg组件不能像userland应用那样直接使用beaker.*Web API,而是要通过pauls-electron-rpc等机制显式连接主进程。每个fg组件目录下都能看到bg-process-rpc.js(如modals/、perm-prompt/、prompts/、shell-menus/、shell-window/目录内均存在),这正是“1:1 组件 + 手动 RPC”架构的直接证据。

userland:运行在网页环境中的用户态应用

userland/README.md 对第三层代码域做了最详细的阐述,它是理解 Beaker 应用模型的关键文档,核心内容如下:

  • 定义:userland包含在“与任何 userland 页面相同的环境”中执行的 fg 代码。与fg中的代码不同,这里标准 Web API 可用,原因是webview-preload.js被注入了(即 fg/webview-preload 下的预加载脚本,内含index.js、execute-javascript.js、prompt.js等)。
  • 应用模型:/app/userland下的每个文件夹都托管在自己的beaker://域名下,可以视为一个独立的应用(其中 “viewer” 应用包含多个子应用)。beaker://app-stdlib提供了一批跨应用复用的组件。
  • 构建策略:userland 应用尽可能不做构建;仅当需要与 Beaker 内部代码共享代码时才引入构建步骤,典型案例是 “library” 和 “site-info”。
  • 演进方向:userland中的每个应用都应被视为“可迁入 hyperdrive”的候选者;如果一个应用没有可能迁入 hyperdrive,它就应当被放进fg。

仓库中userland下实际包含:app-stdlib(标准组件库)、cmd-pkg(命令行工具包)、desktop、diff、drive-view、editor、explorer、history、hypercore-tools、init、library、settings、setup、site-info、webterm——它们分别对应 Beaker 内置的桌面模式、文件浏览器、编辑器、历史、设置、站点信息、WebTerm 等应用,全部运行在beaker://域名之下。

从源码构建与运行

仓库根目录 README.md 提供了完整的构建指南,本节结合 scripts 目录下的构建脚本做展开说明。

环境依赖

源码构建要求Node.js 12 或更高版本。不同平台还需安装原生模块编译工具链:

Linux(部分 macOS 场景同样需要):

sudo apt-get install libtool m4 make g++ autoconf # debian/ubuntu sudo dnf install libtool m4 make gcc-c++ libXScrnSaver # fedora brew install libtool autoconf automake # macos

Windows:需要 Python 2.7、Visual Studio 2015 或 2017 与 Git(可尝试 windows-build-tools),随后配置 node-gyp:

npm config set python c:/python27 npm config set msvs_version 2017 npm install -g node-gyp npm install -g gulp

构建步骤与脚本化工作流

git clone https://github.com/beakerbrowser/beaker.git cd beaker/scripts npm install # 不必担心构建原生模块时的 v8 api 报错,rebuild 会修复 npm run rebuild # 每次 install 之后都需要执行,参见 electron/electron#5851 npm start

scripts目录中的任务脚本(由 scripts/package.json 定义)把上述步骤自动化了:

  • npm run rebuild→ scripts/tasks/rebuild.js:通过 gulp 对需要重建的原生模块执行 Electron 环境的npm rebuild。从源码看,MODULES_NEEDING_REBUILD = ['sqlite3'],即本项目需要针对 Electron runtime 重新编译的模块是sqlite3;命令为npm rebuild sqlite3 --runtime=electron --target=11.0.0-beta.18 --disturl=https://electronjs.org/headers --build-from-source,随后自动执行npm run build。这就是 README 中“rebuild 会修复原生模块错误”的实现依据。
  • npm start→ scripts/tasks/start.js 与 scripts/tasks/start-cli.js:启动应用。
  • npm run watch→gulp start-watch:开发模式下监听文件变更、自动重建资源(构建管线见 scripts/gulpfile.js)。

疑难杂症处理:npm run burnthemall

README 中有一个颇具 Beaker 风格的“终极清理”命令:

npm run burnthemall

其背后的实现是 scripts/tasks/burnthemall.js。从源码可以看到它依次完成:

  1. 删除scripts/与app/下的node_modules(源码注释戏称这是“the mad king”在焚烧依赖目录);
  2. 删除两处的package-lock.json;
  3. 依次执行npm install→npm run rebuild→npm run build。

README 对该命令的定位是:当你从仓库拉取最新代码后遇到诡异的模块错误时使用,执行完npm start应当恢复工作。对于这个已归档的项目,它同样适合在本地环境混乱时一键重建干净的依赖树。

打包发布

scripts/package.json 的scripts.release为electron-builder -p never && gulp postbuild,build配置块(appId: com.bluelinklabs.beaker-browser、asar: false、macOShardenedRuntime与 entitlements、Linux AppImage 分类等)完整描述了如何用 electron-builder 产出各平台安装包;发布流程细节可参考 scripts/how-to-make-a-release.md。普通用户更推荐直接使用 Releases Page 的现成安装包(见根 README.md)。

环境变量:调试与测试的开关面板

根 README.md 的 “Env Vars” 一节集中列出了 Beaker 支持的环境变量,这是本地调试和自动化测试最实用的入口。结合源码,逐条展开如下。

DEBUG

需要输出哪些日志系统?逗号分隔的字符串。可选值:beaker、dat、bittorrent-dht、dns-discovery、hypercore-protocol。指定*表示全部。

从 bg/logger.js 的实现看,Beaker 的日志基于 winston:日志同时写入userData/beaker.log文件(JSON 格式,含 timestamp,并会对 64 位 hash 做4..2形式的截断显示)与控制台;bg/dat/dns.js等模块通过logger.child({category: 'dat', subcategory: 'dns'})建立按分类的日志通道,因此DEBUG=dat即可过滤出 dat 域名解析等子系统的输出。例如:

DEBUG=beaker npm start # 只看 Beaker 自身日志 DEBUG=* npm start # 输出全部日志系统

BEAKER_OPEN_URL

启动时打开指定的 URL,而非恢复上一次会话或默认标签页。

其实现位于 bg/ui/windows.js:源码第 68 行通过getEnvVar('BEAKER_OPEN_URL')判断该变量是否设置,第 170 行在构造初始页面时把opts.pages = [getEnvVar('BEAKER_OPEN_URL')]传入。使用示例:

BEAKER_OPEN_URL="hyper://example.com" npm start

注意:环境变量读取是大小写不敏感的——bg/lib/env.js 中的getEnvVar会先查process.env[name.toUpperCase()],再查小写形式,所以beaker_open_url同样有效。

BEAKER_USER_DATA_PATH

覆盖 user-data 路径,从而改变数据读写位置。对测试很有用。默认值参见 Electron 文档中app.getPath('userData')的定义。

源码实现同样在 app/main.js:启动最早期执行

if (getEnvVar('BEAKER_USER_DATA_PATH')) { console.log('User data path set by environment variables') console.log('userData:', getEnvVar('BEAKER_USER_DATA_PATH')) app.setPath('userData', getEnvVar('BEAKER_USER_DATA_PATH')) }

即通过app.setPath('userData', ...)重定向 Electron 的用户数据目录。由于 SQLite 数据库、日志、hyperdrive 元数据都落在这个目录下,切换该路径即可获得一套完全隔离的浏览器环境,非常适合并行测试多个配置:

BEAKER_USER_DATA_PATH=/tmp/beaker-test-1 npm start

BEAKER_DAT_QUOTA_DEFAULT_BYTES_ALLOWED

覆盖 dat 站点允许写入字节数的默认最大配额。对测试很有用。默认值为'500mb'。可以是 Number 或 String,支持的单位与缩写见bytes.parse。

这是与 dat 协议磁盘配额相关的高级测试开关。默认500mb意味着普通 dat 站点默认最多可向本机写入 500MB 数据;调大/调小该值可以分别模拟“海量站点写入”与“配额耗尽”场景:

BEAKER_DAT_QUOTA_DEFAULT_BYTES_ALLOWED='10gb' npm start # 字符串形式 BEAKER_DAT_QUOTA_DEFAULT_BYTES_ALLOWED=10485760 npm start # 数字形式(字节)

其他调试辅助

除 README 列出的四个变量外,源码中还有两个实用的隐藏开关:

  • BEAKER_TEST_DRIVER:app/main.js 在启动早期检测该变量并调用testDriver.setup()(实现见 bg/test-driver.js),用于启用测试驱动接口,供自动化测试套件驱动浏览器行为;
  • ELECTRON_DISABLE_SECURITY_WARNINGS:被强制置为'1',用于静默 Electron 的安全警告输出(源码注释自嘲 “we know, we know”)。

已知问题与安全说明

tmux 启动挂起问题

根 README.md 记录了一个已知问题:在 macOS 上从 tmux 启动会导致 GUI 应用出问题,Beaker 可能因此启动时挂起。如果你在 tmux 会话中运行 Beaker 且无窗口响应,应考虑在 tmux 外直接启动,或换用其他终端复用工具。

漏洞披露

涉及安全漏洞的发现与上报,请遵循 SECURITY.md 中的流程处理;社区贡献规范见 CONTRIBUTING.md。

结语:如何用好这份源码地图

把本文的各个部分串起来,app目录的三层结构可以归结为一句话:bg决定浏览器“能做到什么”(主进程能力),fg决定界面“长什么样”(内嵌 UI 组件),userland决定网页“能调用什么”(beaker://应用与 Web API 沙箱)。

上手实践的建议路径:

  1. 先用环境变量BEAKER_OPEN_URL与BEAKER_USER_DATA_PATH做隔离式冒烟测试,理解各协议(dat:、hyper:、beaker:)的页面行为;
  2. 想改 UI,进 app/fg 找对应组件目录,并留意其bg-process-rpc.js与 app/bg/ui 的 1:1 对应关系;
  3. 想研究 P2P 数据能力,读 app/bg/web-apis 与 app/bg/dbs 的 52 个版本化 schema;
  4. 想理解“无主机应用”模型,重点研读 app/userland/README.md 与beaker://app-stdlib的复用机制。

这份目录结构文档虽然只有五行,但它准确反映了 Beaker 将“Electron 主进程、内嵌 UI、用户态 Web 应用”三者物理隔离的架构选择——而上述所有细节,都对应着仓库中可逐行阅读的真实源码。

  • 前端

【免费下载链接】beaker

An experimental peer-to-peer Web browser

项目地址:https://gitcode.com/gh_mirrors/be/beaker
点击查看免费下载

相关推荐

上一篇:Unity WebGL中RTSP视频流播放终极指南:零插件实现实时监控
下一篇:终极指南:如何快速掌握Vue可视化打印解决方案vue-plugin-hiprint

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询