Arclet Copier 诞生的故事
🔄 English
起点
从大约 3 年前开始,我就一直使用 Arc 浏览器作为我最主力的浏览器,即使到后期 Arc 明确不会再有功能更新,仅提供内核安全性更新,我也坚持使用了很长时间,期间间歇性尝试过 Dia(不如 Arc 那样打动我)。直到 Atlassian 宣布收购了 The Browser Company,我计划彻底放弃了使用 Arc 和 Dia,兜兜转转又回到了 Chrome。
不过始终有一个让我头疼的问题是 Chrome 无法通过快捷键复制 URL,尤其是我非常习惯使用 Arc 的 cmd+shift+C
来复制 URL,而在切换到 Chrome 后我每天至少十几次在想要复制 URL 的时候打开了 Chrome 开发者工具。
我很清楚一定有浏览器扩展程序已经解决了这个问题,但是试用了好几个,不好看、不顺手、不好用,也有可能就是我想自己写一个,于是我用 Claude Code 很快就开发好了 Arclet Copier v0.1.0,一键复制当前网页的 URL,支持配置快捷键,默认清理 URL 跟踪参数。
在这个过程中我感受到很强烈的创造的快乐,以及 Claude Code 的聪明,于是我开始设计更多功能:
- 复制 Markdown 格式
- 集成短链接服务
- 生成二维码,复制二维码
- URL 清理模式切换,清理参数自定义
- 复制格式模板自定义
- 批量复制
- 更多……
我开始像对待一个正式产品一样对待 Arclet Copier,不断完善功能,打磨 UI/UX,上架应用商店,推广宣传。现在 Arclet Copier 已经开发到 v1.6.7 了,我设计的大部分功能都上线了,我也终于可以写下这篇文章来记录一下这段开发旅程。
我喜欢的功能
复制的稳定性
复制 URL 的成功率是 Arclet Copier 最核心的指标,一开始我使用的最常见的方案 —— 内容脚本注入(Content Script),在网页 DOM 注入一段 JavaScript 脚本来获取网页 URL 并复制到用户剪贴板。我曾经尝试过的大部分扩展程序都是这么做的,但是这有一个巨大的问题是在网页 DOM 没有准备好,或者在浏览器系统页面时,是无法成功注入脚本的,这会导致复制 URL 失败。
我想要实现一种接近于原生的复制效果,即用户在任何页面都应该能使用 Arclet Copier 成功复制 URL,这个问题把我和 Claude Code 卡了很久,最终我让 Claude Code 搜索 Chrome 最新的 API 以及广泛搜索网络内容来了解可能的解决方案。最终我们发现了 Offscreen Document API,这是 Chrome Manifest V3 引入的新 API,专门用于在后台执行需要 DOM 环境的操作。
传统的 Content Script 方案依赖于网页的 DOM 环境,这导致了三个主要问题:
- DOM 准备问题:在网页 DOM 没有准备好时,无法成功注入脚本;
- CSP 限制:许多网站的内容安全策略(Content Security Policy)会阻止外部脚本的执行;
- 系统页面限制:在
chrome://
或edge://
等浏览器系统页面无法注入脚本。
而 Offscreen Document API 的工作原理是:
// 在 background service worker 中创建一个隐藏的文档
await chrome.offscreen.createDocument({
url: 'offscreen/offscreen.html',
reasons: ['CLIPBOARD'],
justification: '复制文本到剪贴板'
});
// 通过消息传递将内容发送给 offscreen 文档
chrome.runtime.sendMessage({
action: 'copy',
text: urlToCopy
});
这个隐藏文档拥有完整的 DOM 环境和剪贴板访问权限,但不受网页 CSP 的限制,因为它运行在扩展的独立上下文中。这样一来,无论用户在什么页面,Arclet Copier 都能稳定地完成复制操作。
URL 参数清理
我设计了三种清理模式:
- 关闭(off):保留所有参数,适合技术性场景
- 智能(smart):只移除跟踪参数,保留功能性参数
- 激进(aggressive):移除所有参数,追求最简洁的 URL
更进一步,我还允许用户自定义参数规则。你可以把某个参数标记为「跟踪参数」或「功能性参数」,系统会记住你的偏好。
自定义复制模板
一开始只提供了 URL 和 Markdown 格式的复制,但是用户的复制需求非常多样化:
- 有人想要
[标题](URL)
的 Markdown 格式 - 有人想要
标题 - URL
的纯文本格式 - 有人想要带时间戳的归档格式
- 还有人想要各种奇奇怪怪的自定义格式
于是我实现了一个模板引擎,支持一些常用变量,让用户可以自己创建模板,比如:
{{title}} 👉 {{url}}
Arc 风格的 Toast
由于我真的很喜欢 Arc 浏览器(很显然通过 Arclet 这个名字也能体现这一点),所以我在 Arclet Copier 中一些 UI 设计都有参考 Arc,想要做到 Arc 那种质感,不过很显然我没有做到,好想学会 UI 设计。
一开始我通过 Chrome 系统通知来同步 URL 复制结果,对于多屏用户,这个通知显得很烦人,用户在屏幕 A 复制网页,通知从屏幕 B 出现(因为屏幕 B 是主屏幕),所以我又通过内容脚本注入,在当前网页的右上角注入一个 Arc 风格的通知 toast,我真的很喜欢这个小 toast。
但是这种方式依然受限于网页 DOM 是否准备好,在一些特殊页面(如浏览器内置页面)无法显示。我还没有找到完美的解决方案,只能先忍一忍了。😭
从个人工具到产品
最初 Arclet Copier 只是一个解决我自己痛点的小工具,但在开发过程中我逐渐将它当作一个正式产品来打磨:
- 国际化
- 主题系统
- 性能优化
为了保证代码质量,我还引入了(不过是在开发很后期进行的,前期主要多堆功能):
- Vitest 测试框架:覆盖核心模块的单元测试
- ESLint 代码规范:保持代码风格一致
- esbuild 构建工具:快速的打包和开发体验
Claude Code 协作心得
Arclet Copier 99% 以上的代码都是 Claude Code 写的,主要使用 Claude 和 GLM 的模型,整个项目开发到现在大概消耗了 5 亿 tokens,真的不算便宜。我也实践出几点建议可以分享:
- 单个对话主题要集中:避免在一个上下文环境中开发完全没有关联的不同功能,会给 AI 造成干扰。但是可以开多个对话同时进行不同功能开发。
- 使用
\init
命令创建 CLAUDE.md:完成一个阶段的开发或者功能设计后,让 AI 沉淀文档到项目中。这个 CLAUDE.md 会在后续对话中作为项目说明,有助于 AI 快速了解项目架构。 - 善用网络搜索:面对复杂问题、多次尝试解决不了的问题,直接让 AI 主动进行网络搜索。比如 Offscreen API 就是通过搜索最新的 Chrome 文档找到的。
- 先分析,再动手:让 AI 先分析问题,提供解决方案给你确认,然后再让 AI 进行开发。这样可以避免走弯路。
- 大任务拆解 TODO:对于大型任务,可以让 AI 创建一个 TODO List 给你确认,然后再让 AI 一边开发一边更新 TODO List,直到所有任务完成。
- 保持代码审查意识:虽然 AI 写的代码大部分时候都很好,但还是要 review 一下,尤其是涉及安全、性能的关键部分。可以另起一个对话让 AI 来 review。
另外:
Arclet Copier 已经上架了 Chrome Web Store 和 Edge Add-ons,完全免费,更多信息可访问 官网 了解。
欢迎下载使用,有任何 Bug 反馈或功能建议请通过 GitHub Issues 或邮件联系我。如果觉得有用,不妨给项目点个 Star ⭐️ 或者在应用商店留个五星好评。❤️