接上一篇博客: ast-grep:结构化搜索与重构利器ast-grep 的主要论点是在文本 grep 与重量级 AST 工具之间建立一座 - 掘金
在多语言项目里,文件扩展名未必等于想要的解析语法:比如 .vue 内嵌 <script setup lang="tsx">,但默认解析器可能把整文件当成 Vue 语法,导致 TS/TSX 规则匹配不到。ast-grep 提供两条路可以"强制"指定解析语言:
- 命令行临时指定
--lang; - 在规则/配置文件里用
language覆盖。 本文给出可直接复用的命令、配置示例,以及在 Vue/Pug 场景下的避坑方案。
方法一:命令行临时指定语言
适合一次性查询或快速验证模式。
基本用法
bash
sg run --lang tsx -p 'defineProps($P)' src/views/yufukuan/Yufukuan.vue
--lang tsx:强制把输入文件按 TSX 解析,即使扩展名是.vue。-p 'defineProps($P)':模式示例,可替换成任意 TS/TSX 语法模式。
如果模板干扰解析
- 现有 tree-sitter-vue 对
lang="pug"模板不做 AST 解析,命令会把模板当作文本,可能触发 ERROR。 - 解决思路:
-
仅喂
<script>部分:先用脚本提取<script>,再通过 stdin 传给 sg。bashnode -e "const fs=require('fs');const txt=fs.readFileSync('src/views/yufukuan/Yufukuan.vue','utf8');const m=txt.match(/<script[\\s\\S]*?<\\/script>/);if(m)process.stdout.write(m[0]);" \ | sg run --lang tsx --stdin -p 'defineProps($P)' -
临时改模板为普通 HTML(不改需求时就别这么做),确认解析器可工作后再回滚。
-
只想做文本级匹配
如果解析器对模板报错,可以降级用模板严格度或纯文本:
bash
sg run --lang vue --strictness template -p 'handlerEditInst' src/views/**/*.vue
这不会给出 AST 结构,但可在 VSCode/CLI 内快速找关键词。
方法二:在规则/配置里指定语言
适合需要多次复用的规则或集成到 sg scan 的场景。
规则文件示例
新建规则 rules/vue-script-tsx.yml:
yaml
id: vue-script-tsx-define-props
language: tsx # 这里强制按 TSX 解析
rule:
pattern: "defineProps($P)"
要让规则只作用于指定路径,可以配合 files 或在运行时用 --globs:
bash
sg scan --config sgconfig.yml --globs "src/**/*.vue" --rules vue-script-tsx-define-props
说明:
language字段覆盖扩展名默认解析器。- 模式仍需符合该语言语法;若模板残留会导致 ERROR,可结合"只喂脚本"或在规则里增加条件过滤。
针对 JS/JSX 的示例
yaml
id: vue-script-jsx-import-check
language: jsx
rule:
pattern: "import $A from '$B'"
运行:
bash
sg scan --config sgconfig.yml --globs "src/**/*.vue" --rules vue-script-jsx-import-check
常见问题与处理
- "Pattern contains an ERROR node":
- 解析器在遇到模板/非目标语法时产生错误。尝试提取
<script>后再解析,或临时移除 Pug 语法测试。
- 解析器在遇到模板/非目标语法时产生错误。尝试提取
- "matched nothing" 且无错误:
- 确认模式语法合法;用
--debug-query=pattern查看解析结果。
- 确认模式语法合法;用
- VSCode 插件无结果但 CLI 正常:
- VSCode 也依赖同一解析器,对 Pug/TSX 一样受限。可在插件里用文本模式,或等待支持更好的解析器。
实操建议(Vue 项目)
-
先在 CLI 验证:
bashsg run --lang tsx -p 'defineProps($P)' src/views/foo.vue -
若模板导致 ERROR,先用脚本提取
<script>再搜。 -
需要重复用的查询,写进
rules/*.yml,加上language: tsx/js/jsx,通过sg scan --globs "src/**/*.vue"运行。 -
如果必须结构化解析模板层(Pug),要么把模板改为 HTML,要么寻找/自建支持 Pug 的 Vue 解析器重新编译
vue.so。
结语
ast-grep 支持在命令行和规则层双重覆写解析语言,这让你可以在混合文件中对脚本部分进行结构化搜索。但解析器能力是天花板:当模板/脚本语法不被支持时(如 Pug + TSX),需要先裁剪输入或更换解析器,否则只能退化为文本匹配。按照本文的命令与配置示例,可以快速在 Vue 项目里对脚本逻辑做 TS/TSX/JSX 级别的精确查询,而不必等待默认解析器完善。***