- 桌面应用
【免费下载链接】EcoPaste
🎉跨平台的剪贴板管理工具 | Cross-platform clipboard management tool
本文基于 EcoPaste 仓库的 CONTRIBUTING.zh-CN.md 贡献指南,系统讲解这个跨平台剪贴板管理器的项目状态、平台范围、Rust-First 架构边界、完整技术栈、开发环境搭建、质量检查流程与仓库结构。读完本文,你将掌握 EcoPaste 的开发环境搭建方法、前端与 Rust 后端各自的职责边界、跨层常量与事件契约的维护规则,以及一套可直接复用的代码提交与质量保障流程。
项目状态:正式发布通道下的演进纪律
EcoPaste 已进入正式发布(stable)通道。这一状态对贡献者有明确约束:后续变更应当直接演进当前应用,而不是另起炉灶;凡是涉及已发布用户数据的存储、设置或数据库契约变化,都必须提供 migration 或升级处理,不能静默破坏既有数据。
仓库中的 src-tauri/migrations/0001_init.sql 是这一纪律的直接体现——它定义了clipboard_groups、clipboard_apps、clipboard_items、file_type_icons等表结构,并针对clipboard_items建立了 FTS5 虚拟表clipboard_items_fts及三个同步触发器(AFTER INSERT、AFTER DELETE、AFTER UPDATE),支撑search_text、note字段的全文检索。从源码结构看,后续任何 schema 演进都应追加新的 migration 文件(0002_*.sql等),而不是修改已发布的0001_init.sql。
平台范围:仅 macOS 与 Windows
EcoPaste仅支持 macOS 与 Windows,Linux 不在支持范围内。这意味着:
- 新增代码不得引入 Linux 特有实现;
- 新增依赖不得针对 Linux 平台;
- 构建产物与文档宣传都应聚焦 macOS 与 Windows。
这一点在源码中有大量印证。例如 src-tauri/src/lib.rs 中,keyboard、mouse模块都以#[cfg(target_os = "windows")]条件编译(Windows 专属的 OS 级键盘/鼠标钩子),而 macOS 专属的tauri_plugin_macos_permissions插件、window::macos::register_plugin与setup_clipboard_panel均以#[cfg(target_os = "macos")]隔离。贡献者新增平台能力时,应沿用这种条件编译隔离,并尽量两端同步实现。
修改代码前必读
单一真相源:AGENTS.md
贡献指南明确要求:动手改代码前先读 AGENTS.md。该文件是本仓库架构边界、平台范围、编码规范和质量要求的单一真相源,本贡献指南中的规则都可在其中找到更细化的条款,包括 Rust 错误处理约定(AppError序列化为{ kind, message })、SQL 必须用sqlx::query/query_as而非query!宏、依赖版本写法、React 组件规范(FC<Props>、禁止新增forwardRef、箭头函数一律显式return)等。
尊重工作区状态
请尊重当前工作区(dirty worktree)状态,不要覆盖或回滚并非由你产生的改动。需要改动已修改文件时,先读清楚再动。
提交信息规范
提交信息使用单行 Conventional Commits,例如:
feat: add clipboard group pinning fix: correct FTS search on note field refactor: move storage location logic to rust docs: update contributing guide常见的类型前缀包括feat:、fix:、refactor:、docs:。仓库的 lint-staged.config.ts 与 simple-git-hooks.json 在提交阶段自动执行 lint 与格式化检查,保证提交质量。
架构:Rust-First 的 Tauri v2
EcoPaste 采用Rust-First 的 Tauri 架构,核心思想是:业务逻辑、原生能力、数据库访问、存储、设置持久化和平台集成一律优先放在 Rust 侧;React 前端只负责渲染、交互与 UI 状态。
模块职责划分
| 模块 | 职责 |
|---|---|
src-tauri/src/clipboard/ | 剪贴板采集、内容识别、写回、来源应用、资源落盘、监听回环抑制 |
src-tauri/src/db/ | SQLite 仓储、模型、迁移、FTS 搜索 |
src-tauri/src/settings/ | 设置模型与持久化 |
src-tauri/src/window/ | 窗口状态、定位、生命周期 |
src-tauri/src/shortcut/ | 全局快捷键 |
src-tauri/src/tray/ | 托盘菜单 |
src-tauri/src/menu/ | 列表项右键菜单 |
src-tauri/src/autostart/ | 开机自启 |
src-tauri/src/backup/ | 备份导入导出 |
src/ | React UI、Ant Design 组件、UnoCSS 样式、Valtio 状态镜像、i18n 资源、类型化 Tauri command 封装 |
从 src-tauri/src/clipboard/mod.rs 可以看到,剪贴板模块内部又细分为watcher(监听)、read/write(读写)、detect(内容识别)、ingest(入库)、storage(图片落盘)、source(来源应用)、guard(写回防护)等十余个子模块;而 src-tauri/src/db/mod.rs 则暴露了init(初始化)、db_path(数据库路径)、DatabaseState(连接池状态)三个公共接口,仓储层单测通过内存数据库连接池(sqlite::memory:+foreign_keys(true)+ 完整跑 migrations)验证ON DELETE SET NULL等外键行为。
前端 ↔ Rust 的通信契约
前端通过Tauri command调用 Rust,Rust 则通过命名空间事件向前端推送刷新信号。事件名统一采用domain://action形式,例如:
clipboard://updated— 剪贴板数据更新settings://updated— 设置变更window://visibility— 窗口可见性变化
前端侧的事件名集中维护在 src/constants/events.ts(TAURI_EVENT常量表,含clipboard://menu-action、keyboard://nav、preview://updated等共 13 个事件);对应的命令名常量集中在 src/constants/commands.ts(TAURI_COMMAND,覆盖剪贴板读写、分组管理、备份、更新、窗口、设置等 70+ 命令)。根据 src/commands/index.ts 的约定,业务代码一律import { foo } from "@/commands"调用类型化包装函数,禁止裸调invoke或引用常量表字面量。
跨层常量镜像规则:command 名、事件名、channel、storage key 等跨层复用的字面量,需要同时维护 Rust 常量与src/constants/下的镜像,两端保持一致,避免魔法字符串漂移。
技术栈一览
| 维度 | 选型 |
|---|---|
| 桌面外壳 | Tauri v2 |
| 前端 | React 19、Ant Design 6、UnoCSSpresetWind4 |
| 状态 | Valtio(仅用于 UI 状态与设置镜像) |
| 后端 | Rust、sqlx、SQLite |
| 构建 | Vite、pnpm |
| 质量 | Biome、TypeScript、rustfmt、clippy、cargo test |
仓库 package.json 中engines字段与packageManager字段(pnpm@10.33.1)分别声明了 Node ≥ 20、pnpm ≥ 10 与 pnpm 10 的版本约束;前端依赖包含@tauri-apps/api、antd、react-virtuoso(虚拟滚动列表)、valtio、i18next等。Rust 侧依赖(sqlx、thiserror、anyhow、tauri-plugin-log、tauri-plugin-global-shortcut、tauri-plugin-single-instance、tauri-plugin-updater 等)可在 src-tauri/Cargo.toml 中查看。
开始开发
环境要求
| 项 | 要求 |
|---|---|
| 操作系统 | macOS 或 Windows |
| Node.js | 20 或更高版本 |
| pnpm | 10 或更高版本 |
| Rust | rust-toolchain.toml 指定的工具链(1.96.0,含rustfmt、clippy) |
| 系统依赖 | Tauri v2 所需的原生依赖,参考对应系统平台的 Tauri prerequisites 文档 |
仓库根目录的 rust-toolchain.toml 实际内容为:
[toolchain] channel = "1.96.0" components = ["rustfmt", "clippy"] profile = "minimal"profile = "minimal"意味着只安装编译与代码检查所需的最小组件集;当切换分支后,rustup会自动按该文件解析并安装对应工具链。此外,开发流程文档以 Trellis 工作流(Trellis 文档)为准,仓库中的.trellis/目录承载分阶段 backlog。
安装依赖
pnpm install由于 package.json 中配置了preinstall: npx only-allow pnpm,该命令会强制校验包管理器为 pnpm,使用 npm/yarn 安装会被直接拦截——这保证了锁文件(pnpm-lock.yaml)与 workspace 的一致性。
开发运行
pnpm tauri dev该命令会同时启动 Vite 前端开发服务器与 Tauri 桌面外壳(Debug 模式)。从 src-tauri/src/lib.rs 看,Debug 模式下tauri_plugin_log会额外启用 Stdout 与 Webview 日志目标,方便在前端 devtools console 中查看 Rust 侧日志。
构建
pnpm tauri build生产构建会产出各平台的安装包与安装器(macOS 的.dmg/.app,Windows 的安装程序),并可配合 Tauri 的签名与更新机制使用。
质量检查
贡献指南给出了前后端两套质量检查命令。
前端检查
pnpm lint pnpm tscpnpm lint对应biome check,由 biome.json 配置驱动。该配置开启了recommended规则集,并将noConsole(禁止裸console.*)、noUnusedImports、noUnusedVariables、useSortedClasses(UnoCSS 类名排序)、useSelfClosingElements等设为 error 级别。pnpm tsc对应tsc --noEmit,由 tsconfig.json 驱动,做全量类型检查。
Rust 检查
cd src-tauri cargo fmt cargo clippy -- -D warnings cargo testcargo fmt:按 rustfmt.toml 格式化代码;cargo clippy -- -D warnings:将任何 clippy 警告提升为错误,强制零警告;cargo test:运行单元测试与集成测试。剪贴板相关测试因触碰系统剪贴板这一全局资源,在 src-tauri/src/clipboard/mod.rs 中通过一个静态Mutex(test_lock::serial())串行执行,避免并行测试相互覆盖系统剪贴板内容。
前端格式化
pnpm format对应biome check --write,会自动修复可安全修复的 lint 问题(排序、自闭合标签、模板字符串等)。
仓库结构
src-tauri/ src/ commands/ # Tauri command 入口 clipboard/ # 剪贴板读写、采集、识别、存储 db/ # SQLite 仓储、模型、迁移 settings/ # 设置模型与持久化 window/ # 窗口状态、定位、生命周期 shortcut/ # 全局快捷键 tray/ # 托盘菜单 menu/ # 列表项右键菜单 backup/ # 备份导入导出 i18n/ # Rust 侧用户可见文案 migrations/ src/ commands/ # 类型化 Tauri invoke 封装 components/ # 共享 React 组件 constants/ # 跨层复用常量镜像 hooks/ # 共享 hooks locales/ # zh-CN 和 en-US 翻译 pages/ # Clipboard、Preference、Preview、ContextMenu stores/ # Valtio UI 状态与设置镜像 types/ # TypeScript 契约镜像对照实际目录可验证:
src-tauri/src/commands/下现有admin.rs、autostart.rs、backup.rs、clipboard.rs、context_menu.rs、drag.rs、link.rs、onboarding.rs、settings.rs、storage.rs、update.rs、window.rs等命令模块;src-tauri/src/clipboard/下按职能拆分为watcher.rs、read.rs、write.rs、detect.rs、ingest.rs、storage.rs、source.rs、guard.rs、sound.rs等;src/前端侧包含pages/Clipboard、pages/Preference、pages/Preview、pages/ContextMenu四个页面域,stores/下是 Valtio 状态(settings.ts、clipboardView.ts等);- 双语语言资源
locales/zh-CN/与locales/en-US/各含clipboard、commands、common、onboarding、preferences、preview、update七组 JSON。
贡献检查清单
贡献指南最后给出了一份可直接对照执行的行为清单,是提 PR 前的最终自检:
- 职责归属:除非现有架构明确要求放在其它层,业务逻辑、原生能力、数据库访问、存储、设置持久化和平台集成都应放在 Rust。
- React 职责收窄:React 侧专注于渲染、交互、UI 状态、前端 i18n 和预览。
- 常量镜像同步:command 名、事件名、channel、storage key 等跨层复用常量,需要同时维护 Rust 常量与
src/constants/镜像。 - migration 纪律:已发布 schema 变更必须新增 migration,不要直接修改已发布 migration。
- 双语同步:前端用户可见文案需要同步更新
zh-CN(默认)和en-US语言资源。 - Rust 侧文案:托盘、原生菜单、命令返回 toast 等 Rust 侧短文案走
i18n/模块。 - 验证范围:针对改动范围运行检查;触及共享行为或跨层契约时,需要扩大验证范围(例如改动剪贴板事件契约后,前端命令封装、常量表与 Rust 侧 emit 端都要回归验证)。
总结
对 EcoPaste 贡献者而言,本指南浓缩为三条核心纪律:Rust-First 的职责划分(前端只做渲染交互,其余交给 Rust)、双端契约的集中维护(命令名/事件名/存储 key 在 Rust 与src/constants/同步镜像)、发布数据的迁移纪律(已发布契约不回改,schema 变更只追加 migration)。开发时按「安装依赖 →pnpm tauri dev开发 →pnpm lint/pnpm tsc/cargo fmt/cargo clippy/cargo test质量检查 →pnpm tauri build构建」的流程推进,配合单行 Conventional Commits 提交,即可与项目既有工程规范无缝衔接。
- 桌面应用
【免费下载链接】EcoPaste
🎉跨平台的剪贴板管理工具 | Cross-platform clipboard management tool
相关推荐
旧Mac免费安装macOS 11到15:OpenCore Legacy Patcher完整上手指南
旧Mac免费安装macOS 11到15:OpenCore Legacy Patcher完整上手指南 OpenCore Legacy Patcher 是一款免费开
桌面应用Spacedrive V2 贡献指南:Rust-First 架构下的环境搭建、开发流程与 V1 迁移全解
Spacedrive V2 贡献指南:Rust First 架构下的环境搭建、开发流程与 V1 迁移全解 Spacedrive 是一个用 Rust 编写、以虚拟
桌面应用移动开发后端存储数据同步EcoPaste 工程架构与开发规范:Rust-First 的 Tauri 跨平台剪贴板管理器实战指南
EcoPaste 工程架构与开发规范:Rust First 的 Tauri 跨平台剪贴板管理器实战指南 本文以 EcoPaste 仓库根目录的 AGENTS.m
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考