首页 · jinx.mom

Clash Verge Rev 扩展脚本不能跑怎么办?按入口、报错和配置覆盖排查

更新于 2026-10-20 · jinx.mom

简答:导入脚本后没反应、运行报错或策略组变空时,先确认你使用的是 Clash Verge Rev 的“扩展脚本”入口,而不是 YAML“扩展配置”。粘贴最小的 main(config) 测试代码,先在扩展脚本编辑器或开发者控制台确认是否执行,再按报错、字段结构和应用设置覆盖逐层排查。本文只适用于 Clash Verge Rev,不适用于其他客户端的脚本机制。

定义:Clash Verge Rev 扩展脚本是运行在客户端内置 JavaScript 执行环境中的配置处理代码,通过 main(config) 接收并返回配置对象;它不同于 YAML 扩展配置,也不等同于内核脚本或其他客户端的模块脚本。

先试这一步:用最小脚本确认有没有执行

如果你遇到“脚本导入成功但没有变化”“策略组突然为空”或保存时直接报错,不要先改 DNS、TUN 或节点。先在 Clash Verge Rev 的配置卡片上右键,找到“编辑扩展/脚本”;不同版本的界面文案可能略有差异,以当前界面为准。官方文档说明,扩展脚本需要通过 main 函数接收配置对象,并返回修改后的配置。可先查看Clash Verge Rev 自定义脚本说明。

先把原脚本备份,再临时替换为下面的最小代码:

function main(config) { console.log("script-test"); return config; }

  1. 保存扩展脚本。
  2. 重新加载、更新或重新激活对应配置,让客户端重新生成配置。
  3. 优先查看扩展脚本编辑区域、脚本运行结果或开发者控制台,搜索 script-test。
  4. 如果扩展脚本区域没有输出,再查看该扩展卡片的错误提示或日志;不要只在内核日志中搜索,因为 console 输出位置可能随版本和调试入口不同而变化。
  5. 最小脚本能执行后,再逐段恢复原脚本,每次只增加一个修改目标。

官方文档列出了脚本环境支持 console,项目讨论中也有在全局扩展脚本区域查看 console.log 输出的说明。由于不同版本的界面可能不同,最稳妥的判断方式是同时观察脚本编辑区域、开发者控制台和扩展卡片提示,而不是把内核日志作为唯一依据。可参考项目讨论中的扩展脚本调试说明。

四类症状的第一处理动作
现象优先检查第一步处理
脚本无法保存或导入入口、脚本类型、基础语法确认编辑的是“扩展脚本”,先粘贴最小 main(config)。
导入成功但完全无变化是否启用、是否重新生成配置保存后重新加载或激活配置,再查看脚本区域的输出。
脚本执行时报错入口函数、沙箱 API、字段路径记录完整报错关键词,暂时删除外部模块、文件读写和网络请求。
脚本执行后策略组或节点为空过滤条件、数组判空、节点名称引用先保护数组,再确认过滤结果和策略组引用的节点确实存在。
脚本修改后又恢复应用设置和扩展执行顺序检查设置页是否接管了模式、端口、TUN 或部分 DNS 字段。

先分清脚本类型:JavaScript 扩展脚本不是 YAML 配置

“模块脚本不能跑”经常不是代码本身的问题,而是脚本被放进了错误的入口。Clash Verge Rev 官方文档将扩展分为“配置”和“脚本”:配置使用 YAML 做覆写或合并,脚本使用 JavaScript 处理配置对象。两者的编辑入口、语法和报错方式不同,不能把 JavaScript 代码粘贴到 YAML 扩展配置中。可查看Clash Verge Rev 扩展配置与脚本说明。

Clash Verge Rev 中常见机制对照
机制主要格式是否需要 main(config)常见用途
扩展配置YAML不需要覆写 dns、rules、tun 等配置字段。
扩展脚本JavaScript需要按条件修改规则、策略组、DNS 或订阅生成的配置对象。
内核配置YAML不需要供 Mihomo 内核实际读取的完整配置,不等于客户端脚本。
其他客户端脚本因客户端而异不一定其他桌面端或移动端可能使用 Actions、覆写、插件或不同的脚本 API。

本文只讲 Clash Verge Rev 的扩展脚本。Clash for Windows 的 Actions 或 parsers、移动端客户端的模块与插件机制,以及其他客户端的脚本参数,不应直接套用本文代码。即使文件后缀都是 .js,入口函数、可用 API、执行时机和返回值要求也可能不同。

按报错关键词排查:入口、语法和脚本沙箱

1. 先确认入口函数和返回值

Clash Verge Rev 官方文档说明,脚本入口是 main 函数,接收一个配置对象,并返回修改后的配置对象。最稳妥的基础结构如下:

function main(config) { return config; }

如果脚本没有定义 main,或者最后返回了字符串、布尔值、数组等非配置对象,可能出现入口未找到、返回对象无效或配置无法生成等问题。具体报错文案可能因内置 JavaScript 引擎和版本而不同,不要只按某一条固定英文报错判断。

2. 使用 Node.js 做语法检查,但不要把它当成兼容性测试

如果你把脚本复制到本地文件,可以在 PowerShell 或终端中运行:

node --check script.js

它只能检查括号、引号、关键字等基础 JavaScript 语法,不能验证 Clash Verge Rev 的内置执行环境、传入参数、配置字段结构或应用设置优先级。即使语法检查通过,仍需在客户端内实际运行最小脚本。

3. 遇到 require、import、文件或网络相关错误

官方文档说明,Clash Verge Rev 扩展脚本使用 boa_engine 执行,并且不支持网络 IO 和文件 IO。遇到 require is not defined、文件读取失败、请求接口失败,或使用 ES 模块语法后出现 SyntaxError 等情况,应删除 Node.js 模块、动态加载、文件读写和网络请求代码,改为只处理传入的 config 对象。

支持的 API 中包含 console、JSON、数组、正则表达式和常见错误对象,但这不代表可以直接使用 Node.js 的内置模块。报错关键词可能因执行引擎而异,建议保留完整错误文本和出错行号,再逐段缩小代码范围。

4. 需要区分订阅时,再使用第二个参数

官方文档说明,较新的版本增加了字符串类型的 profileName 参数。可以这样写:

function main(config, profileName) { if (profileName === "订阅A") { config["log-level"] = "debug"; } return config; }

如果脚本来自其他客户端,不要默认它也会传入同名参数。先用只有一个参数的 main(config) 验证执行,再加入第二个参数和条件逻辑。

脚本执行了但策略组或节点为空:加判空保护再查引用

如果最小脚本能够输出,但原脚本执行后节点、代理组或规则消失,重点检查过滤条件和字段结构。常见风险是直接把 proxies 过滤成空数组,或者策略组中引用了订阅里并不存在的节点名称。不要先假设是线路故障,先在脚本中加入判空和数量检查。

下面的示例只在代理组存在且原本有节点时进行过滤,并保留过滤前后的数量信息:

function main(config) { const groups = Array.isArray(config["proxy-groups"]) ? config["proxy-groups"] : []; groups.forEach(group => { if (group && group.name === "示例策略组" && Array.isArray(group.proxies)) { const before = group.proxies.length; const filtered = group.proxies.filter(name => typeof name === "string" && !name.includes("测试")); if (filtered.length > 0) { group.proxies = filtered; } console.log("group", group.name, "before", before, "after", group.proxies.length); } }); return config; }

  1. 把 示例策略组 换成配置中真实存在的策略组名称。
  2. 先确认 config["proxy-groups"] 是数组,再访问其中的 proxies。
  3. 过滤后如果数量为零,先不要覆盖原数组,避免整个策略组失去节点。
  4. 如果策略组仍为空,检查订阅生成的节点名称是否和脚本中的字符串完全一致。
  5. 脚本恢复正常后,再逐步加入规则、DNS 或其他字段修改。

Clash Verge Rev 官方示例也使用数组和配置对象进行规则、策略组等字段处理,因此脚本修改前应先确认字段存在、类型正确,并保留返回的 config 对象。可参考官方自定义脚本示例。

常见报错速查卡
报错或现象可能原因修复动作
main 未定义或入口错误函数名称不对,或代码没有定义入口改为 function main(config) { return config; } 测试。
SyntaxError括号、引号、关键字或模块语法不适配先运行 node --check,再删除 import 等不必要语法。
ReferenceError使用了不存在的变量、Node.js 全局对象或外部模块检查变量是否定义,删除 require、文件和网络依赖。
TypeError对不存在的对象或非数组字段调用方法使用 Array.isArray、空值判断和条件初始化。
执行后节点或策略组为空过滤结果为空,或引用名称不存在打印过滤前后数量,保留非空结果并核对名称。
修改 DNS、TUN 或端口后恢复应用设置在扩展流程末尾覆盖字段检查设置页接管项和扩展卡片提示。

执行顺序导致配置被覆盖:检查应用设置和扩展合并规则

脚本能够执行,不代表脚本写入的每个字段都会成为最终配置。Clash Verge Rev 官方文档给出的扩展链路是:订阅原文、应用设置、全局扩展配置、全局扩展脚本、订阅扩展配置、订阅扩展脚本,最后再进行应用设置回写。设置页中的选项优先级高于订阅原文、扩展配置和扩展脚本,部分字段会被应用接管。

因此,如果脚本修改了 mode、端口、tun.enable、TUN 细项或部分 DNS 字段,界面设置可能在最终生成配置时重新写回。官方文档明确列出了应用接管的字段,并说明被覆盖时会在扩展卡片日志中记录。详细执行顺序和优先级可查看扩展配置与脚本官方说明。

  • 脚本修改 DNS 后恢复:检查 DNS 覆写是否开启,以及设置页是否接管了相关字段。
  • 脚本修改 TUN 后恢复:检查 TUN 设置中的启用状态、路由、DNS 劫持、MTU 等项目。
  • 脚本修改模式或端口后恢复:检查客户端设置中的运行模式、混合端口、 SOCKS 端口或其他端口选项。
  • 全局脚本和订阅脚本结果不同:确认脚本放置范围,并注意订阅扩展脚本在执行链路中更靠后。
  • DNS 规则被替换:扩展配置中的部分 DNS 字段按整体替换处理,不一定是逐项合并;需要保留多项内容时,应在脚本中读取原对象后再追加。

排查时应查看最终生成的配置,而不是只看脚本源码。可以先关闭一个可能接管目标字段的应用设置,重新生成配置,再比较修改前后的结果;确认原因后,再决定由脚本还是由设置页统一管理该字段。

安全与回滚:先备份订阅和脚本,再缩小复现范围

扩展脚本会参与订阅配置生成,修改前先备份当前脚本和配置。订阅链接、访问令牌、API 密钥、控制器密钥以及包含个人信息的日志,不要粘贴到公开脚本、截图或问题帖中。

  1. 复制当前扩展脚本,保存一份可以恢复的原始版本。
  2. 暂时只保留 main(config) { return config; } 或最小测试代码。
  3. 确认最小脚本可以执行后,只增加一个目标,例如先测试规则,再测试策略组,最后测试 DNS 或 TUN。
  4. 每次修改后重新生成配置,并在扩展脚本区域或开发者控制台观察输出。
  5. 发现远程脚本包含网络请求、文件读写、动态加载或难以解释的混淆代码时,不要直接启用。
  6. 如果最小脚本正常而原脚本失败,优先检查 API、字段结构、过滤逻辑和应用设置优先级,而不是立即更换节点。

如果仍无法判断问题来自脚本、订阅配置还是网络连接,可以停止使用原脚本,用不含敏感信息的最小配置复现,再分别恢复配置和脚本。本站是第三方使用指南站,不是 Clash Verge Rev 官方站;版本界面和脚本行为如有差异,应以当前客户端文档和实际提示为准。

常见问题

Clash Verge Rev 扩展脚本不能跑,最先应该检查什么?

先确认脚本放在配置卡片的“扩展脚本”入口,而不是 YAML“扩展配置”入口。然后用 function main(config) { console.log("script-test"); return config; } 测试,并在扩展脚本编辑区域、运行结果或开发者控制台查看输出。

为什么 console.log 输出不在客户端内核日志里?

Clash Verge Rev 官方文档只说明脚本环境支持 console,项目讨论显示扩展脚本输出可以在全局扩展脚本区域查看。不同版本的调试入口可能不同,因此应优先查看脚本编辑区域或开发者控制台,不要只搜索内核日志。

node --check 通过后,为什么 Clash Verge Rev 仍然报错?

node --check 只能检查基础 JavaScript 语法,不能验证 Clash Verge Rev 的内置 JavaScript 执行环境、main 参数、配置字段结构或应用设置优先级。语法通过后仍需在客户端内运行最小脚本。

Clash Verge Rev 扩展脚本支持 require、import 或网络请求吗?

官方文档说明扩展脚本使用 boa_engine 执行,不支持网络 IO 和文件 IO。遇到 require、文件读取或网络请求相关错误时,应改为只处理传入的 config 对象;import 写法出错时,报错关键词可能因执行引擎而异。

为什么脚本执行后策略组或节点为空?

常见原因是脚本把 proxies 过滤成了空数组,或策略组引用了订阅中不存在的节点名称。先用 Array.isArray 检查字段,记录过滤前后的数量,过滤结果为空时不要覆盖原数组,再核对策略组和节点名称。

为什么脚本修改了 DNS 或 TUN,重新加载后又恢复?

Clash Verge Rev 的应用设置优先级高于扩展配置和扩展脚本,部分 DNS、TUN、模式和端口字段会在扩展流程后被应用设置回写。应检查设置页的接管项,并查看最终生成配置和扩展卡片提示。

其他客户端的 Clash 模块脚本可以直接放进 Clash Verge Rev 吗?

不建议直接套用。其他桌面端和移动端可能使用 Actions、覆写、插件或不同的入口函数和参数。本文只适用于 Clash Verge Rev 扩展脚本,跨客户端使用前应先核对对应客户端的脚本文档。

相关阅读

参考资料

  1. Clash Verge Rev Docs:自定义脚本(clashverge.dev)
  2. Clash Verge Rev Docs:扩展配置与脚本(clashverge.dev)
  3. Clash Verge Rev GitHub Discussion:如何调试全局扩展脚本