- 桌面应用
- 音视频
【免费下载链接】BiliTools
本项目已停止维护。
BiliTools 是一款基于 Tauri 2 + Vue 3 + Rust 的跨平台哔哩哔哩工具箱(桌面应用与独立文档站点并存)。本篇指南以仓库根目录的 CONTRIBUTING.md 为骨架,完整梳理项目的问题反馈渠道、Pull Request 提交规范、前后端开发环境搭建、文档开发流程、提交前质量检查清单,并结合仓库源码(package.json、src-tauri/src/lib.rs、docs/config.ts 等)解释每一项规范背后的工程原因。读完本文,你将能独立完成一次从"发现问题 → 提交 Issue → 本地开发 → 质量检查 → 提交 PR"的完整贡献闭环。
一、贡献总览:两种参与路径
BiliTools 的贡献指南将参与方式分为两类,各自对应不同的通道与处理优先级:
| 场景 | 通道 | 要求 |
|---|---|---|
| 功能请求(Feature Request)或 bug 报告 | 创建 Issue | 使用官方 Issue 模板,尽可能提供详细复现步骤 |
| 一般性问题求助(如"xxx 无法下载""xxx 报错") | 发起 Discussion | 不属于明确的 bug 或功能需求,进入讨论区交流 |
指南明确要求不要在 Issues 中提交与项目无关的内容,这是保证 issue 列表可检索、可追踪、可被后续贡献者复用的基础。同时,由于项目属于免费公益性质、维护者时间与精力有限,无法承诺所有问题都能被快速处理——这要求贡献者在提问前尽量做到问题描述清晰准确、错误信息充足,否则维护者将很难定位与复现问题。
从仓库现状看,docs/config.ts 的导航配置中专门设有"参与贡献"入口(指向仓库根目录的CONTRIBUTING.md),说明该指南是项目对外协作的官方入口,与文档站、更新日志并列,是贡献者入门的第一份材料。
二、Pull Request 规范:分支、签名与提交信息
分支策略:只提交dev,不提交master
PR 必须提交至主仓库的dev分支,禁止提交至master分支。这是典型的两分支策略:master仅承载稳定发布版本,dev汇聚所有开发中的变更,经合入与验证后才会发布。为dev之外的长期分支或master直接提 PR 会被要求修改目标分支。
所有提交必须签名(Signed-off)
"所有提交必须签名"意味着每个 commit 都需要通过 Git 的--signoff机制(或配置 GPG/SSH 签名)附带签名信息,用于声明代码来源与作者授权。签名是开源项目常见的法律与追溯手段,请在提交前确认你的本地 Git 已正确配置签名。
约定式提交(Conventional Commits)
所有提交信息必须遵循约定式提交规范,即type: description的结构。指南给出了五种示例:
| type | 示例 | 语义 |
|---|---|---|
feat | feat: add notifications support for macOS | 新增功能 |
fix | fix: ffmpeg path handling issue | 修复缺陷 |
chore | chore: cleanup unused assets | 杂务(清理、构建配置等) |
refactor | refactor: simplify error handling | 重构但不改变行为 |
docs | docs: update install guide | 文档变更 |
pref | pref: improve playurl parsing speed | 性能优化 |
注:
pref是约定式提交中的非标准 type,属于本项目自定义的惯用写法(对应常规的perf),在参与提交时建议沿用仓库现有风格。描述部分使用祈使句、小写开头,聚焦"做了什么"而非"做了什么以及为什么"。
标准化的提交信息直接服务于自动化工具链:本项目 scripts/updatelog.mjs 用于生成更新日志(对应pnpm ci:updatelog),scripts/binaries.mjs 负责管理随包分发的二进制资源,规范的提交信息能让这些脚本稳定解析变更类型。
PR 提交流程
- Fork 主仓库并克隆到本地;
- 为更改创建独立的新分支(建议按功能或修复命名,如
feat/xxx、fix/xxx); - 按照上述约定式提交规范逐条提交更改;
- 将分支推送到你的 Fork,随后在主仓库基于
dev分支打开 Pull Request。
三、开发环境搭建:版本门槛与平台依赖
BiliTools 是 Tauri 2 桌面应用(前端 Vue 3 + 后端 Rust),开发环境需要同时满足两端要求。指南明确列出两个硬性版本门槛:
- Rust 1.80.0+:后端语言最低版本,低于该版本将无法通过编译;
- Node.js 20.0+:前端工具链最低版本,与根目录 package.json 中
"engines": { "node": ">=20.0.0" }的声明一致; - 包管理器为pnpm(仓库根目录 package.json 声明
"packageManager": "pnpm@10.25.0",并由 pnpm-workspace.yaml 定义 workspace)。
环境搭建请参照 Tauri 官方文档的前置依赖说明(各平台所需的系统级依赖:Windows 的 WebView2、macOS 的 Xcode Command Line Tools、Linux 的 webkit2gtk 等)。若对具体版本命令有疑问,可对照 src-tauri/Cargo.toml 与 package.json 的依赖声明。
Ubuntu 系统额外依赖
在 Ubuntu 上,除 Tauri 通用前置依赖外,还需安装以下包:
sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-libappindicator3-dev librsvg2-dev patchelflibwebkit2gtk-4.1-dev:WebView 渲染引擎开发头文件(Tauri 2 在 Linux 上依赖 WebKitGTK 4.1);libayatana-libappindicator3-dev:系统托盘(Tray)与 AppIndicator 支持;librsvg2-dev:SVG 渲染支持(用于应用图标与界面资源);patchelf:发布打包时调整 ELF 二进制 rpath 的工具,Tauri 打包流程必需。
四、App 开发工作流:安装、启动与构建
在项目根目录执行以下三步即可完成从安装到构建的完整开发循环:
# 1. 安装前端依赖 pnpm install # 2. 启动开发服务器(会同时拉起 Tauri 窗口与 Vite HMR) pnpm dev # 3. 构建发布版本 pnpm build这三条命令在根目录 package.json 中均有对应脚本定义:
"dev": "cross-env RUST_BACKTRACE=1 tauri dev":开启 Rust 回溯信息便于调试,并调用tauri dev;"build": "tauri build":完整构建桌面发布产物;另有"build:debug": "tauri build --debug"可产出调试构建;pnpm dev实际由 Vite 承载前端:见 vite.config.ts,其开发服务器固定使用1420 端口(strictPort: true,端口被占用会直接失败),HMR 走 1421 端口(WebSocket),且配置了ignored: ['**/src-tauri/**']让 Vite 忽略 Rust 目录的变更监听。
从源码结构看,Tauri 进程的入口分为两层:src-tauri/src/main.rs 仅做平台窗口属性设置(Release 下 Windows 隐藏控制台)并调用bilitools_lib::run();真正的初始化逻辑在 src-tauri/src/lib.rs,其中:
- 通过
collect_commands!注册了init、config_write、sms_login、submit_task、plan_scheduler等约二十个后端命令; - 在 debug 构建下使用
tauri-specta将 Rust 类型自动导出为 TypeScript 绑定到 src/services/backend.ts,这意味着修改后端命令后,前端类型提示会自动同步,这也是为什么贡献前端代码时无需手写重复的类型定义; - 注册了 log、clipboard、dialog、http、notification、opener、os、process、shell、single-instance、updater 等插件;
setup中异步执行storage::init()与services::init(),后者在 src-tauri/src/services.rs 中会依次初始化aria2c与ffmpeg并做可用性测试。
如果你只调试前端而不想拉起桌面窗口,还可以使用pnpm web:dev(纯 Vite)、pnpm web:build(vue-tsc --noEmit && vite build,含类型检查)、pnpm web:preview。
五、文档开发:基于 VitePress 的独立 workspace
项目文档是一个独立的 VitePress 站点,位于根目录docs文件夹,且作为 pnpm workspace 的子包(名为@btjawa/bilitools-docs,见 docs/package.json)。
# 启动文档开发服务器(带热更新) pnpm docs:dev # 构建文档站点 pnpm docs:build两条命令经由根目录 package.json 转发到子包:
"docs:dev": "pnpm --filter @btjawa/bilitools-docs dev"(即vitepress dev .);"docs:build": "pnpm --filter @btjawa/bilitools-docs build"(即vitepress build .);- 另有
pnpm docs:preview可预览构建产物。
文档站点的主题配置位于 docs/config.ts:站点语言为 zh-CN,标题为 "BiliTools",侧边栏按"快速开始 / 须知 / 资源下载 / 工具箱 / 设置页 / 常见问题"组织导航,并开放了editLink(在 GitHub 上编辑此页)与lastUpdated(最后更新于)功能——这意味着为文档贡献内容时,应保持与现有指南目录(docs/guide)一致的组织方式,例如补充功能说明时优先考虑归入对应指南页,而非另起孤立的页面。贡献文档同样需要遵循约定式提交(docs: ...),且文档属于"参与贡献"的一部分,质量要求与代码一致。
六、提交前质量检查:四道关卡
无论贡献代码还是文档,在提交更改前必须依次运行以下四个命令并确保全部通过:
pnpm lint # ESLint 静态检查前端代码 pnpm format # Prettier 全仓格式化 pnpm clippy # Rust Clippy 严格检查 pnpm rustfmt # Rust 代码格式化对照根目录 package.json 可看到这些脚本的精确实现:
"lint": "eslint src":仅对src目录执行 ESLint;"lint:fix": "eslint src --fix"可自动修复。配套的 eslint.config.ts 是扁平化(flat config)配置,集成了typescript-eslint与eslint-plugin-vue;"format": "prettier --write .":对整个仓库运行 Prettier;"format:check": "prettier --check ."可在 CI 中做只读校验;"clippy": "cargo clippy --manifest-path ./src-tauri/Cargo.toml --all-targets --all-features -- -D warnings":以-D warnings(warning 升级为 error)的严格模式检查 src-tauri 下所有 target 与 feature,任何 lint 警告都会导致失败;"rustfmt": "cargo fmt --manifest-path ./src-tauri/Cargo.toml";对应只读校验为"rustfmt:check": "cargo fmt --manifest-path ./src-tauri/Cargo.toml --check",配合 src-tauri/rustfmt.toml 使用。
这四道关卡在语义上分别覆盖:前端语法与规范(lint)、全仓格式统一(format)、Rust 代码质量(clippy)、Rust 格式(rustfmt)。全部通过后,再按上文"Pull Request"章节提交。
七、技术选型与代码风格:前后端各有章法
前端:TypeScript 优先 + Composition API
贡献指南的前端要求可以浓缩为两条原则:
原则一:优先 TypeScript 而非 JavaScript。理由是其更强的类型系统能在开发阶段发现潜在错误、提升可维护性。落实为两条硬性写法:
- 使用
.ts文件而非.js文件; - 在
.vue文件中为<script>标签添加lang="ts"属性:
<script lang="ts"> </script>原则二:使用 Composition API 而非 Options API。落实方式是为<script>标签添加setup属性:
<script lang="ts" setup> </script>这一风格在仓库中得到普遍践行。以通用开关组件 src/components/Switch.vue 为例,它正是<script lang="ts" setup>写法,并通过defineModel<boolean>()实现 v-model 双向绑定;全局搜索显示,src/components 下的Popup.vue、Queue.vue、Scheduler.vue、Task.vue、Filter.vue、MediaList.vue、ContextMenu.vue等绝大多数 Vue 组件均采用该写法。此外:
- 前端状态管理采用 Pinia,见 src/store/index.ts,其中
useAppStore、useQueueStore、useSettingsStore、useUserStore、useComponentsStore按业务域拆分; - 路由配置集中在 src/router/index.ts,注册了
userPage、searchPage、historyPage、downPage、settingsPage、infoPage六个视图; - 后端自动导出的类型绑定 src/services/backend.ts 为前端提供了带类型的 invoke 封装,贡献前端代码时应直接复用这些类型,而不是另写
any。
后端:anyhow 错误体系,远离 unwrap
Rust 后端的代码风格要求:
- 优先使用
anyhow::Result代替标准库Result,利用其轻量的错误上下文能力; - 尽量少用
unwrap(),改用?运算符向上冒泡传递错误; - 关键逻辑使用
anyhow::Context添加报错上下文,让错误链可读、可定位。
这一规范与仓库的错误处理架构完全对应:自定义错误类型TauriError定义在 src-tauri/src/errors.rs,它通过impl From<E> for TauriError where E: Into<anyhow::Error>将任何anyhow::Error自动转换为携带code、message、stack三字段的前端可读错误结构(stack字段还会用正则对 backtrace 做裁剪,只保留bilitools_lib内部帧,避免向用户暴露过长的系统级堆栈)。也就是说:贡献者在 Rust 端写好?与.context(...),最终错误会以结构化形式传到前端展示。与之配套,src-tauri/src/services.rs 中aria2c::init()、ffmpeg::test()均返回anyhow::Result,并在初始化失败时通过process_err包装错误。
代码示例合规自查
提交 Vue 代码前,可对照上文模板自查:
<script lang="ts" setup> // 使用 TypeScript + Composition API const visible = defineModel<boolean>({ default: false }); </script>八、关于 AI:可辅助,不可代劳
指南对 AI 辅助开发给出了明确边界:请勿提交完全由 AI 生成、且未经本人理解、测试与检查的代码。AI 工具可以提升开发效率,但不应负责编写全部代码。最终提交的代码必须满足:
- 符合项目整体的代码风格(即上文第七节的 TS/Composition API/anyhow 规范);
- 经过充分测试、检查与验证(对应第六节的四道质量关卡,以及功能层面的实际运行验证);
- 可以由作者本人清楚解释其实现逻辑(可解释性是代码可维护与可 review 的前提)。
这一政策与开源协作的 review 机制互为表里:代码最终会由维护者在 PR 中审阅,只有作者真正理解并验证过的代码,才能在评审中经得起追问、在后续维护中经得起演进。
九、贡献者行动清单
将上文内容压缩为一份可直接执行的清单:
- 确定通道:明确 bug/功能 → 开 Issue 并提供复现步骤;一般求助 → 发 Discussion;勿在 Issues 中发无关内容。
- 准备环境:Rust 1.80.0+、Node.js 20.0+、pnpm;Ubuntu 额外安装
libwebkit2gtk-4.1-dev libayatana-libappindicator3-dev librsvg2-dev patchelf。 - 本地开发:
pnpm install→pnpm dev(或按需pnpm web:dev);文档类改动使用pnpm docs:dev。 - 自测与格式化:
pnpm lint、pnpm format、pnpm clippy、pnpm rustfmt四连通过(clippy 为-D warnings严格模式)。 - 提交:commit 全部签名;信息遵循约定式提交(
feat/fix/chore/refactor/docs/pref);从 Fork 的新分支向主仓库dev分支发起 PR。 - 对 AI 生成代码负责:确保自己理解、测试并能为实现逻辑作出解释。
遵循上述流程,你的每一次贡献——无论是修复一个 aria2c 路径处理问题(对应fix: ffmpeg path handling issue这类提交),还是补一篇安装指南(对应docs: update install guide),都能被项目快速接纳并沉淀到下一个发布版本中。
- 桌面应用
- 音视频
【免费下载链接】BiliTools
本项目已停止维护。
相关推荐
Argilla 开源贡献指南:从 Issue 提报到 PR 合并的完整工作流
Argilla 开源贡献指南:从 Issue 提报到 PR 合并的完整工作流 本篇指南围绕 Argilla 仓库的官方贡献文档( docs/_source/co
数据标注人工智能NLPMLOpsRAGMCP Python SDK 贡献指南:从 Issue 提报到 PR 合并的完整开发流程
MCP Python SDK 贡献指南:从 Issue 提报到 PR 合并的完整开发流程 导读 本文是 CONTRIBUTING.md https://link
人工智能MCP 服务MCP Clientsjsdiff开发贡献指南:从Issue提交到PR合并的完整流程
jsdiff开发贡献指南:从Issue提交到PR合并的完整流程 项目概述 jsdiff是一个JavaScript文本差异比较库(A javascript tex
开发者工具版本控制
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考