如何创建ESLint自定义规则以禁止JSX语法中的特定HTML元素
如何创建ESLint自定义规则来禁用JSX中的原生HTML元素?
嘿,这个需求很常见——强制团队统一使用UI库组件而非原生HTML元素,避免样式和行为不一致。我之前帮团队搭建过类似的ESLint规则,下面给你一步步拆解实现方法:
1. 明确规则核心逻辑
我们需要检测JSX中的原生HTML元素(小写开头,比如<input>、<button>),同时允许UI库的组件(大写开头,比如<Button>、<Input>)。React的约定正好帮我们简化判断:组件名大写开头,原生HTML标签小写开头。
2. 创建自定义规则文件
假设你在现有项目中添加规则,先在项目根目录创建eslint-rules文件夹,再新建no-native-jsx-elements.js文件,这就是规则的核心代码:
module.exports = { meta: { type: "problem", // 规则类型:触发时抛出错误 docs: { description: "禁止使用原生JSX HTML元素,必须使用UI库组件", recommended: true, }, messages: { forbiddenNativeElement: "禁止使用原生{{element}}元素,请使用UI库的<{{Component}} />组件替代", }, schema: [ { type: "object", properties: { forbiddenElements: { type: "array", items: { type: "string" }, description: "需要禁用的原生HTML元素列表", }, }, }, ], }, create(context) { // 从配置获取禁用元素列表,默认禁用button和input const forbiddenElements = context.options[0]?.forbiddenElements || ["button", "input"]; // 生成对应UI组件的大写名称 const getComponentName = (element) => element.charAt(0).toUpperCase() + element.slice(1); return { // 监听JSX打开标签节点 JSXOpeningElement(node) { // 原生HTML元素的name是JSXIdentifier类型,且名称为小写 if (node.name.type === "JSXIdentifier") { const elementName = node.name.name; if (forbiddenElements.includes(elementName)) { context.report({ node, messageId: "forbiddenNativeElement", data: { element: elementName, Component: getComponentName(elementName), }, }); } } }, }; }, };
3. 在ESLint配置中引入规则
修改项目根目录的.eslintrc.js(或对应格式的配置文件),让ESLint识别这个自定义规则:
module.exports = { // ...其他配置项 rules: { // 启用自定义规则,设为error级别(触发时抛出错误) "./eslint-rules/no-native-jsx-elements": "error", }, // 部分ESLint版本需要指定规则目录,添加此行 rulesDirectory: ["./eslint-rules"], };
4. 测试规则效果
写一段示例代码验证规则是否生效:
// ❌ 会触发ESLint错误 function BadComponent() { return ( <div> <button>点击我</button> <input type="text" /> </div> ); } // ✅ 不会触发错误 function GoodComponent() { return ( <div> <Button>点击我</Button> <Input type="text" /> </div> ); }
触发错误时,ESLint会提示:禁止使用原生button元素,请使用UI库的<Button />组件替代,完全匹配你的需求。
5. 扩展优化(可选)
如果需要禁用更多原生元素,只需在ESLint配置中传递自定义列表即可:
module.exports = { rules: { "./eslint-rules/no-native-jsx-elements": ["error", { forbiddenElements: ["button", "input", "a", "textarea"] // 自定义禁用元素列表 }], }, };
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

