尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Nuxt ESLint 开发者指南:no-page-meta-runtime-values 规则源码精讲——AST 分析与函数深度追踪

Nuxt ESLint 开发者指南:no-page-meta-runtime-values 规则源码精讲——AST 分析与函数深度追踪 Nuxt ESLint 开发者指南no-page-meta-runtime-values 规则源码精讲——AST 分析与函数深度追踪【免费下载链接】eslint-configCollection of ESLint-related packages for Nuxt项目地址: https://gitcode.com/gh_mirrors/esl/eslint-configNuxt ESLintnuxt/eslint系列内置的no-page-meta-runtime-values规则专门拦截definePageMeta宏顶层eager 层中不合法的运行时值比如useRoute()、ref()、await等。这条规则是理解ESLint 自定义规则如何结合 AST 分析与函数深度追踪做静态检查的优秀范例。本文带你读懂它的源码设计与测试验证思路。 为什么 definePageMeta 会嫌弃运行时值Nuxt 在构建时会把definePageMeta宏抽取到一个独立的 chunk它先于组件 setup 执行。这意味着顶层作用域里没有this、没有 effect scopeuseRoute()、useNuxtApp()这类依赖 setup 上下文的组合式函数无法工作await语法在抽取产物中也不被支持。而写在middleware/validate内联函数内部的代码是在路由导航时才执行的这些 API 全部可用。规则的任务就是用 AST 静态分析精确区分这两种场景。 规则源码的三大零件规则主体位于 no-page-meta-runtime-values.ts由三块核心逻辑组成1️⃣ CONTEXT_APIS依赖上下文的 API 名单源码维护了一个 Set 名单L17-L51收录三类 Vue API分类示例依赖什么响应式 APIref、computed、watch活跃的 effect scope生命周期钩子onMounted、onBeforeUnmount组件实例上下文组件上下文inject、getCurrentInstance当前实例2️⃣/^use[A-Z]/正则一网打尽所有组合式函数第 59 行 用一个正则匹配useXxx命名约定这样无论内置的useRoute、还是第三方库的useI18n、useAuth只要出现在顶层都会被捕获——不需要枚举天然可扩展。3️⃣ meta.messages三种精准报错规则元信息L63-L73 定义了 3 类错误消息composableCall顶层调用了依赖运行时上下文的函数建议移入middleware或validatethisExpression顶层使用了thisawaitExpression顶层使用了await。规则通过 createRule 工具函数 创建并在 rules/index.ts#L10 统一注册导出。 AST 分析如何识别 definePageMeta 的边界核心思路是先找到宏调用节点把它当作一个作用域边界只在该边界内、且未进入任何内联函数时做检查。CallExpression 监听器L100-L120 做了两件事定位边界当被调用者是名为definePageMeta的标识符时记下该节点definePageMetaNode检查顶层调用若当前已处于边界内isAtEagerLevel()且调用名命中CONTEXT_APIS或use[A-Z]正则立即context.report。对应的 CallExpression:exitL122-L127 在离开宏调用节点时把状态重置为初始值——这是 ESLint 规则开发中防止状态泄漏到其他代码的关键细节。判定函数只有一行isAtEagerLevel() 边界存在 functionDepth 0。 函数深度追踪functionDepth 如何区分顶层与内联函数这是本规则最精巧的部分。L131-L136 对三类函数节点监听进出ArrowFunctionExpression箭头函数FunctionExpression函数表达式FunctionDeclaration函数声明每次进入函数functionDepth离开时functionDepth--enterFunction / exitFunctionL87-L95。效果如下definePageMeta({ layout: ref(admin), // depth 0 → 报错 middleware: (to) { const r useRoute() // depth ≥ 1 → 放行 return r.path ! /admin } })同样地ThisExpressionL140-L147和AwaitExpressionL149-L156也只在内联函数外depth 0才报告。✅ 测试用例验证valid 与 invalid 的分界线测试文件 no-page-meta-runtime-values.test.ts 用两类用例完整刻画了规则的边界✅ 合法valid场景L7-L102纯静态值layout: admin、meta: { title: Home }外部变量与导入import { PAGE_TITLE } from ./constants后引用——构建时会提升这些依赖顶层引用是安全的内联函数中任意使用useRoute()、useNuxtApp()、await、this——导航时才执行。❌ 非法invalid场景L104-L185顶层ref(admin)、computed(...)、useRoute().name、useI18n()、inject(key)、onMounted(...)全部命中composableCall顶层this.layout、await getTitle()分别命中另外两类错误一条代码多个错误时逐一报告如definePageMeta({ route: useRoute(), data: ref(null) })。这份测试用例本身就是一份规则说明书值得在定制类似规则时参考。️ 如何启用这条规则通常无需手动配置nuxt/eslint模块和nuxt/eslint-config已自动包含它见 插件文档手动启用在 ESLint 配置中将nuxt/no-page-meta-runtime-values设为error即可可视化检查Nuxt DevTools 中的 ESLint Config Inspector 可以按插件、状态、使用方式过滤和查看全部 102 条规则非常方便定位这条规则的生效情况想通读全部源码获取仓库后即可在packages/eslint-plugin/目录下查看git clone https://gitcode.com/gh_mirrors/esl/eslint-config❓ 常见疑问速答问为什么t(home)、someHelper()不被报告规则只拦截依赖运行时上下文的调用名单 use[A-Z]正则普通工具函数在构建期是安全的。问顶层引用一个外部常量为什么合法这些模块级依赖会被构建过程提升hoist进独立 chunk执行时已经存在与需要活跃 setup 上下文的 API 有本质区别。问想给自己的宏写类似规则该抄哪个设计三件套照搬即可入口/出口监听定位宏边界 深度计数器区分顶层与内联函数 单一判定函数isAtEagerLevel。小结no-page-meta-runtime-values 用不到 200 行代码演示了 ESLint 规则开发的精髓——边界定位、状态追踪与精准报告。读懂它你就掌握了为 Nuxt 编写项目感知型自定义规则的通用套路。【免费下载链接】eslint-configCollection of ESLint-related packages for Nuxt项目地址: https://gitcode.com/gh_mirrors/esl/eslint-config创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表