让 ast-grep 听你的:指定语言解析 Vue/TSX/JSX 全流程

接上一篇博客: ast-grep:结构化搜索与重构利器ast-grep 的主要论点是在文本 grep 与重量级 AST 工具之间建立一座 - 掘金

在多语言项目里,文件扩展名未必等于想要的解析语法:比如 .vue 内嵌 <script setup lang="tsx">,但默认解析器可能把整文件当成 Vue 语法,导致 TS/TSX 规则匹配不到。ast-grep 提供两条路可以"强制"指定解析语言:

  1. 命令行临时指定 --lang
  2. 在规则/配置文件里用 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。
  • 解决思路:
    1. 仅喂 <script> 部分:先用脚本提取 <script>,再通过 stdin 传给 sg。

      bash 复制代码
      node -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)'
    2. 临时改模板为普通 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 项目)

  1. 先在 CLI 验证:

    bash 复制代码
    sg run --lang tsx -p 'defineProps($P)' src/views/foo.vue
  2. 若模板导致 ERROR,先用脚本提取 <script> 再搜。

  3. 需要重复用的查询,写进 rules/*.yml,加上 language: tsx/js/jsx,通过 sg scan --globs "src/**/*.vue" 运行。

  4. 如果必须结构化解析模板层(Pug),要么把模板改为 HTML,要么寻找/自建支持 Pug 的 Vue 解析器重新编译 vue.so

结语

ast-grep 支持在命令行和规则层双重覆写解析语言,这让你可以在混合文件中对脚本部分进行结构化搜索。但解析器能力是天花板:当模板/脚本语法不被支持时(如 Pug + TSX),需要先裁剪输入或更换解析器,否则只能退化为文本匹配。按照本文的命令与配置示例,可以快速在 Vue 项目里对脚本逻辑做 TS/TSX/JSX 级别的精确查询,而不必等待默认解析器完善。***

相关推荐
春风得意之时9 小时前
前端安装项目出现代理问题和ssl认证问题
前端·网络协议·ssl
星星电灯猴9 小时前
全面解决Charles抓取HTTPS请求响应中文乱码问题的方法与技巧
后端·ios
问心无愧05139 小时前
ctf show web入门109
android·前端·笔记
meilindehuzi_a9 小时前
透视 V8 底部:从物理内存到函数式哲学,重新解构 JavaScript 数组
开发语言·javascript·ecmascript
粉末的沉淀9 小时前
vue:Vite项目中高效管理纯色SVG图标的方案
前端·javascript·vue.js
FlyWIHTSKY9 小时前
JavaScript 和 TypeScript 分别是什么,可以相互写吗
javascript·ubuntu·typescript
YHHLAI9 小时前
JavaScript 数据结构精讲:数组底层与实战避坑
开发语言·javascript·数据结构
moMo9 小时前
Promise 的本质:不是异步处理,而是流程控制
javascript
dotnet909 小时前
PDF 页面尺寸上限是 14400。iText 直接加载成功的大图可能超过这个限制,需要在 setPageSize 之前等比缩放。
前端·javascript·html
threelab9 小时前
Three.js 几何图形变换 | 三维可视化 / AI 提示词
开发语言·前端·javascript·人工智能·3d·着色器