Clash Verge Rev(clash-verge-rev 仓库)的 Merge 用于在订阅内容上叠加配置修改。它按层处理配置:后面的层接着前面的结果继续改,应用接管的设置还会在处理末尾写回。因此,扩展里的内容不一定就是最终生效的内容。
截至 2026-11-08,最新版本为 v2.5.10。文档使用“扩展配置”这个名称。理解它需要分清两件事:修改在哪一层执行,以及目标字段采用替换还是合并。
Merge 的名称与作用范围
截至 2026-11-08,文档说明,从 v1.7.x 开始,原来的“Merge 配置”称为“扩展配置”,原来的“Script 配置”称为“扩展脚本”;v1.6.x 用户对应的是旧版 Script 配置指南。
扩展有两种处理方式:
| 方式 | 使用的内容 | 作用 |
|---|---|---|
| 扩展配置 | YAML | 覆写字段或合并对象 |
| 扩展脚本 | JavaScript | 通过脚本处理配置 |
它们还分为全局与订阅两个范围。全局扩展影响大多数订阅;订阅扩展只影响对应的单个订阅。“全局”不能理解为对所有订阅都无条件生效。
要编辑某个订阅的扩展,右键该订阅,选择“编辑扩展配置/脚本”。先确定希望修改的范围,再确定使用配置还是脚本,可以避免把单个订阅的修改放到全局范围。
订阅内容要经过哪些层
合并并非只把扩展配置盖到订阅上。文档列出的处理链如下,每一步都以紧邻的上一步结果为输入。
| 顺序 | 处理层 | 对结果的影响 |
|---|---|---|
| 1 | 订阅原文 | 提供起始配置 |
| 2 | 应用设置 | 在扩展处理前参与配置 |
| 3 | 全局扩展配置 | 叠加全局 YAML 修改 |
| 4 | 全局扩展脚本 | 处理前一步的结果 |
| 5 | 订阅扩展配置 | 加入该订阅自己的 YAML 修改 |
| 6 | 订阅扩展脚本 | 处理该订阅此前形成的结果 |
| 7 | 应用设置回写 | 写回由应用接管的设置 |
这个顺序解释了两类容易混淆的情况。
订阅扩展配置在全局扩展脚本之后执行。因此,全局脚本已经处理过的内容,仍可能被后面的订阅扩展配置改变。订阅扩展脚本又在订阅扩展配置之后,读取的是已经叠加过该配置的结果。
但订阅扩展脚本也不是整条链的终点。应用设置还会回写,所以判断字段是否生效,不能只看扩展之间谁更靠后。
哪些字段替换,哪些字段合并
扩展配置对不同数据结构采用不同处理方式,不能把“合并”理解为保留所有旧内容。
| 字段或结构 | 处理方式 | 阅读配置时要注意什么 |
|---|---|---|
列表,例如 rules、dns.nameserver | 用新列表替换原列表 | 不会自动把两份列表接在一起 |
普通值,例如 tcp-concurrent | 用新值替换原值 | 后续层可以改掉此前的值 |
嵌套对象,例如 tun、sniffer | 按子键合并 | 需要分别看写了哪些子键 |
dns 中明确写出的字段 | 按下述版本规则替换 | 不能直接套用普通嵌套对象的理解 |
顶层 hosts | 按下述版本规则整体替换 | 不能假定两层的条目会累加 |
截至 2026-11-08,文档对 v2.5.5 及以后版本给出的规则是:扩展中明确写出的 dns 字段,按整个字段替换;这一规则也涉及 nameserver-policy 和 fallback-filter。没有写出的其他 dns 字段仍保留。顶层 hosts 则整体替换。
这里要分清“某个 DNS 字段整体替换”和“整个 DNS 配置全部清空”。前者针对扩展中写出的字段,不能据此推断未写出的 DNS 字段也会消失。
DNS 字段的相关内容可接着查看DNS 配置整理。
最小示例:一项 DNS 策略怎样被覆盖
用字段关系就能说明覆盖过程,无需放入完整配置。
假设全局扩展中的 dns.nameserver-policy 已经包含 geosite:cn,对应订阅又在自己的扩展配置中写了 nameserver-policy。
| 所在层 | 写入内容 | 结果 |
|---|---|---|
| 全局扩展配置 | nameserver-policy 中含 geosite:cn | 先形成全局策略 |
| 订阅扩展配置 | 写入该订阅自己的 nameserver-policy | 替换此前的同名字段 |
订阅扩展执行得更晚,而该字段按整体替换处理,因此全局层里的 geosite:cn 不会自动带入订阅层的新内容。
文档给出的处理方向有两个:在订阅扩展配置中也写入需要保留的 geosite:cn;或在订阅扩展脚本的 main(config) 中追加所需内容。
两种方式对应不同的处理层。使用 YAML 时,要把需要保留的内容纳入替换后的字段;使用脚本时,则是在前面已经形成的配置上继续处理。相关入口与处理方式见扩展脚本的使用说明。
为什么写进扩展仍被应用设置覆盖
应用会接管一部分设置。扩展即使写了这些字段,链尾的回写仍会丢弃相应修改。
文档列出的范围包括:
- 部分顶层字段,例如
mixed-port、mode、ipv6。 tun.enable,以及 TUN 弹窗保存的字段。- 特定条件下的
dns.ipv6。
这与列表替换、对象合并是两回事。合并规则决定扩展层之间怎样处理数据;应用回写决定由应用接管的值如何进入最终配置。
遇到这类覆盖时,应用会在对应扩展处显示提示,并写入日志。检查时应把提示与处理链一起看,不能仅凭 YAML 中存在某个值,就认定最终配置采用了它。
把追加、覆盖与回写分开检查
扩展配置用于覆写和合并。文档已将 prepend/append 的操作放到可视化编辑器中;对于 YAML 键使用 prepend-、append- 前缀的写法,官方没有说明。
排查结果与预期不一致时,可以依次检查:
- 修改放在全局范围,还是单个订阅范围。
- 后续扩展是否再次写入同一字段。
- 目标是列表、普通值,还是按子键合并的对象。
- 涉及 DNS 时,是否触发已写字段的整体替换。
- 目标字段是否属于应用接管范围。
扩展配置与脚本文档列出了这些层的关系。理解 Merge 的重点,是沿着处理链追踪同一字段,而不是只看某一份扩展里写了什么。
第三方整理,与项目方无关。