首页
/ uBlock Origin MV3 构建指南:从零构建 uBO Lite(uBOLite)扩展包的完整流程

uBlock Origin MV3 构建指南:从零构建 uBO Lite(uBOLite)扩展包的完整流程

2026-09-03 15:33:08作者:咎岭娴Homer

本文以 platform/mv3/README.md 为蓝本,系统讲解 uBlock Origin 仓库中 MV3 分支的构建体系:如何在 Linux 环境下通过 Makefile 与 tools/make-mv3.sh 为 Chromium、Edge、Firefox、Safari 四个平台分别产出 uBOLite 扩展包,并深入解析其底层机制——过滤列表如何被 make-rulesets.js 转换为声明式网络请求(Declarative Net Request, DNR)规则集、本地缓存如何避免重复抓取远程列表,以及构建日志的生成与诊断方法。读完后你将能够独立完成一次完整的 MV3 构建、定位构建失败原因,并理解产出包内部各目录的职责。

一、构建前提:为什么 MV3 构建是独立流程

uBlock Origin 主线(MV2 形态)的构建目标位于 Makefilechromiumfirefoxopera 等条目中;而 MV3 形态(对外称 uBO Lite,简称 uBOLite)走的是另一套独立目标:

  • mv3-chromiummv3-firefoxmv3-edgemv3-safari —— 对应 platform/mv3/README.md 中提到的 make mv3-[platform]
  • 每个目标都依赖 ubol-codemirror 目标,该目标先构建 platform/mv3/extension/lib/codemirror/codemirror-ubol 下的 CodeMirror 6 自定义 bundle(cm6.bundle.ubol.min.js),因为 MV3 扩展的规则编辑界面依赖它;
  • 各平台目标的依赖列表中显式包含 $(mv3-data)dist/build/mv3-data,即 Makefile 会把过滤列表缓存目录纳入增量构建的依赖计算——缓存中的列表更新后,会重新触发规则集生成。

构建脚本本身假设运行在 Linux 环境(tools/make-mv3.sh 文件头部注释即写明 "This script assumes a linux environment"),并且要求 Node.js 17.5.0 及以上版本——这一约束同样固化在 platform/mv3/package.jsonengines 字段中:

{
  "engines": {
    "node": ">=17.5.0"
  },
  "type": "module"
}

Node 17.5.0 是首个稳定提供全局 fetch 的版本,而 make-rulesets.js 的抓取逻辑正依赖原生 fetch(见下文第三节)。

二、标准构建步骤(完整继承自官方文档)

以下步骤逐条对应 platform/mv3/README.md 的官方说明,适用于一个干净的 Linux 环境:

# 1. 打开 Bash 控制台
# 2. 克隆仓库
git clone https://github.com/gorhill/uBlock.git
# 3. 进入仓库
cd uBlock
# 4. 初始化子模块
git submodule init
# 5. 更新子模块
git submodule update
# 6. 执行 MV3 构建,[platform] 取值为 chromium / edge / firefox / safari 之一
make mv3-[platform]

第 6 步会完整地构建 uBOLite,并在构建过程中从各远程服务器下载过滤列表(uAssets、EasyList、EasyPrivacy 等)。构建完成后,各平台的扩展包分别落在:

平台 产物路径
Chromium dist/build/uBOLite.chromium
Edge dist/build/uBOLite.edge
Firefox dist/build/uBOLite.firefox
Safari dist/build/uBOLite.safari

这些产物路径与 tools/make-mv3.shUBOL_DIR="dist/build/uBOLite.$PLATFORM" 的定义完全一致。

此外还有两点官方文档明确说明、值得强调的运维细节:

  1. 列表缓存目录dist/build/mv3-data 会缓存从远程服务器抓取的过滤列表数据,避免重复执行构建命令时反复抓取远程资源。如果需要用最新版列表重新构建,先执行 make cleanassets 清掉本地缓存。对照 Makefile 可以看到该目标的具体行为是删除 dist/build/mv3-datadist/build/uAssets 两个目录。
  2. 构建日志dist/build/uBOLite.[platform]/log.txt 记录了构建过程发生的一切,是排查构建失败的第一入口(其生成机制见第三节)。

三、构建流程深挖:make-mv3.sh 的三段式工作流

官方文档指出,实现整个构建过程的 Makefile 条目是 tools/make-mv3.sh [platform]。该 Bash 脚本的职责是把 uBlock Origin 主线分支的文件与 MV3 专属分支的文件拷贝合并到一个文件夹,这个文件夹就是最终的扩展包。通读 tools/make-mv3.sh,可以将其工作流拆解为四个阶段:

3.1 参数解析与平台选择

脚本通过 case 解析命令行参数:chromium/firefox/edge/safari 决定 PLATFORMfull 或形如 1.2.3 的版本号会置 FULL=yes(构建可发布的 zip/xpi 包),before=<dir> 则用于规则 ID 回收(见 3.4)。值得注意的是,Edge 平台实际复用 platform/mv3/chromium/manifest.jsonMANIFEST_DIR="chromium"),因为 Edge 本质上是 Chromium 的 DNR 方言。

3.2 文件合并:主线与 MV3 分支的拼装

脚本先清空并重建 dist/build/uBOLite.$PLATFORM,然后分两批拷贝:

  • 通用文件(来自 src/,即主线代码):CSS 主题与字体(common.cssdashboard-common.cssfa-icons.css 等)、核心 JS(arglist-parser.jsi18n.jsstatic-filtering-parser.jsredirect-resources.js 等)、flags-of-the-world 国旗图片、LICENSE.txt
  • MV3 专属文件(来自 platform/mv3/extension 与平台子目录):各页面 HTML、platform/mv3/extension/css 下的界面样式、platform/mv3/extension/js 下的全部脚本(包含 dnr-editor.jsfilter-manager.jsruleset-manager.js 等 MV3 特有模块)、platform/mv3/extension/_locales 下的 70 余种语言包,以及平台补丁文件(如 ext-compat.jsext-offscreen.jscss-api.js)。

随后拷贝第三方库:CodeMirror、csstree、s14e-serializer 等,写入 lib/ 目录。

3.3 规则集生成:从过滤列表到 DNR 规则

这是整个构建的核心。脚本把 platform/mv3 目录下的构建资产(rulesets.jsonmake-rulesets.jssalvage-ruleids.mjs)、扩展内的解析模块(ubo-parser.jsutils.jsstatic-dnr-filtering.js 等,以及 platform/mv3/extension/js/offscreen 下的 offscreen 处理模块)汇集到一个临时构建目录,然后执行:

node --no-warnings make-rulesets.js output="<扩展包目录>" platform="<平台>"

make-rulesets.js(约 1246 行)完成了文档所述"将过滤列表转换为声明式可用的各类规则集"的工作,其关键实现要点如下:

  • 列表抓取与本地缓存fetchText() 先尝试从 <输出目录>/../mv3-data(即 dist/build/mv3-data)读取以 URL 转写为文件名的缓存,命中则直接使用;未命中才发起远程 fetch,成功后写回缓存文件。这正是官方文档强调 mv3-data 缓存目录的原因,也解释了为什么 make cleanassets 之后重建才能拿到最新列表。
  • 规则集定义main() 启动时解析 platform/mv3/rulesets.json(656 行、约几十个条目),逐项调用 rulesetFromURLs()。每条规则集是一个声明式对象,核心字段包括:
    • id / name / group:规则集标识、显示名与分组(defaultmalwareadsprivacyannoyancesregions 等);
    • enabled:默认启用状态;trusted:标记为可信列表(可生成更强力的规则);
    • urls:列表源地址,通常指向 uAssets 的 GitHub Pages 或各社区列表;
    • excludedPlatforms:如 pglublock-badware 等条目显式排除了 safari 平台,构建时会被跳过(if ( ruleset.excludedPlatforms?.includes(platform) ) { continue; });
    • lang / tags / parent / homeURL:区域列表的语言代码、检索标签、父级分组及来源主页。
  • 规则分类统计:每条列表会被解析为网络规则,并按类型计数——普通规则、正则规则、removeparam(展开处理)、redirect、modifyHeaders、strictblock、urlskip,以及被丢弃/拒绝的规则数,全部记入 ruleset-details.json
  • cosmetic 过滤器的脚本化:由于 MV3 的 service worker 架构无法注入页面 CSS 规则,cosmetic 过滤器被编译为 CSS 脚本(make-cosmetic-filters.jsmake-scriptlets.js,模板见 platform/mv3/scriptlets),经 offscreen 文档处理,统计信息写入 scriptlet-details.json
  • 产物落盘与 manifest 打补丁main() 末尾将每个规则集写为 /rulesets/main/<id>.json,汇总注册到 ruleResources;随后回写扩展包内的 manifest.json——填充 declarative_net_request.rule_resources(源模板中该数组为空占位,由构建期注入)、追加重定向资源到 web_accessible_resources,并用当前 UTC 时间生成形如 2026.903.1530(年月.日时.分秒)的版本号。源 manifest 还要求 minimum_chrome_version: "122.0"、以 "service_worker": "/js/background.js" 的 module 类型运行后台逻辑,权限包含 declarativeNetRequestoffscreenscripting 等。
  • 日志输出:脚本临时接管 console.log,把所有输出缓冲到 stdOutput,最后一次性写入 <输出目录>/log.txt——这正是官方文档中 dist/build/uBOLite.[platform]/log.txt 的由来。若某条日志以 !!! 开头,会同时打印到终端,通常提示构建中出现异常。

3.4 本地构建、发布打包与平台差异

tools/make-mv3.sh 的收尾阶段还有几处与日常开发直接相关的行为:

  • 本地构建默认开启 DNR 调试:当不带版本号参数(即普通 make mv3-[platform])时,脚本用 jq 向 manifest 的 permissions 追加 declarativeNetRequestFeedback(用于在开发者工具中查看 DNR 规则匹配),Firefox 平台还会把扩展 ID 改写为 uBOLite.dev@raymondhill.net 以区分正式包;
  • 正式发布模式:传入版本号(如 make mv3-chromium 调用链中的 full/1.0.0 参数)会触发 FULL=yes,删除 rulesets/debug 目录、把版本写入 manifest,最终打包为 dist/build/uBOLite_<版本>.<平台>.zip(Firefox 为 .xpi);
  • Edge 兼容性修正:Edge 要求声明式规则集放在包根目录,脚本会把 rulesets/main/* 移到包根并运行 platform/mv3/edge/patch-extension.js;Safari 则统一交由 platform/mv3/safari/patch-extension.js 做合规性修补;
  • 规则 ID 回收:若指定 before=<旧包目录>,会执行 salvage-ruleids.mjs,在新旧规则集之间比对并尽量保留旧规则 ID,以最小化更新时 DNR 规则集的 diff 体积——从源码结构看,这对商店分发场景下的更新效率有直接意义。

四、构建产物结构速览

一次 make mv3-chromium 之后,dist/build/uBOLite.chromium 内的关键布局为:

  • 扩展包根部的 manifest.json:构建期已注入 rule_resources 与版本号;
  • rulesets/ 目录:全部最终规则集(main/<id>.json),以及 ruleset-details.jsonscriptlet-details.jsongeneric-details.json 三份统计元数据,官方文档亦明确"All the final rulesets are present in the dist/build/uBOLite.[platform]/rulesets";
  • rulesets/scripting/:由 cosmetic/scriptlet 过滤器编译出的注入脚本;
  • js/css/img/lib/_locales/:扩展运行所需的全部前端资源;
  • log.txt:本次构建的完整日志。

五、常见问题排查

  • 构建报错 "fetch is not defined" 或网络类错误:确认 Node.js 版本 ≥ 17.5.0(platform/mv3/package.json 的硬性要求);远程列表抓取失败时先检查网络,或改用 make cleanassets 清缓存后重试以获取最新列表。
  • 想强制刷新过滤列表make cleanassets(删除 dist/build/mv3-datadist/build/uAssets)再重新执行 make mv3-[platform]
  • 定位构建异常:优先阅读 dist/build/uBOLite.[platform]/log.txt;终端上以 !!! 开头的行是脚本主动放出的告警信息,可直接对应日志中的异常条目。
  • 构建产物版本:普通本地构建的版本号是构建时刻的 UTC 时间戳;发布模式则使用传入的版本号并附带可安装压缩包。

六、小结

uBlock Origin 的 MV3 构建体系是一个典型的"声明式定义 + 构建期编译"流程:platform/mv3/rulesets.json 声明"要哪些列表",make-rulesets.js 负责"把列表变成浏览器原生 DNR 引擎可加载的规则集",tools/make-mv3.shMakefile 则负责"把主线与 MV3 分支拼成可安装的扩展包"。理解这条链路后,无论是复现官方构建、定制规则集来源,还是调试 DNR 规则匹配行为,都有了清晰的代码级抓手。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
503
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384