Bruno 本地开发环境搭建与 npm 多工作区构建流程详解(贡献者指南)
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
本文基于 Bruno 仓库的贡献者文档(docs/contributing/contributing_bn.md,为英文 contributing.md 的本地化版本),系统讲解如何在本机把 Bruno 跑起来:从技术栈与运行环境要求,到双进程(前端 + Electron)的本地开发命令、内部包构建顺序、Unsupported platform错误的排障手段、测试执行方式与 Pull Request 分支规范。读完后你可以独立完成 Bruno 的 checkout、安装、开发调试与测试全流程。
技术栈总览
贡献者文档明确给出了 Bruno 的前端技术选型:
- CSS — Tailwind
- 代码编辑器 — Codemirror
- 状态管理 — Redux
- 图标 — Tabler Icons
- 表单 — formik
- Schema 校验 — Yup
- 请求客户端 — axios
- 文件系统监听 — chokidar
- 国际化 — i18next(见 contributing.md 的完整列表)
这些声明在源码中可以得到逐一印证。前端应用 packages/bruno-app/package.json 的依赖中可以直接找到codemirror、@reduxjs/toolkit、@tabler/icons、formik、yup、i18next,devDependencies 中有tailwindcss;桌面端 packages/bruno-electron/package.json 则引入了axios与chokidar(用于监听本地集合目录的文件变化,这也是 Bruno 支持本地文件集合的核心机制之一)。
一个需要注意的演进点:bn 文档原文写的是“React + Electron,Next.js 构建”,但当前仓库的前端已从 Next.js 迁移到 rsbuild——packages/bruno-app/package.json 的dev/build脚本均为rsbuild命令,构建配置见 packages/bruno-app/rsbuild.config.mjs(启用了 React、Babel、Sass、styled-components 等插件)。英文贡献指南中也标注了这一点:“We use React for the frontend and rsbuild for build and dev server”。
运行环境与依赖
贡献者文档要求使用 Node 18.x 及 npm 8.x(bn 文档版本),并声明项目使用npm workspaces组织多个包。就当前仓库而言,版本要求已经提高:
- 仓库根目录 .nvmrc 固定为
v22.12.0,英文 contributing.md 明确要求 Node v22.x 或最新 LTS; - 热重载脚本 scripts/dev-hot-reload.js 会直接读取
.nvmrc的大版本号,用它启动对应 Node 的监视进程。
npm workspaces 的定义在根目录 package.json 中,共包含 16 个工作区:
"workspaces": [ "packages/bruno-app", "packages/bruno-electron", "packages/bruno-cli", "packages/bruno-common", "packages/bruno-converters", "packages/bruno-schema", "packages/bruno-schema-types", "packages/bruno-query", "packages/bruno-js", "packages/bruno-tests", "packages/bruno-toml", "packages/bruno-graphql-docs", "packages/bruno-requests", "packages/bruno-filestore", "packages/bruno-sqlite" ]其中bruno-app是前端界面,bruno-electron是桌面壳,其余为可被两者复用的库(集合解析、格式转换、JS 沙箱、请求执行、文件存储等)。根 package.json 中还配置了overrides(如锁定rollup为 3.30.0、axios为 1.18.0),用于统一跨工作区的依赖版本,安装时遇到 peer 依赖冲突需按文档使用--legacy-peer-deps。
本地开发流程
Bruno 是一个桌面应用。开发时需要在前端 dev server 与 Electron 主进程之间建立连接:前端跑在浏览器端口的 rsbuild dev server 上,Electron 窗口加载该地址。
第一步:安装依赖
按贡献者文档的最小步骤:
# 切换到 .nvmrc 指定的 nodejs 版本 nvm use # 安装依赖 npm i --legacy-peer-deps更省事的方式是执行仓库自带的一键脚本:
# 安装依赖并完成全部初始化 npm run setupnpm run setup实际调用 scripts/setup.js。从源码可以看到它做了四件事:
- 递归扫描并删除各子目录的
node_modules(保留tests/scripting/additional-context-roots/fixtures这类被测试当作 fixture 数据使用的目录); - 执行
npm i --legacy-peer-deps安装依赖; - 按平台强制安装
@lydell/node-pty对应的原生二进制包(darwin/win32/linux 各自 arm64/x64),这是 Electron 内嵌终端功能所需,也是后文Unsupported platform类问题的常见根源; - 依次构建全部内部包(见下一步说明),最后执行
npm run sandbox:bundle-libraries --workspace=packages/bruno-js打包 JS 沙箱内置库。
第二步:构建内部包
bn 文档给出的最小构建集是:
# 构建 GraphQL Docs 组件 npm run build:graphql-docs # 构建 Bruno Query 包 npm run build:bruno-query当前仓库的完整构建集(即npm run setup覆盖的范围)为:
npm run build:graphql-docs npm run build:bruno-query npm run build:bruno-common npm run build:bruno-converters npm run build:bruno-requests npm run build:schema-types npm run build:bruno-filestore # 打包 JS 沙箱库 npm run sandbox:bundle-libraries --workspace=packages/bruno-js这些命令都定义在根 package.json 的 scripts 中,本质都是对相应工作区转发npm run build。例如bruno-graphql-docs与bruno-query的构建入口都是rollup -c(见各自 package.json),产物输出到dist/供bruno-app与bruno-electron以@usebruno/*包名引用。
其中 JS 沙箱库的打包不是可选项:packages/bruno-electron/src/index.js#L9-L15 在开发模式下会检查bruno-js/src/sandbox/bundle-browser-rollup.js是否存在,若缺失会直接抛出 “JS Sandbox libraries have not been bundled yet” 错误并给出补执行命令。
第三步:启动应用
贡献者文档的标准做法是两个终端并行:
# 终端 1:启动前端应用(rsbuild dev server) npm run dev:web # 终端 2:启动 Electron 主进程 npm run dev:electron从源码看这条链路如何工作:
dev:web转发到packages/bruno-app的rsbuild dev;dev:electron转发到packages/bruno-electron的electron .;- Electron 侧 packages/bruno-electron/src/index.js#L356 读取环境变量
BRUNO_DEV_PORT(缺省为 3000)来确定前端页面地址。
仓库另提供两种更自动化的方式:
# 方式一:一条命令同时拉起前端与 Electron npm run dev # 方式二:带全链路热重载的开发模式 npm run dev:watchnpm run dev对应 scripts/dev.js:它先启动 rsbuild dev server,用正则Local:\s+http://localhost:(\d+)从 rsbuild 输出中自动探测实际端口,再以BRUNO_DEV_PORT=<端口>环境变量启动 Electron 子进程,两个进程任一退出时自动清理另一个。dev:watch(scripts/dev-hot-reload.js)则额外监视packages/**/dist/、bruno-electron/src、bruno-lang、bruno-js、bruno-schema等目录的变化并联动重启,适合修改底层库包时的开发。
定制 Electron 的 userData 路径
开发调试时经常需要隔离应用数据。若设置了环境变量ELECTRON_USER_DATA_PATH且处于开发模式,userData路径会被改写(packages/bruno-electron/src/index.js#L21-L26 中通过app.setPath('userData', ...)生效):
ELECTRON_USER_DATA_PATH=$(realpath ~/Desktop/bruno-test) npm run dev:electron这会在桌面创建bruno-test目录并作为 Electron 的userData,从而让偏好设置、工作区状态等与默认环境完全隔离——调试“脏”环境问题时非常有用。
常见问题:Unsupported platform 错误
贡献者文档的 Troubleshooting 一节指出:运行npm install时可能遇到Unsupported platform错误。原因是原生模块(典型如@lydell/node-pty)按平台分发可选二进制包,跨平台切换或 lockfile 残留会导致平台包缺失。文档给出的修复方法是删除所有node_modules与package-lock.json后重装:
# 删除子目录中的 node_modules find ./ -type d -name "node_modules" -print0 | while read -d $'\0' dir; do rm -rf "$dir" done # 删除子目录中的 package-lock.json find . -type f -name "package-lock.json" -delete之后重新npm install,npm 会按当前平台重新安装所有必需包。这与npm run setup的自动化行为一致——scripts/setup.js 中的forceInstallPlatformDeps函数正是通过按process.platform强制安装对应平台的@lydell/node-pty-<platform>-<arch>@1.1.0来保证原生依赖完整(注释中也强调这些包必须硬编码版本且已通过安全审计,因为是以--force强制安装的)。
运行测试
贡献者文档给出了两条测试命令:
# 运行 bruno-schema 的测试 npm test --workspace=packages/bruno-schema # 在所有工作区运行测试(仅执行存在 test 脚本的工作区) npm test --workspaces --if-present根 package.json 的完整脚本表还列出了各库包的独立执行方式(npm run test --workspace=packages/<name>),覆盖bruno-schema、bruno-query、bruno-common、bruno-converters、bruno-app、bruno-electron、bruno-lang、bruno-toml等。从各工作区的test脚本定义看,大多数包使用 Jest,细节各有不同:bruno-sqlite需要NODE_OPTIONS=--experimental-sqlite,bruno-converters会附带覆盖率收集,bruno-js与bruno-cli通过node --experimental-vm-modules启动 Jest 以支持 ESM。
除 Jest 单测外,仓库还维护了 Playwright 驱动的 E2E 测试体系,根 package.json 中按场景拆分了test:e2e(default + system-pac 项目)、test:e2e:ssl、test:e2e:auth、test:e2e:mock-server、test:e2e:sanity等脚本,用例位于 tests/ 目录,对应 playwright.config.ts 中的项目划分;test:codegen则通过 playwright/codegen.ts 生成操作代码。验证自己的改动时,建议先用npm test --workspaces --if-present做全量单测,再按改动范围选择对应的 E2E 项目。
Pull Request 与分支规范
贡献者文档对 PR 的要求非常明确:
- 保持 PR 小而专注:一个 PR 只做一件事;
- 遵循分支命名格式:
feature/[功能名]:该分支只包含某个具体功能的改动,例如feature/dark-mode;bugfix/[缺陷名]:该分支只包含针对某个具体缺陷的修复,例如bugfix/bug-1。
此外,仓库配置了 Husky + nano-staged 的提交钩子(根 package.json 中prepare: "husky"与nano-staged段),对*.{js,ts,jsx}文件在暂存时自动执行npm run lint:fix,因此提交前保持代码能通过 ESLint(eslint.config.js)是默认要求。
小结
Bruno 的贡献者开发环境围绕 npm workspaces 的多包结构展开:nvm use对齐 .nvmrc 的 Node 版本,npm i --legacy-peer-deps(或一键npm run setup)完成依赖与全部内部包构建,npm run dev:web+npm run dev:electron(或npm run dev/npm run dev:watch)完成双进程启动,ELECTRON_USER_DATA_PATH提供数据隔离调试能力,npm test --workspaces --if-present与 Playwright E2E 脚本构成验证闭环。遇到Unsupported platform错误时,清理node_modules与package-lock.json重装即可。完整命令与规范的权威来源仍以 contributing.md 及其各语言版本(如 docs/contributing/contributing_bn.md)为准。
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考