
eslint-plugin-unicorn 的 no-keyword-prefix 规则详解禁止以new、class等关键字为前缀命名标识符【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn导读no-keyword-prefix是 eslint-plugin-unicorn 中用于提升代码可读性的一条命名风格规则其核心职责是禁止开发者为变量、函数、属性等标识符使用new、class这类 JS 关键字作为前缀。本文以 docs/rules/no-keyword-prefix.md 为骨架结合规则源码 rules/no-keyword-prefix.js、完整测试用例 test/no-keyword-prefix.js 与规则注册表 rules/index.js系统讲解该规则的设计动机、三个配置项disallowedPrefixes、checkProperties、onlyCamelCase的用法与底层判定逻辑并给出可直接复制的 ESLint 配置示例。读完本文你将能在项目中精准启用并按需定制这条规则。规则动机new Foo与newFoo的视觉歧义在 JavaScript 中new Foo是实例化构造函数的语法而newFoo只是一个普通标识符。两者在视觉上几乎一模一样极易在快速阅读代码时产生误导——读者可能会把newFoo误认为是在使用new关键字创建对象。这条规则正是为此而生禁止以关键字为前缀的标识符命名迫使开发者选择不会与关键字用法混淆的替代命名。文档开头的示例展示了典型场景// ❌ 与 new Foo 语法高度相似 const newFoo foo; // ❌ 以 class 关键字为前缀 const classFoo foo; // ✅ const foo foo; // ✅ 下划线隔断前缀无歧义 const _newFoo foo; // ✅ 下划线结尾 const new_foo foo; // ✅ 关键字放在末尾 const fooNew foo;规则性质与默认状态从规则元数据rules/no-keyword-prefix.js可以看到meta.type为suggestion属于代码风格建议类规则不涉及运行时错误默认recommended: false因此在 eslint-plugin-unicorn 的recommended、unopinionated两个预设配置中该规则处于禁用状态见 readme.md 规则总表中该行无推荐标记需要开发者显式开启规则仅支持js/js语言不作用于 CSS、JSON 等其他语言文件该规则没有自动修复fixable能力因为重命名标识符可能跨越作用域引用属于需要人工决策的重构只能通过context.report报告错误。规则的报错信息为固定模板Do not prefix identifiers with keyword \{{keyword}}.其中{{keyword}}会被替换为实际命中的关键字源码第 3-6 行的messages 定义。Options三个配置项详解规则通过prepareOptions源码第 8-19 行解析配置支持三个选项均可在.eslintrc或 flat config 中配置。JSON Schema 定义在源码第 187-209 行明确要求additionalProperties: false即不认识的配置键会被直接拒绝。disallowedPrefixes自定义禁用前缀列表默认值为[new, class]。如果你希望按团队规范扩展或替换禁用前缀可以传入自定义数组/* eslint unicorn/no-keyword-prefix: [error, {disallowedPrefixes: [new, for]}] */ // ✅ 不再检查 class 前缀 const classFoo a; // ❌ for 被加入禁用列表 const forFoo a;Schema 中的约束包括items必须是字符串、minItems: 0允许空数组表示不检查任何前缀、uniqueItems: true前缀不能重复。测试用例也验证了自定义列表的生效方式disallowedPrefixes: [old]时const oldFoo foo会被报错而默认列表下的const newFoo foo反而不报错test/no-keyword-prefix.js 与 L261-L265。checkProperties是否检查对象属性名默认值为true即对象属性名如foo.newFoo、{newFoo: 1}也会被检查。设置为false后属性名将豁免/* eslint unicorn/no-keyword-prefix: [error, {checkProperties: true}] */ // ❌ foo.newFoo 2; // ✅ foo.foo 2;/* eslint unicorn/no-keyword-prefix: [error, {checkProperties: false}] */ // ✅ var foo {newFoo: 1}; // pass // ✅ foo.newFoo 2; // pass对应测试test/no-keyword-prefix.js覆盖了对象字面量、成员赋值、_newBar前缀等边界场景。onlyCamelCase是否仅检查驼峰命名默认值为true规则只拦截“关键字紧跟大写字母”的驼峰形态从而放过new_foo这类以下划线隔断的命名。设为false后只要标识符以关键字开头就会被拦截/* eslint unicorn/no-keyword-prefix: [error, {onlyCamelCase: true}] */ // ✅ const new_foo foo;/* eslint unicorn/no-keyword-prefix: [error, {onlyCamelCase: false}] */ // ❌ const new_foo foo; // ✅ const foo foo;参数一览表配置项类型默认值作用disallowedPrefixesstring[][new, class]自定义禁用前缀列表空数组表示不限制checkPropertiesbooleantrue是否同时检查对象属性名与成员表达式onlyCamelCasebooleantrue为true时仅检查前缀后紧跟大写字母的驼峰命名源码剖析前缀匹配与多种 AST 场景前缀匹配核心findKeywordPrefix规则的核心判定函数findKeywordPrefix源码第 21-42 行逻辑非常直接遍历options.disallowedPrefixes用String#startsWith判断标识符是否以某个关键字开头若name恰好等于关键字本身如变量就叫new由于nextCharacter为空会被跳过——这正是测试中const foo {new: 1};合法的原因在onlyCamelCase为true时要求紧跟关键字后的字符必须是A–Z之间的大写字母源码第 35-37 行的字符区间比较这解释了为什么newfoo全小写、new_foo、NEW_FOO均不会被拦截。Identifier监听器与场景分流规则在context.on(Identifier, ...)源码第 130-184 行中统一处理所有标识符节点按parent节点类型分流为四类场景并配有一个去重机制成员表达式MemberExpression交由reportMemberExpression源码第 44-73 行处理。仅在checkProperties: true时生效特殊规则是当属性名与对象名相同如foo.foo.newFoo中的链式结构或处于赋值表达式的左侧目标位置时报告从而避免对bar.newBar这类只读取值产生重复告警对象属性Property与默认参数AssignmentPattern若嵌套在ObjectPattern解构中走reportObjectPatternAndShouldSkipPropertyCheck源码第 75-103 行针对简写属性、计算属性[newFoo]、解构重命名{ newFoo: bar }、解构默认值{ newFoo 1 }分别处理并跳过“右侧已被检查过”的解构取值防止重复报错普通属性场景则在checkProperties开启时报告导入说明符ImportSpecifier/ImportNamespaceSpecifier/ImportDefaultSpecifier只在本地导入名parent.local?.name违规时才报告。因此import { newFoo as foo }合法而import { foo as newFoo }、import * as newFoo、import newFoo都会报错其余一切标识符变量声明、函数名、参数等直接报告但CallExpression与NewExpression中的标识符被ALLOWED_PARENT_TYPES白名单豁免——这是为了放行new newFoo这种“用关键字命名的构造函数调用”及new.target等合法语法。代码注释明确说明源码第 105-106 行核心逻辑参考自 ESLint 内置的camelcase规则测试用例也大量沿用了 camelcase 的测试集test/no-keyword-prefix.js理解这一点有助于你在两个规则之间迁移经验。去重与简写解构源码第 110-128 行维护了一个reported数组同一节点只报告一次避免简写解构如const { newFoo } foo因“既是属性键又是新变量”的双重身份被报两遍。测试中const newFoo 0; function foo({ newBar newFoo}) {}精确产生两条错误对应newFoo与newBar两个不同标识符验证了去重逻辑的准确性。辅助工具解构场景还借助了共享工具 rules/utils/is-shorthand-property-assignment-pattern-left.js 来判断标识符是否为简写属性赋值模式{ newFoo 1 }的左侧节点该工具基于 rules/utils/is-shorthand-property-value.js 判断简写属性值从而精确识别“默认值参数左侧的简写解构”。测试覆盖规则行为全景验证test/no-keyword-prefix.js 通过getTester(import.meta)框架对规则进行全量验证valid段与invalid段合计覆盖数十个场景其中值得注意的边界包括合法场景new newFoo、new newFoo()构造调用、foo.newFoo()方法调用此时属性名是方法而非赋值目标、new.target在函数与类构造函数中的使用、const { newFoo: foo } bar解构重命名到安全名称、const { _newFoo } bar下划线前缀豁免非法场景var/let/const三种声明、函数声明function newFoo(){}、属性赋值foo.newFoo function(){}、嵌套成员foo.foo.newFoo、计算属性解构var { [newFoo]: bar } foo、带默认值的解构var { newFoo 1 } foo、各类 import 形式等。这些测试同时印证了文档中的全部示例可作为理解规则精确行为的第一手参考资料。如何在项目中启用由于该规则未包含在recommended预设中需要显式配置。在 flat config 中import eslintPluginUnicorn from eslint-plugin-unicorn; export default [ { plugins: {unicorn: eslintPluginUnicorn}, rules: { unicorn/no-keyword-prefix: [error, { disallowedPrefixes: [new, class, for], checkProperties: true, onlyCamelCase: true, }], }, }, ];在传统.eslintrc中{ plugins: [unicorn], rules: { unicorn/no-keyword-prefix: [error, { disallowedPrefixes: [new, class], checkProperties: true, onlyCamelCase: true }] } }如果只想启用默认行为直接配置unicorn/no-keyword-prefix: error即可源码中defaultOptions: [{}]保证空配置会落入disallowedPrefixes: [new, class]、checkProperties: true、onlyCamelCase: true的默认值。小结no-keyword-prefix通过约束标识符命名规避new Foo与newFoo之间的视觉歧义是一项低成本高收益的代码风格规则。其三个配置项disallowedPrefixes、checkProperties、onlyCamelCase分别覆盖“前缀集合”“属性是否纳入检查”“命名形态的检查粒度”配合对解构、导入、成员表达式等 AST 场景的精细分流可以在不产生重复告警的前提下有效净化命名。该规则默认关闭、不可自动修复适合作为团队编码规范的一部分按需开启与 ESLint 内置camelcase规则的思路同源两者搭配使用可建立更一致的命名约束体系。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考