ESLint插件如何自定义规则来检测特定代码模式?

Mc.子武 阅读 23

最近在尝试通过ESLint插件来自定义一条规则,目的是检查项目中是否有直接使用了`alert()`函数的情况。我按照文档开始编写自己的规则,但是遇到了一些麻烦。


module.exports = {
  create(context) {
    return {
      CallExpression(node) {
        if (node.callee.name === 'alert') {
          context.report({
            node,
            message: 'Unexpected use of alert.'
          });
        }
      }
    };
  }
};

这段代码似乎没有生效,不知道是不是哪里写错了?也试过调整AST节点的匹配方式但都没有成功触发警告信息。希望有人能指点一下。

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
慕容永伟
你这个规则大体是对的,但问题出在 AST 节点判断不够严谨。当 alert() 出现在复杂表达式里时,node.callee.name 可能不是直接可访问的,比如被包装成 window.alert() 或者是变量引用的情况。

最简单的修复方式是先确认 callee 是一个标识符(Identifier),然后再判断名字:

module.exports = {
create(context) {
return {
CallExpression(node) {
const { callee } = node;
if (callee.type === 'Identifier' && callee.name === 'alert') {
context.report({
node,
message: 'Unexpected use of alert.'
});
}
}
};
}
};


这样就能准确捕获 alert() 调用。如果你还想进一步拦截 window.alert() 这种情况,可以扩展一下逻辑:

MemberExpression(node) {
const { object, property } = node;
if (
object.type === 'Identifier' && object.name === 'window' &&
property.type === 'Identifier' && property.name === 'alert'
) {
context.report({
node,
message: 'Unexpected use of window.alert.'
});
}
}


不过大多数场景下只检测直接调用就够了。先把基础规则跑通,再逐步迭代会更稳。

另外记得把这规则注册到插件里,并在 .eslintrc 中启用,不然也不会生效。别折腾半天规则写对了,结果没配进去……我也干过这种事。
点赞 2
2026-02-12 14:10
ლ子硕
ლ子硕 Lv1
你的代码其实没太大问题,但可能漏掉了规则的元数据定义。懒人方案是直接补全规则配置,试试这个:

module.exports = {
meta: {
type: "suggestion",
schema: []
},
create(context) {
return {
CallExpression(node) {
if (node.callee.type === 'Identifier' && node.callee.name === 'alert') {
context.report({
node,
message: 'Unexpected use of alert.'
});
}
}
};
}
};


关键是加了 meta 配置,同时确保 node.callee.typeIdentifier 类型。这样就能正常工作了。
点赞 10
2026-01-30 08:04