news 2026/10/15 19:03:05

Web Clipper 开源通用网页剪藏工具:安装、开发与架构全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Web Clipper 开源通用网页剪藏工具:安装、开发与架构全解析
  • 开发工具

【免费下载链接】web-clipper

For Notion,OneNote,Bear,Yuque,Joplin。Clip anything to anywhere

项目地址:https://gitcode.com/gh_mirrors/we/web-clipper
点击查看免费下载

本文围绕开源仓库 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 的核心价值在于两点:

  1. 抓取能力强:内置完整页面、选中区域、截图、全文提取(Readability)、二维码、选择工具等多种剪藏方式;
  2. 投递范围广:通过统一的后端服务抽象(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)

手动安装的完整步骤如下:

  1. 从 release page 下载webclipper.zip压缩包;
  2. 在浏览器地址栏打开chrome://extensions/,勾选右上角的开发者模式(Developer mode);
  3. 在本地解压下载的 ZIP 文件;
  4. 回到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 devwebpack --config webpack/webpack.dev.js --watch以 watch 模式启动开发构建,源码变更后自动重新编译
npm run testvitest运行 Vitest 单元测试(watch 模式)
npm run covvitest --coverage生成测试覆盖率报告
npm run releasets-node script/release.ts执行发布打包流程
npm run formatweb-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'), },

这三个入口对应浏览器扩展的三种典型运行环境:

  1. background worker(src/main/background.worker.ts):扩展的后台常驻脚本,负责注册 IPC 服务通道(tab、worker、permissions、webRequest、cookies)、监听工具栏图标点击与右键菜单事件,并把这些事件分发给对应的内容脚本与插件;
  2. content script(src/main/contentScript.main.ts):注入到网页页面中的脚本,负责在页面上下文里执行剪藏逻辑(如高亮选择、正文提取),并通过 IPC 与后台通信;它还会根据系统深浅色模式自动更新扩展图标颜色;
  3. 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 定义),可以还原一次完整剪藏的执行链路:

  1. 用户点击扩展图标,后台 worker(src/main/background.worker.ts)通过chrome.action.onClicked检查内容脚本状态并触发 toggle;
  2. tool 页面(React 应用)根据当前路由/plugins/<插件id>找到对应扩展(extensions.find(o => o.router === pathname));
  3. 依次执行自动扩展(automaticExtensions),再执行当前选中扩展的run/afterRun,得到最终 Markdown 内容;
  4. 组装CreateDocumentRequest(包含title、content、url、repositoryId,接口定义见 src/common/backend/services/interface.ts),调用backend.getDocumentService().createDocument(...)写入目标平台;
  5. 成功后通过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后,脚本会:

  1. 以生产模式构建(NODE_ENV=production,实际构建脚本为script/build);
  2. 将dist/chrome打包为web-clipper-chrome.zip;
  3. 将dist打包为web-clipper-firefox.zip;
  4. 为 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

项目地址:https://gitcode.com/gh_mirrors/we/web-clipper
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 19:02:44

参考资源不是链接,而是一套方法论

写到第32章&#xff0c;我想换个话题&#xff0c;认真聊聊"参考资源"这四个字。前31章的内容&#xff0c;几乎每一章都会出现类似于"详细的接口说明可以查阅官方文档""这位同行的实现在某社区有详细讨论""补课的读者可以先看某某基础教程&q…

作者头像 李华
网站建设 2026/10/15 19:02:27

Swift纯代码实现 UIKit 控件创建与模态页面切换实战指南

如果你已经厌倦了在 Storyboard 里拖线、牵约束、找 IBOutlet&#xff0c;那这篇内容应该能省下你不少时间。用 Swift 在 Xcode 里写视图控制器&#xff0c;核心就是两件事&#xff1a;在代码里创建控件&#xff0c;以及在不同控制器之间切换。今天要拆解的正是把 UILabel、UIB…

作者头像 李华
网站建设 2026/10/15 19:02:26

blink 项目中 Musl Libc 预编译二进制的集成、构建与动态链接机制

虚拟化调试器 【免费下载链接】blink tiniest x86-64-linux emulator 项目地址&#xff1a; https://gitcode.com/gh_mirrors/bl/blink 点击查看 免费下载 本文围绕 blink 仓库中 third_party/musl/README.md 所记录的 Musl Libc 预编译二进制获取与构建方案展开&#xff0c;结…

作者头像 李华
网站建设 2026/10/15 19:01:58

Tilt 中的 Tarjan 算法:强连通分量与资源依赖环检测实战

开发工具云原生微服务 【免费下载链接】tilt Define your dev environment as code. For microservice apps on Kubernetes. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/tilt/tilt 点击查看 免费下载 导读 本篇文章围绕 Tilt 仓库内嵌的第三方库 github.com/loopl…

作者头像 李华
网站建设 2026/10/15 19:00:15

异步FIFO验证核心:跨时钟域建模与UVM可观测性设计

简介&#xff1a;本资源是一份面向数字IC验证初学者与求职者的实战型笔试复盘资料&#xff0c;聚焦UVM验证方法学在异步FIFO设计中的落地应用&#xff0c;特别适配2023届IC验证岗位校招备考。内容完整覆盖思朗科技2022提前批笔试真题&#xff1a;基于给定异步FIFO RTL代码&…

作者头像 李华