为什么我的自定义ESLint规则无法正确触发?
我在开发一个检查函数参数数量的ESLint插件,规则逻辑写好了但总不生效。比如写个加法函数:add(a, b)应该通过,但调用add(a)时规则没报错。
规则配置是这样的:
module.exports = {
meta: { ... },
create(context) {
return {
CallExpression(node) {
if (node.callee.name === 'add' && node.arguments.length !== 2) {
context.report({
node,
message: 'add必须接收两个参数'
});
}
}
};
}
};
测试用例明明符合条件,控制台却没有任何输出。我尝试在回调函数里加console.log('test')调试,发现这个方法根本没被调用过。是不是访问者模式的节点类型写错了?或者需要额外配置什么选项?
add(a)这种直接调用的情况,而实际项目里很可能用的是import { add } from './math'然后调用add(a),这时候node.callee.name是add,但node.callee.type是Identifier,不过更常见的是你插件没被 ESLint 加载进去,或者规则没注册。先确认几件事:
1. 你的规则是不是放在了
rules目录下,然后在index.js里正确导出了?比如:2. 你在 ESLint 配置里是不是写了插件名和规则名?比如
.eslintrc.js里:3. 最容易踩的坑:你用的是
&&而不是&&,这明显是复制粘贴时 HTML 实体转义没还原,直接导致语法错误或者逻辑错误。你贴出来的代码里是&&,这在 JS 里是两个字符&和amp;,不是逻辑与运算符。console.log('test')没执行是因为条件根本没进得去。修正后的代码应该是:
如果还是不触发,可以加个
console.log(node.type)看看有没有走到CallExpression,一般 ESLint 能走到这一步,除非你规则根本没被加载。另外如果函数是通过对象调用的,比如obj.add(a),那node.callee.name就是undefined了,得用node.callee.property.name。通用的做法是用
node.callee.type === 'Identifier' && node.callee.name === 'add'或者更稳妥地用node.callee.type === 'MemberExpression' && node.callee.property.name === 'add'来判断,或者用node.callee.type === 'Identifier' || (node.callee.type === 'MemberExpression' && node.callee.property.name === 'add')。如果还是不行,把你的完整插件目录结构贴出来看看,大概率是配置没对。
CallExpression没问题,但你漏了配置规则的meta.schema和测试环境的规则启用部分。直接复制下面的代码:另外,检查下你的 ESLint 配置文件,确保规则已经正确加载和启用。比如:
最后提醒一下,调试的时候不要只靠
console.log,可以在create方法里加个断点,确保规则注册进去了。我之前也踩过类似的坑,折腾半天发现是规则没启用来着。