ESLint通过解析器(如espree、@typescript-eslint/parser)将源码转换为ESTree标准AST,再遍历节点触发对应规则;规则监听特定节点类型(如CallExpression),依赖正确配置parserOptions(ecmaVersion、sourceType、jsx等)确保AST结构完整。

AST 是怎么被 ESLint 读进去的
ESLint 不是靠正则去“猜”代码结构,而是先把源码喂给解析器(parser),转成标准 AST(ESTree 格式),再逐个节点遍历检查。你写的规则本质就是监听特定 AST 节点类型,比如 CallExpression、JSXElement、VariableDeclarator。
默认用 espree,但项目里有 JSX 或 TypeScript 就得换:@babel/eslint-parser(旧项目)、@typescript-eslint/parser(TS 项目)。不配对 parser 和语法特性,AST 解析直接失败——比如没开 jsx: true 却检查 JSXElement,规则压根不会触发。
-
parserOptions.ecmaVersion必须 ≥ 你代码实际用的 ES 版本,否则async/await、可选链等节点根本不会出现在 AST 中 -
parserOptions.sourceType设为module才能正确解析import/export节点 - 用
astexplorer.net粘贴代码实时看 AST 结构,比盲写高效得多
写一条规则:禁止 console.log 但允许 console.error
核心逻辑就两步:匹配 CallExpression 节点 → 判断 callee.object.name === 'console' && callee.property.name === 'log'。不能只查 node.callee.name === 'console.log',那根本不是合法 AST 属性。
规则文件 lib/rules/no-console-log.js 长这样:
module.exports = {
meta: {
type: "suggestion",
docs: { description: "禁止使用 console.log" },
schema: [] // 无配置项
},
create(context) {
return {
CallExpression(node) {
const { callee } = node;
// 必须是 console.xxx 形式,且 callee 是 MemberExpression
if (
callee.type === "MemberExpression" &&
callee.object.type === "Identifier" &&
callee.object.name === "console" &&
callee.property.type === "Identifier" &&
callee.property.name === "log"
) {
context.report({
node,
message: "不允许使用 console.log,请改用 console.error 或其他方式"
});
}
}
};
}
};
- 别漏判
callee.type === "MemberExpression",否则会误伤foo.console.log() - 如果要支持配置白名单(如允许
error、warn),得在meta.schema定义,并用context.options[0]?.allow读取 - 测试时用
RuleTester写invalid用例,确保报错位置精准到行号
插件发布前必须验证的三件事
本地跑通不等于别人能用。一个可用的插件至少要过这三关:
- 入口文件
lib/index.js必须导出rules对象,键名和规则 ID 严格一致(比如"no-console-log": require("./rules/no-console-log")) -
package.json的name必须以eslint-plugin-开头,否则extends或plugins字段无法识别 - 用户项目里引用时,
plugins数组填的是插件名去掉前缀后的部分(如"wjcao-utils"),但规则 ID 前必须加插件名前缀(如"wjcao-utils/no-console-log")
为什么你的自定义规则在 IDE 里不报错
最常见原因是 VS Code 的 ESLint 插件没读到你的本地插件路径。它默认只认 node_modules 下已安装的包,不会自动 resolve 未 publish 的本地目录。
- 开发阶段,在用户项目中用
npm link或yarn link把插件 link 进去 - 确认用户项目的
.eslintrc.js里plugins和rules配置拼写完全正确(大小写、连字符、前缀) - VS Code 的 ESLint 输出面板(Output → ESLint)里常有解析失败提示,比如
Failed to load plugin 'xxx': Cannot find module 'eslint-plugin-xxx',这就是路径或 name 没对上
AST 规则本身不难,难的是让整个链路——从解析器、插件加载、规则注册到编辑器反馈——全部对齐。少一个环节,规则就只是个静态文件。

















