直接编辑订阅文件是新手常犯的错误:改完确实生效,但订阅一更新,全部修改灰飞烟灭。Clash Verge 提供了正确的解法——Merge 和 Script,把「你的修改」和「服务商的配置」分开存放,运行时叠加。

订阅配置经过 Merge 与 Script 处理后生成最终配置的流程
每次生效顺序:订阅原文 → Merge 合并 → Script 加工 → 内核加载

机制:叠加而不是修改

内核每次加载配置时的流水线:订阅原文 → 应用 Merge(声明式合并)→ 执行 Script(JavaScript 加工)→ 得到最终配置。订阅更新只替换第一环,你的 Merge 和 Script 原样保留、自动重新叠加。

入口:「订阅」页面右键「全局扩展配置」,或右键某个订阅卡片选「编辑 Merge / 编辑 Script」(前者对所有订阅生效,后者只作用于该订阅)。

Merge:够用九成场景

Merge 文件也是 YAML,用带前缀的字段声明合并行为。最常用的三个前缀:prepend-(插到最前)、append-(追加到最后)、直接写字段名(整体覆盖)。

# 在规则列表最前面插入自己的规则(优先级最高)
prepend-rules:
  - DOMAIN-SUFFIX,company-vpn.example,DIRECT
  - PROCESS-NAME,Telegram.exe,PROXY

# 覆盖 DNS 配置
dns:
  enable: true
  enhanced-mode: fake-ip
  nameserver:
    - https://223.5.5.5/dns-query

# 追加一个自用分组
append-proxy-groups:
  - name: "流媒体"
    type: select
    proxies: [HK-01, SG-02]

规则用 prepend 还是 append 有讲究:想抢在订阅规则之前生效(比如强制某域名直连)用 prepend;做兜底补充用 append。规则语法本身见自定义规则

Script:处理动态逻辑

Merge 做不到的(按条件改节点名、批量过滤、动态生成分组),交给 Script。它是一个 JavaScript 函数,入参是合并后的配置对象,返回值就是最终配置:

function main(config) {
  // 过滤掉名字带「到期」「剩余」的信息节点
  config.proxies = config.proxies.filter(
    p => !/到期|剩余|流量/.test(p.name)
  );
  // 给所有 vmess 节点强制开启 udp
  config.proxies.forEach(p => {
    if (p.type === "vmess") p.udp = true;
  });
  return config;
}

Script 里抛异常会导致配置加载失败、内核用不上新配置。改完先在「日志」页确认没有报错,再验证分流是否符合预期。

排查:改了没生效?

  1. 确认编辑的是当前选中的订阅(或全局扩展配置);
  2. 「日志」页面看有没有 YAML 语法错误——缩进错一格整段作废;
  3. 右键订阅卡片「重新激活」强制重载一次;
  4. 用「连接」页面实测流量命中的规则,验证 prepend 顺序是否如预期。

配置文件三大件还不熟的话,先补配置结构详解这一课。