Loon 插件开发技能
何时使用
- 编写或修改 Loon 插件(
.plugin文件) - 编写 Loon 复写(Rewrite)规则,尤其是新版
if ... then ...语法 - 编写 Loon 脚本(去广告、签到、解锁、定时任务)
- 排查插件不生效、参数读不到、Rewrite 报错、MitM 未解密
- 把旧语法插件迁移到新语法
核心原则
- 先确认目标 Loon 版本。本技能覆盖的多数能力有明确的版本门槛,写错
#!loon_version会导致用户端直接不可用。 - 优先使用新版 Rewrite 语法。旧语法仅作输入兼容,Loon 的生成、保存和配置展示统一输出新语法。
- 不要凭记忆写 Action 名和参数顺序。Action 使用严格的位置参数,写错会在加载时被拒绝整条规则。动手前查
references/rewrite-v2.md。 - HTTPS 必须配 MitM。Rewrite 和 http 脚本只对 HTTP 以及经 MitM 解密的 HTTPS 生效,漏写
[Mitm] hostname是最常见的「不生效」原因。
插件骨架
#!name = 示例插件
#!desc = 展示插件信息和用户参数
#!author = Loon
#!homepage = https://example.com
#!icon = https://example.com/icon.png
#!system = iOS,iPadOS,tvOS,macOS
#!system_version = 15
#!loon_version = 3.5.1(978)
#!tag = 示例,工具
#!type = normal
[Argument]
name = input,"Loon",tag=名称,desc=输入一个名称
region = select,"CN","US","JP",tag=地区
enabled = switch,true,tag=启用
[General]
bypass-tun =
skip-proxy =
real-ip =
dns-server =
[Rule]
[Rewrite]
[Host]
[Script]
http-response ^https?:\/\/example\.com\/conf\/server-mapping script-path=remove_ads.js,requires-body=true,tag=移除广告,argument=[{name},{region},{enabled}]
[Mitm]
hostname = example.com
模块都是可选的,按需保留。写插件时不要保留空的 [General] 占位键(bypass-tun = 等),会覆盖用户的通用配置。
元信息字段
| 字段 | 说明 |
|---|---|
#!name |
插件名称 |
#!desc |
功能说明 |
#!author |
作者 |
#!homepage |
主页地址 |
#!icon |
图标地址 |
#!system |
支持的系统,不区分大小写;未填写表示全部支持 |
#!system_version |
最低系统版本,如 15.0 |
#!loon_version |
最低 Loon 版本,如 3.5.1(978) |
#!tag |
分类标签 |
#!type |
插件类型 |
#!type 从 Loon 3.5.0 (969) 起支持:
normal:普通插件parser:资源解析器,可在节点、规则和配置订阅页面中选择
[Argument] 用户参数
需要 Build 733+。Loon 会据此自动生成设置界面。
参数名 = 控件类型,默认值或可选值,tag=标题,desc=说明
| 控件 | 说明 | 支持类型 | 默认类型 |
|---|---|---|---|
input |
文本输入;默认值可省略 | String、Number | String |
select |
单选列表;第一个值为默认值 | String、Number | String |
switch |
开关;默认值为 false |
Boolean | Boolean |
需要数字类型时显式声明 type=number:
price = input,9.99,type=number,tag=价格
level = select,1,2,3,type=number,tag=等级
未声明 type 的旧插件保持原行为(input/select 按 String,switch 按 Boolean)。
引用语法在两处不同 —— 最高频错误
| 使用位置 | 写法 | 示例 |
|---|---|---|
[Script] 的 argument |
{参数名} |
argument=[{name},{region}] |
[Script] 的其他字段 |
{参数名} |
enable={enabled}、cron {cronExpression} |
新版 [Rewrite] |
${参数名} |
${region}、${price} |
脚本内通过 $argument.name 读取。switch 参数可直接控制脚本开关:enable={enabled}。
本地 Rewrite 没有 [Argument] 来源,本地编辑页只能用内置变量和当前 Rewrite 的正则捕获。
插件内规则的策略限制 —— 第二高频错误
插件 [Rule] 里只能使用这三类策略:
DIRECTREJECT系列PROXY
不能直接写用户的策略组名。PROXY 表示交由用户选择策略组。规则未指定策略时默认 DIRECT。
Rewrite 速览
新版语法(Loon 3.5.1 (978) 起):
<阶段> if <条件> then <Action>[ | <Action> ...]
request if ${url} ~= /^https:\/\/api\.example\.com/ then request.header.set("X-Loon", "true")
response if ${url} ~= /^https:\/\/api\.example\.com\/profile$/ && ${response.status} == 200 then response.json.replace("data.vip", true)
- 阶段只有
request和response,一条规则不能混用请求 Action 和响应 Action(response.body.mock是特例)。 - 比较用
==(精确)和~=(正则查找,需完整匹配时自行加^$)。 - 多个 Action 用
|连接,从左到右执行。 - 内置变量:
${url}、${request.method}、${request.header['name']}、${response.status}、${response.header['name']}。 if条件中读不到 Body,${request.body}/${response.body}/ JSON Key Path 均不支持。
完整的 Action 清单、参数顺序、批量数组参数、正则捕获(as)、Mock 限制、旧语法迁移表见 references/rewrite-v2.md。旧语法维护见 references/rewrite-legacy.md。
脚本速览
| 类型 | 触发时机 |
|---|---|
http-request |
请求发出前 |
http-response |
收到响应后 |
cron |
按 Cron 表达式定时 |
network-changed |
网络环境变化(配置多条只执行第一条) |
generic |
App 内手动触发 |
http-response ^https?:\/\/example\.com script-path=response.js,requires-body=true,tag=响应脚本,timeout=10,argument="name=loon",enable=true
cron "0 8 * * *" script-path=cron.js,tag=定时任务,timeout=300
要读 Body 必须显式加 requires-body=true,否则 $request.body / $response.body 为空。脚本结束务必调用 $done()。
脚本类型详细参数与 $done() 返回格式见 references/script-types.md,API 清单见 references/script-api.md。
排查清单
不生效时按顺序检查:
- HTTPS 是否配了 MitM ——
[Mitm] hostname = example.com,且用户已安装并信任证书。 - URL 正则是否真的匹配 —— 插件里的正则需转义
/,如^https?:\/\/example\.com。 - 是否漏了
requires-body=true—— 需要读写 Body 的脚本必须显式声明。 - 策略是否越界 —— 插件规则里写了用户策略组名,改成
PROXY。 - 参数引用语法是否用错 —— Script 用
{name},新版 Rewrite 用${name}。 - 版本门槛是否够 ——
[Argument]需 733+,新版 Rewrite 需 3.5.1(978)+,#!type需 3.5.0(969)+。 - Action 参数顺序与类型 —— 位置参数不能写参数名,可选参数只能从右往左省略。
- 来源优先级 —— 本地配置 > 插件 > 订阅。本地同类配置会覆盖插件。
Loon 加载配置时会做静态检查,错误信息带行号和原因,优先看它:
Rewrite 第 18 行:未定义的参数 ${price2}
Rewrite 第 21 行:正则 item 只有 2 个捕获组,不能引用 ${item.3}
Rewrite 第 25 行:request 阶段不能引用 ${response.status}
交付约定
产出插件时:
- 明确标注
#!loon_version,取所用特性中的最高门槛。 - 用到 HTTPS 拦截就必须给出
[Mitm] hostname。 - 参数化的插件要在
[Argument]中写清tag和desc,这是用户唯一能看到的说明。 - 说明脚本需要联网请求哪些域名,便于用户判断隐私影响。
按需阅读
- 新版 Rewrite 完整语法:
references/rewrite-v2.md - 旧版 Rewrite 语法与迁移:
references/rewrite-legacy.md - 脚本类型与
$done()格式:references/script-types.md - Script API 清单:
references/script-api.md - 分流规则类型:
references/rules.md - 可运行示例插件:
references/examples.md
来源
内容整理自 Loon 官方文档 https://nsloon.app/docs/intro,抓取日期 2026-08-04,对应 Loon 3.5.1 (978) 前后的文档状态。Loon 更新后请以官网为准。