- 开发工具
【免费下载链接】web-clipper
For Notion,OneNote,Bear,Yuque,Joplin。Clip anything to anywhere
本文围绕开源仓库 web-clipper 的核心文档展开,系统讲解这款“将网页上的一切保存到任何地方”的浏览器剪藏扩展的安装方式、开发调试流程与测试方法,并结合仓库源码剖析其插件化扩展体系、后端服务架构与构建打包原理,帮助读者快速上手使用,并为二次开发提供源码级参考。
Web Clipper 是一个开源的通用网页剪藏扩展(Universal open source web clipper),支持将网页内容保存到 FlowUs、Obsidian、GitHub、语雀、Notion、有道云笔记、OneNote、Bear、Joplin、滴答清单、Wolai、Flomo、思源笔记、Confluence 等众多笔记与知识管理平台。仓库采用 TypeScript + React 编写,通过插件化架构将“页面内容提取”与“文档写入”解耦,实现了“Clip anything to anywhere”的设计目标。本文基于 README.md 的官方说明,结合 package.json、webpack/webpack.dev.js、webpack/webpack.common.js、script/release.ts 及 src/extensions 等源码文件,完整还原安装、开发、测试流程,并深入解读底层实现。
一、项目概览:把网页上的任何内容保存到任何地方
You can use Web Clipper to save anything on the web to anywhere.
这是 README 对项目能力最凝练的概括。Web Clipper 的核心价值在于两点:
- 抓取能力强:内置完整页面、选中区域、截图、全文提取(Readability)、二维码、选择工具等多种剪藏方式;
- 投递范围广:通过统一的后端服务抽象(DocumentService),把剪藏内容写入十余种笔记平台。
从 package.json 可以看到项目版本为1.42.0,采用GPL-2.0-or-later许可证,作者为 DiamondYuan。依赖中值得关注的技术选型包括:
- UI 层:React 17、antd 4.16.3、dva(基于 redux-saga 的状态管理)、mobx;
- 内容转换:
@web-clipper/readability(正文提取)、@web-clipper/turndown与turndown(HTML 转 Markdown)、@web-clipper/highlight(页面元素高亮选择)、@web-clipper/area-selector(区域选择)、showdown(Markdown 渲染); - 基础设施:typedi(依赖注入容器)、
@web-clipper/chrome-promise(Chrome API 的 Promise 封装)、webdav(WebDAV 协议客户端)、umi-request(HTTP 请求层)。
二、支持平台(Support Site)
README 官方列出的剪藏目标平台如下:
- FlowUs
- Obsidian
- Github
- Yuque
- Buildin.AI
- Notion
- Youdao
- OneNote
- Bear
- Joplin
- Server Chan
- dida365
- baklib
- wolai
- Leanote
- Flomo
- Siyuan
- Ulysses
- Confluence
这些平台在源码中均有对应实现。以src/common/backend/services目录为例,每个平台是一个独立子目录,包含index.ts(服务元数据声明)、service.ts(文档服务实现)、form.tsx(配置表单)等文件。例如:
- 语雀:src/common/backend/services/yuque/index.ts 声明了
type: 'yuque'的服务元数据,并通过permission字段申请https://www.yuque.com/*的站点访问权限; - Joplin:src/common/backend/services/joplin/index.ts 通过
permission申请http://localhost:41184/*,对应 Joplin 本地 Web Clipper API 服务端口; - WebDAV:src/common/backend/services/webdav/service.ts 使用
webdav包创建客户端,把剪藏内容以<标题>.md文件形式写入服务器目录。
三、安装(Install)
3.1 从应用商店安装
官方推荐从浏览器应用商店直接安装:
- Chrome:访问 Chrome 网上应用商店安装 Web Clipper(扩展 ID:
mhfbofiokmppgdliakminbgdgcmbhbac); - Edge:访问 Microsoft Edge 加载项商店安装。
注意:README 特别提示,由于商店审核通常需要约一周时间(“Because the review takes a week”),应用商店中的版本往往会落后于 GitHub 上的最新发布版本。因此,追求最新功能的用户可以考虑从 GitHub Releases 手动安装。
3.2 从 GitHub Releases 手动安装(From Github)
手动安装的完整步骤如下:
- 从 release page 下载
webclipper.zip压缩包; - 在浏览器地址栏打开
chrome://extensions/,勾选右上角的开发者模式(Developer mode); - 在本地解压下载的 ZIP 文件;
- 回到
chrome://extensions/页面,点击加载已解压的扩展程序(Load unpacked extension),选择刚才解压出来的文件夹完成安装。
该流程与本地开发时的加载方式一致(见下文开发章节),因此也适合希望提前体验最新版本的用户。
四、开发(Develop)
4.1 环境准备与启动
README 给出的开发启动命令如下:
$ git clone https://github.com/webclipper/web-clipper.git $ cd web-clipper $ npm i $ npm run dev结合 package.json 中的 scripts 配置,可以更精确地理解各步骤的作用:
| 命令 | 实际执行内容 | 说明 |
|---|---|---|
npm i | 安装全部依赖 | 仓库使用 pnpm 作为包管理器(packageManager: pnpm@8.14.0),使用pnpm install亦可 |
npm run dev | webpack --config webpack/webpack.dev.js --watch | 以 watch 模式启动开发构建,源码变更后自动重新编译 |
npm run test | vitest | 运行 Vitest 单元测试(watch 模式) |
npm run cov | vitest --coverage | 生成测试覆盖率报告 |
npm run release | ts-node script/release.ts | 执行发布打包流程 |
npm run format | web-clipper format | 格式化代码 |
4.2 在浏览器中加载产物
启动npm run dev后,webpack 会将构建产物输出到dist目录,此时需要把扩展加载进浏览器:
- Chrome:加载
dist/chrome文件夹; - Firefox:加载
dist/manifest.json所在的dist文件夹。
具体操作依然是chrome://extensions/(Firefox 为about:debugging)→ 开启开发者模式 → 加载已解压的扩展程序。
4.3 构建配置的源码级解读
从 webpack/webpack.dev.js 可以看出,开发模式使用source-map提供完整的调试映射,并开启了watchOptions.ignored: /dist/避免对输出目录的循环监听。
webpack/webpack.common.js 揭示了扩展的三个入口与整体构建思路:
entry: { tool: resolve('src/main/tool.main.chrome.ts'), content_script: resolve('src/main/contentScript.main.ts'), background: resolve('src/main/background.worker.ts'), },这三个入口对应浏览器扩展的三种典型运行环境:
- background worker(src/main/background.worker.ts):扩展的后台常驻脚本,负责注册 IPC 服务通道(tab、worker、permissions、webRequest、cookies)、监听工具栏图标点击与右键菜单事件,并把这些事件分发给对应的内容脚本与插件;
- content script(src/main/contentScript.main.ts):注入到网页页面中的脚本,负责在页面上下文里执行剪藏逻辑(如高亮选择、正文提取),并通过 IPC 与后台通信;它还会根据系统深浅色模式自动更新扩展图标颜色;
- tool 页面(src/main/tool.main.chrome.ts):剪藏时弹出的工具 UI,即扩展的 React 应用入口,最终由 HtmlWebpackPlugin 生成
dist/chrome/tool.html。
其他值得关注的构建细节:
- 分包策略:
splitChunks将 react、react-dom、antd、lodash、@ant-design 等大体积依赖抽成独立的vendorchunk,且不参与 background 的打包; - 路径别名:
@指向src/,另有common、components、extensions等别名,方便源码引用; - 静态资源复制:
CopyWebpackPlugin将 chrome/html、chrome/js、chrome/icons 复制到dist/chrome,其中icons目录存放扩展图标(如 chrome/icons/icon.png); - 清单生成:
WebpackCreateExtensionManifestPlugin(实现见 webpack/plugin/webpack-create-extension-manifest-plugin.js)负责自动生成扩展的manifest.json,config.json 中的chromeWebStoreVersion等字段则记录了各商店的版本号信息。
五、测试(Test)
运行测试只需一条命令:
$ npm run test从 vitest.config.ts 可以看到项目使用Vitest作为测试框架:开启globals: true,默认超时 10 秒,并加载 src/setupTests.ts 作为全局 setup 文件。
仓库中的测试覆盖了多个核心模块,例如:
- src/common/backend/clients/github/client.test.ts 与 src/common/backend/clients/leanote/client.test.ts:验证 GitHub、Leanote 后端客户端的接口行为;
- src/test/utils.ts:提供
MockRequestService,通过注入 mock 请求处理器来模拟网络层,使后端服务的单元测试无需真实网络请求; - src/common/version/index.test.ts、src/common/matchUrl.test.ts、src/common/loading.test.ts:覆盖版本比对、URL 匹配、加载状态等公共工具函数;
- src/common/storage/test/index.spec.ts:验证存储层逻辑;
- src/components/section/snapshots/index.test.tsx.snap:React 组件快照测试。
如需覆盖率报告,可运行npm run cov。
六、深入理解:插件化剪藏架构
6.1 扩展体系:三大入口与生命周期
Web Clipper 的剪藏能力建立在统一的扩展抽象之上。在 src/extensions/common.ts 中定义了两种扩展基类:
- TextExtension:文本型剪藏扩展,输出字符串内容;
- ToolExtension:工具型剪藏扩展,同样以字符串作为最终输出。
每种扩展都实现了一套生命周期接口IExtensionLifeCycle:
| 生命周期方法 | 触发时机 | 作用 |
|---|---|---|
init(context) | 插件被加载之前 | 根据当前上下文(如 pathname、账号类型、URL)决定该插件是否启用 |
run(context) | 执行插件 | 在网页上下文(ContentScriptContext)中执行内容抓取,如提取标题、URL、选中文本 |
afterRun(context) | 执行插件后 | 拿到run的结果result与当前数据data,做最终处理(模板渲染、复制、下载等) |
destroy(context) | 清理环境 | 释放页面资源、移除临时 DOM |
扩展清单的注册方式非常轻量:src/extensions/index.ts 使用 webpack 的require.context自动扫描src/extensions/extensions与src/extensions/contextMenus两个目录下的所有ts/tsx文件,无需手工登记。
6.2 典型插件实现示例
以自带插件Link(添加模版)为例,其实现位于 src/extensions/extensions/web-clipper/link.tsx。它在run阶段返回页面标题与 URL:
run: async context => { return { TITLE: context.document.title, URL: context.document.URL, }; },在afterRun阶段,则按照用户配置的模板渲染最终文本,默认模板为:
{TITLE} \n\n {DOCUMENT}其中{DOCUMENT}是页面正文(Markdown),{TITLE}、{URL}来自run的结果。用户可以在扩展配置面板中修改template字段,或通过autoRunExclude指定某些页面不自动追加链接。该插件的automatic: true标记表明它会作为自动扩展参与每次剪藏(详见下文 6.4 的自动扩展机制)。
仓库还自带了一批开箱即用的工具插件,例如:
- src/extensions/extensions/extensions/remove.ts(删除元素):调用
Highlighter让用户点选页面元素后将其从剪藏内容中移除; - src/extensions/extensions/web-clipper/clear.ts(清空):通过
init判断当前路由是否为/plugin开头,并在afterRun阶段返回空字符串以清空内容; - src/extensions/extensions/web-clipper/copyToClipboard.ts(复制):在
afterRun阶段把剪藏结果复制到剪贴板。
6.3 剪藏执行链路:从点击图标到写入笔记
结合 src/models/clipper.tsx(dva 模型)与 src/actions/clipper.ts(action 定义),可以还原一次完整剪藏的执行链路:
- 用户点击扩展图标,后台 worker(src/main/background.worker.ts)通过
chrome.action.onClicked检查内容脚本状态并触发 toggle; - tool 页面(React 应用)根据当前路由
/plugins/<插件id>找到对应扩展(extensions.find(o => o.router === pathname)); - 依次执行自动扩展(
automaticExtensions),再执行当前选中扩展的run/afterRun,得到最终 Markdown 内容; - 组装
CreateDocumentRequest(包含title、content、url、repositoryId,接口定义见 src/common/backend/services/interface.ts),调用backend.getDocumentService().createDocument(...)写入目标平台; - 成功后通过
routerRedux.push('/complete')跳转到完成页展示结果链接。
6.4 自动扩展机制
在 src/models/clipper.tsx 中可以看到,创建文档时会把所有满足条件的自动扩展(ExtensionType.Tool且manifest.automatic === true且已被用户启用)在正式写入前依次执行一遍:
const automaticExtensions = extensions.filter( o => o.type === ExtensionType.Tool && o.manifest.automatic && enabledAutomaticExtensionIds.some(id => id === o.id) );这意味着“添加模版”“复制到剪贴板”等自动插件可以在每次剪藏时自动生效,用户无需每次手动选择,同时可以在偏好设置中单独启用或禁用某个自动扩展。
七、后端服务抽象:一套接口,接入所有平台
7.1 工厂模式与依赖注入
所有目标平台都实现了统一的DocumentService接口(见 src/common/backend/services/interface.ts):
export interface DocumentService<T = any> { getId(): string; getRepositories(): Promise<Repository[]>; createDocument(request: T): Promise<CompleteStatus | void>; getUserInfo(): Promise<UserInfo>; refreshToken?(info: T): Promise<T>; }src/common/backend/index.ts 通过require.context自动收集src/common/backend/services与src/common/backend/imageHosting下的所有服务,并提供两个工厂方法:
documentServiceFactory(type, info):按类型实例化文档服务;imageHostingServiceFactory(type, info):按类型实例化图床服务。
剪藏内容中的图片可以走独立的图床服务上传,仓库内置了 GitHub、Imgur、sm.ms、腾讯云 COS、PicList、七牛、语雀、Joplin、Leanote、思源、baklib、wiznote 等图床实现(见 src/common/backend/imageHosting 目录)。
7.2 一个完整的服务实现:语雀
以语雀为例,src/common/backend/services/yuque/service.ts 的实现展示了完整的接入流程:
- 构造时通过
accessToken创建RequestHelper,并统一携带X-Auth-Token请求头; getRepositories()拉取个人仓库与团队(groups)仓库,并处理分页(每页 20 条);createDocument()调用语雀 API 创建文档(slug 由generateUuid()生成,默认private: true),随后通过updateYuqueTOC把新文档挂载到目录树;- 返回
CompleteStatus,其中href是新文档的访问链接,供完成页跳转使用。
permission字段(如语雀的https://www.yuque.com/*、Joplin 的http://localhost:41184/*)会在账号切换时触发权限检查与申请,相关逻辑见 src/models/clipper.tsx 中asyncChangeAccount对permissionsService.contains / request的调用。
八、发布打包(Release)
README 未直接给出发布流程,但从 script/release.ts 可以还原官方发布方式:运行npm run release后,脚本会:
- 以生产模式构建(
NODE_ENV=production,实际构建脚本为script/build); - 将
dist/chrome打包为web-clipper-chrome.zip; - 将
dist打包为web-clipper-firefox.zip; - 为 Firefox 商店版本追加
browser_specific_settings.gecko.id并改名Universal Web Clipper,输出web-clipper-firefox-store.zip。
打包逻辑由 script/utils/pack.ts 实现,基于compressing库将 dist 目录下的文件(过滤以.开头的隐藏文件)逐一加入 zip 流。这与 README “从 GitHub release page 下载 webclipper.zip 手动安装” 的说明直接对应。
九、常见问题与提示
- 商店版本落后:Chrome/Edge 商店版本因审核周期(约一周)会落后于 GitHub 最新版,如需尝鲜请从 Releases 手动加载;
- Firefox 加载方式不同:Chrome 加载
dist/chrome文件夹,Firefox 加载包含manifest.json的dist文件夹; - 依赖安装:仓库声明了 pnpm 版本(
pnpm@8.14.0),使用 pnpm 安装可避免锁文件版本不一致问题; - 开发调试:
npm run dev是 watch 模式,修改源码后无需手动重新构建,刷新扩展页面即可看到效果; - 测试覆盖:运行
npm run cov可生成覆盖率报告,便于评估改动对核心逻辑(后端客户端、存储、工具函数)的影响。
结语
Web Clipper 用一个简洁的插件化架构,把“抓取网页内容”和“写入目标平台”两件事彻底解耦:左侧是src/extensions下自动扫描注册的剪藏插件,右侧是src/common/backend/services下统一接口的文档服务,中间由后台 worker、内容脚本与 tool 页面三个运行时通过 IPC 串联。无论是普通用户按照 README 的安装指引接入 Chrome/Edge/Firefox,还是开发者基于本文的源码路径深入裁剪流程、接入新的笔记平台,都能在仓库现有代码结构中找到清晰、可复用的答案。
- 开发工具
【免费下载链接】web-clipper
For Notion,OneNote,Bear,Yuque,Joplin。Clip anything to anywhere
相关推荐
Web Clipper 开源贡献完全指南:从零开始参与这个万能剪藏工具
Web Clipper 开源贡献完全指南:从零开始参与这个万能剪藏工具 Web Clipper 是一个功能强大的开源网页剪藏工具,支持将网页内容保存到 Noti
开发工具Focalboard Web Clipper 浏览器扩展开发实战:从网页一键剪藏到看板卡片
Focalboard Web Clipper 浏览器扩展开发实战:从网页一键剪藏到看板卡片 导读 本文以仓库 experiments/webext 下的 Foc
后端前端企业应用桌面应用协同办公【免费下载】 Obsidian Web Clipper 网页剪藏功能详解与技术指南
Obsidian Web Clipper 网页剪藏功能详解与技术指南 一、Obsidian Web Clipper 简介 Obsidian Web Clippe
前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考