首页
/ uBlock uBOLite(MV3)CodeMirror 6 打包重建指南:构建步骤、产物打包与源码消费链

uBlock uBOLite(MV3)CodeMirror 6 打包重建指南:构建步骤、产物打包与源码消费链

2026-09-04 18:16:40作者:瞿蔚英Wynne

本篇以 platform/mv3/extension/lib/codemirror/README.md 为核心,讲解如何为 uBlock 的 MV3 版本 uBOLite 重建唯一的代码编辑器依赖 cm6.bundle.ubol.min.js:文中完整保留了官方 README 的 submodule 初始化与 npm 构建六步流程,并结合 tools/make-mv3.shplatform/mv3/extension/dashboard.html 及各编辑器模块源码,说明该产物在打包阶段如何被复制进最终扩展包、在运行时又被哪些功能消费。读完后你可以独立完成 bundle 重建,并理解它在整条 MV3 构建链路中的位置。

一、这份 README 解决什么问题:cm6.bundle.ubol.min.js 的来源

platform/mv3/extension/lib/codemirror/README.md 的正文只围绕一件事:说明 platform/mv3/extension/lib/codemirror/ 目录下的 cm6.bundle.ubol.min.js 这个文件是从哪里来的、如何重新构建它。该目录当前包含三类内容:

  • README.md:即这份构建说明;
  • codemirror.LICENSE:CodeMirror 的 MIT 许可证(Copyright 2018–2021,Marijn Haverbeke and others,见 codemirror.LICENSE);
  • codemirror-ubol/:Git submodule 挂载点。

关键点在于 codemirror-ubol/ 目录在浅层检出时是空的。它对应 .gitmodules 中定义的子模块:

[submodule "platform/mv3/extension/lib/codemirror/codemirror-ubol"]
    path = platform/mv3/extension/lib/codemirror/codemirror-ubol
    url = codemirror-ubol(作者的定制仓库)

README 进一步说明:进入该目录后,你所在的仓库是一个定制化的 fork,其上游是 RPGillespie6/codemirror-quickstart 项目(CodeMirror 6 的官方快速入门/打包工程)。也就是说,uBlock 并不是直接使用官方 CodeMirror 6 的发布产物,而是维护了一个 fork,以便按自身需求裁剪与封装出单文件的 cm6.bundle.ubol.min.js

从源码结构看,这种“单文件 bundle”的用法与主扩展形成鲜明对比:主扩展(uBlock Origin)的页面如 src/1p-filters.htmlsrc/asset-viewer.html 加载的是 CodeMirror 5 的多文件结构(lib/codemirror/lib/codemirror.js 加 comment、fold、search、hint 等十余个 addon 脚本);而 MV3 的 uBOLite 则只加载一个预打包的 CM6 文件。可以推断,MV3 平台对脚本加载方式的限制促使 uBOLite 采用了“一次打包、单文件引入”的策略,这正是本 README 所描述的 bundle 存在的意义。

二、重建 cm6.bundle.ubol.min.js:官方六步流程

以下命令序列完整继承自原 README(“command line from repo root”,即从仓库根目录开始执行):

# 1. 从仓库根目录初始化 codemirror-ubol 子模块
git submodule init platform/mv3/extension/lib/codemirror/codemirror-ubol

# 2. 进入子模块目录
cd platform/mv3/extension/lib/codemirror/codemirror-ubol/
#    (此时已进入从 codemirror-quickstart fork 出的定制仓库)

# 3. 安装依赖
npm install

# 4. 执行构建
npm run build

构建完成后的两个结果,README 中均有明确表述:

  • cm6.bundle.ubol.min.js 会出现在子模块的 dist 目录中(即 platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/);
  • 该文件正是当前目录(platform/mv3/extension/lib/codemirror/)下同名文件的来源——即 MV3 扩展实际引用的 bundle 由这次构建产出。

补充两点与仓库上下文一致的说明:

  • platform/mv3/README.md 给出的完整 MV3 构建流程中,git submodule init 之后紧跟 git submodule update 才会真正拉取子模块内容;若你只想重建 bundle 而不做完整扩展构建,需自行确保子模块工作区已检出后再执行 npm install / npm run build
  • 由于 codemirror-ubol 是 fork 自 codemirror-quickstart 的工程,npm run build 走的是其 quickstart 构建脚本,产物路径固定为 dist/,这一点与后续打包脚本的预期路径严格对应(见下节)。

三、产物去向:tools/make-mv3.sh 如何把它打进最终扩展包

重建出的 bundle 并非直接可用,而是由 MV3 打包脚本消费。tools/make-mv3.sh 中有一段专门的库文件复制逻辑:

# Libraries
mkdir -p "$UBOL_DIR"/lib/codemirror
cp platform/mv3/extension/lib/codemirror/* \
    "$UBOL_DIR"/lib/codemirror/ 2>/dev/null || :
cp platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/cm6.bundle.ubol.min.js \
    "$UBOL_DIR"/lib/codemirror/
cp platform/mv3/extension/lib/codemirror/codemirror.LICENSE \
    "$UBOL_DIR"/lib/codemirror/
cp platform/mv3/extension/lib/codemirror/codemirror-ubol/LICENSE \
    "$UBOL_DIR"/lib/codemirror/codemirror-quickstart.LICENSE

这段代码印证了 README 所说的构建链路:

  • 打包时,脚本强制从子模块的 dist/ 目录复制 cm6.bundle.ubol.min.js 到最终包的 lib/codemirror/(第 120–121 行)。注意该复制行没有 || : 容错后缀——若 bundle 不存在,构建会直接失败,这正是“必须先成功执行 npm run build”的硬性约束;
  • 许可证文件同步复制:CodeMirror 本体的 codemirror.LICENSE 保留原名,而 fork 仓库自带的 LICENSE 则改名为 codemirror-quickstart.LICENSE,区分上游 quickstart 工程的版权说明;
  • platform/mv3/README.md,最终扩展包落在 dist/build/uBOLite.[platform](platform 为 chromium、edge、firefox 或 safari),bundle 随包内 lib/codemirror/ 一同分发。

四、运行时消费:self.cm6 全局 API 与它的调用方

platform/mv3/extension/dashboard.html 在页面末尾以经典脚本方式加载 bundle,且先于所有业务模块脚本:

<script src="lib/codemirror/cm6.bundle.ubol.min.js"></script>
<script src="js/theme.js" type="module"></script>
<script src="js/dashboard.js" type="module"></script>
<script src="js/develop.js" type="module"></script>

由此可以推断,该 bundle 向全局暴露了一个封装对象 cm6,供 MV3 扩展各编辑器模块调用。仓库中实际消费它的主要模块有:

综合这些调用点,从源码结构看,这个定制化 bundle 并非 CodeMirror 6 的“原样打包”,而是叠加了一层 uBlock 专用封装:编辑器视图创建、工具面板、错误行/片段高亮、全文查找、折叠与撤销历史重置等能力都被收敛进 cm6 命名空间,供 MV3 侧五个编辑器页面以统一接口使用。这也解释了为什么上游是 quickstart 工程的 fork——官方 quickstart 只负责把 CM6 打成 bundle,而 uBlock 需要的错误标注与面板集成必须在其构建基础上定制。

五、验证与排查建议

执行 README 流程后,可按以下顺序验证产物与链路是否完整:

  1. 确认 platform/mv3/extension/lib/codemirror/codemirror-ubol/ 子模块工作区非空(空目录即 git submodule init 未生效或未 git submodule update);
  2. 确认 platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/cm6.bundle.ubol.min.js 已生成——这是 tools/make-mv3.sh 第 120–121 行复制动作的源文件,缺失会导致打包失败;
  3. 如需完整走通 MV3 构建(make mv3-[platform]),按 platform/mv3/README.md 的前提准备环境:完整流程还要求 Node.js 17.5.0 及以上,且构建期间会从远程服务器下载过滤列表数据;
  4. 注意不要混淆两套 CodeMirror:src/lib/codemirror/ 下是主扩展使用的 CodeMirror 5 多文件库(供 src/1p-filters.htmlsrc/advanced-settings.htmlsrc/code-viewer.html 等页面使用),与本 README 讨论的 MV3 侧 CM6 单文件 bundle 相互独立,重建 bundle 不会也不应影响前者。

小结

这份简短的 README 定义了 uBOLite(MV3)编辑器体验的“单一依赖”:cm6.bundle.ubol.min.jscodemirror-ubol 子模块(codemirror-quickstart 的定制 fork)经 npm install + npm run build 产出,再由 tools/make-mv3.sh 连同两份许可证文件复制进各平台最终包,运行时由 dashboard.html 加载,并通过全局 cm6 API 支撑自定义过滤器、动态网络规则等多个编辑器界面。掌握这六步构建命令与上述打包、消费链路,即可独立完成该 bundle 的重建与验证。

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

项目优选

收起
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