ESLint camelcase 规则详解:强制标识符驼峰命名法(命名风格检查与配置实战)

发布时间:2026/9/11 15:53:26
ESLint camelcase 规则详解:强制标识符驼峰命名法(命名风格检查与配置实战) ESLint camelcase 规则详解强制标识符驼峰命名法命名风格检查与配置实战【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本篇技术指南围绕 ESLint 内置规则camelcase展开系统讲解其如何在 JavaScript 代码中强制变量、函数、属性、解构与导入等标识符采用驼峰命名camelCase。文中将完整覆盖该规则的检测逻辑、全部 6 个配置项及其默认值、正反例代码、与properties/ignoreDestructuring/ignoreImports/ignoreGlobals/allow组合的典型实战场景并结合仓库源码 lib/rules/camelcase.js 与测试用例 tests/lib/rules/camelcase.js 剖析其底层实现原理帮助读者在团队项目中精准启用、调优或豁免该命名检查。规则概览为什么需要 camelcase在命名变量时风格指南通常分为两大阵营驼峰命名variableName与下划线命名variable_name。ESLint 的camelcase规则rule type 为suggestion见 docs/src/rules/camelcase.md 文件头的 front matter专注于强制使用驼峰命名。如果你的团队风格指南要求变量名采用驼峰形式那么这条规则就是为你准备的。在仓库的规则注册表 lib/rules/index.js 中可以看到camelcase通过懒加载方式注册camelcase: () require(./camelcase)。同时它并非eslint:recommended预设的一部分——测试 tests/conf/eslint-recommended.js 明确断言assert.notProperty(rules, camelcase)这意味着它需要你在配置中显式开启。Rule Details核心检测逻辑该规则的检测逻辑可以概括为查找源代码中任何出现在标识符中间位置的下划线_。具体规则如下忽略首尾下划线只检查变量名中间部分的下划线因此_myFavoriteColor、myFavoriteColor_均视为合法。常量豁免如果 ESLint 判定该变量是常量全大写如MY_FAVORITE_COLOR则不会发出警告。只标记定义与赋值规则只针对定义declaration和赋值assignment进行检查不检查函数调用。因此do_something()这种调用不会报错。import 语句的特殊处理对于 ES6import语句规则只检查导入到本地模块作用域的变量名local name不检查被导出的原始名称。从源码实现看这一逻辑对应 lib/rules/camelcase.js 中的isUnderscored函数function isUnderscored(name) { const nameBody name.replace(/^_|_$/gu, ); // if theres an underscore, it might be A_CONSTANT, which is okay return ( nameBody.includes(_) nameBody ! nameBody.toUpperCase() ); }该函数先用正则/^_|_$/gu去掉首尾下划线然后判断剩余部分是否包含下划线且不是全大写——二者同时成立才判定为下划线命名这正好对应文档中忽略首尾下划线、全大写常量豁免的两条规则。当规则判定违规时会通过context.report输出消息。源码 lib/rules/camelcase.js 中定义了两条消息notCamelCaseIdentifier {{name}} is not in camel case.notCamelCasePrivate#{{name}} is not in camel case.用于类私有字段/方法此外实现中通过reported集合lib/rules/camelcase.js记录已报告的节点起始位置避免在简写形式shorthand的解构语法下对同一标识符重复报告。Options完整配置项说明camelcase规则接受一个对象配置项所有子项均有默认值。下表汇总了全部配置项配置项取值默认值作用propertiesalways/neveralwaysalways强制对象/类属性名也遵循驼峰never不检查属性名ignoreDestructuringtrue/falsefalsetrue时不检查解构标识符但之后对这些标识符的使用仍会被检查ignoreImportstrue/falsefalsetrue时不检查 ES2015 import 导入名但之后对这些导入的使用仍会被检查函数参数除外ignoreGlobalstrue/falsefalsetrue时不对全局变量强制驼峰命名allowstring[][]允许命名的属性列表支持正则字符串这些默认值在源码 lib/rules/camelcase.js 的defaultOptions中均有体现且其 JSON Schemalib/rules/camelcase.js约束了每个选项的类型ignoreDestructuring、ignoreImports、ignoreGlobals为布尔值properties限定为enum: [always, never]allow为字符串数组minItems: 0、uniqueItems: true即允许空数组且元素不可重复并且additionalProperties: false禁止传入未知选项。properties: always默认默认情况下属性名也必须符合驼峰命名。以下代码会被判为错误配置为/*eslint camelcase: error*/import { no_camelcased } from external-module const my_favorite_color #112C85; function do_something() { // ... } obj.do_something function() { // ... }; function foo({ no_camelcased }) { // ... }; function bar({ isCamelcased: no_camelcased }) { // ... } function baz({ no_camelcased default value }) { // ... }; const obj { my_pref: 1 }; const { category_id 1 } query; const { foo: snake_cased } bar; const { foo: bar_baz 1 } quz;而以下代码在默认配置下是正确的/*eslint camelcase: error*/ import { no_camelcased as camelCased } from external-module; const myFavoriteColor #112C85; const _myFavoriteColor #112C85; const myFavoriteColor_ #112C85; const MY_FAVORITE_COLOR #112C85; const foo1 bar.baz_boom; const foo2 { qux: bar.baz_boom }; obj.do_something(); do_something(); new do_something(); const { category_id: category } query; function foo({ isCamelCased }) { // ... }; function bar({ isCamelCased: isAlsoCamelCased }) { // ... } function baz({ isCamelCased default value }) { // ... }; const { categoryId 1 } query; const { foo: isCamelCased } bar; const { foo: camelCasedName 1 } quz;注意这些正确示例蕴含了几个关键细节const { category_id: category } query;合法因为只有新绑定的本地变量名category会被检查属性来源名category_id不检查bar.baz_boom作为只读引用不报错规则不检查函数调用和只读属性读取解构中若把no_camelcased重命名为camelCasedas语法本地名符合驼峰即通过。这一点与源码中的检测范围一致源码在ObjectExpression Property[computed!true] Identifier.key等节点上检查属性名lib/rules/camelcase.js而MemberExpression[computed!true] Identifier.property的检查要求该成员表达式必须是赋值目标isAssignmentTarget见 lib/rules/camelcase.js注释明确写着ignore read-only references这正是obj.do_something()只读调用不报错的原因。properties: never当你的代码需要与外部系统如后端 API、数据库字段交互而必须保留下划线属性时可以关闭属性名检查。以下代码在{ properties: never }下是正确的/*eslint camelcase: [error, {properties: never}]*/ const obj { my_pref: 1 }; obj.foo_bar baz;测试 tests/lib/rules/camelcase.js 中还覆盖了obj.a_b 2、obj._a 2、obj.a_ 2等赋值场景均作为properties: never下的合法用例同时 tests/lib/rules/camelcase.js 也验证了类字段public/private在两种配置下的行为class C { snake_case; #snake_case; #snake_case2() {} }在properties: never下合法而在properties: always下会报错含私有名使用专门的notCamelCasePrivate消息。ignoreDestructuring: false默认默认配置下解构出来的标识符必须符合驼峰。以下代码都是错误的/*eslint camelcase: error*/ const { category_id } query; const { category_name 1 } query; const { category_id: category_title } query; const { category_id: category_alias } query; const { category_id: categoryId, ...other_props } query;注意最后一行解构出的categoryId虽然合法但 rest 属性other_props仍会被检查并报错。ignoreDestructuring: true开启后只有解构模式内的标识符被豁免但后续对这些变量的使用仍按默认或其它选项规则检查。该选项的常见用途是当解构出的标识符后续根本不会被使用或仅作为属性简写传给他人时避免无谓的重命名。错误示例解构模式内使用了非驼峰别名或 rest 属性/*eslint camelcase: [error, {ignoreDestructuring: true}]*/ const { category_id: category_alias } query; const { category_id, ...other_props } query;正确示例/*eslint camelcase: [error, {ignoreDestructuring: true}]*/ const { category_id } query; const { category_name 1 } query; const { category_id_name: category_id_name } query;请注意该选项仅适用于解构模式内部的标识符它并不会额外允许这些变量在后续代码中的任何特定使用。例如下面的代码会报错/*eslint camelcase: [error, {ignoreDestructuring: true}]*/ const { some_property } obj; // allowed by {ignoreDestructuring: true} const foo some_property 1; // error, ignoreDestructuring does not apply to this statement一个典型应用场景是标识符后续不会使用解构只是为了取出或透传该属性/*eslint camelcase: [error, {ignoreDestructuring: true}]*/ const { some_property, ...rest } obj; // do something with rest, nothing with some_property另一个常见组合是配合{ properties: never }当标识符只打算作为属性简写shorthand使用时/*eslint camelcase: [error, {properties: never, ignoreDestructuring: true}]*/ const { some_property } obj; doSomething({ some_property });该组合行为在测试 tests/lib/rules/camelcase.js 中有专门覆盖其中引用了 eslint/eslint#15572 这一 issue 对应的场景。从源码看ignoreDestructuring依赖equalsToOriginalName函数lib/rules/camelcase.js判断当解构标识符原样使用属性名parent.key.name localName、非计算属性、value 位置对应时即豁免。同时reportReferenceIdlib/rules/camelcase.js中ignoreDestructuring只跳过这类原样使用原属性名的标识符因此后续对some_property的其它使用如some_property 1仍会报错——这与文档表述完全一致。另外 lib/rules/camelcase.js 还体现了另一个向后兼容细节解构/参数的默认值AssignmentPattern的right侧中的引用被忽略。ignoreImports: false默认默认情况下import 的本地绑定名必须符合驼峰。以下代码错误/*eslint camelcase: error*/ import { snake_cased } from mod;测试 tests/lib/rules/camelcase.js 中覆盖了大量 import 变体默认导入、命名空间导入import * as no_camelcased、混合导入、字符串形式的导出名import { snake_cased as snake_cased }等全部要求本地名符合驼峰。ignoreImports: true开启后import 的本地绑定名不再被检查但之后对这些导入标识符的使用仍会被检查函数参数除外。错误示例默认导入与命名空间导入的本地名/*eslint camelcase: [error, {ignoreImports: true}]*/ import default_import from mod; import * as namespaced_import from mod;正确示例/*eslint camelcase: [error, {ignoreImports: true}]*/ import { snake_cased } from mod;一个实用场景是当第三方模块只导出下划线命名的成员而你不想逐个as重命名时ignoreImports: true允许导入语句直接照搬原名。测试 tests/lib/rules/camelcase.js 验证了import { snake_cased } from mod、import { snake_cased as snake_cased }、import { snake_cased as snake_cased }在ignoreImports: true下均合法而 tests/lib/rules/camelcase.js 则说明默认导入import snake_cased from mod与命名空间导入import * as snake_cased即使开启ignoreImports: true仍会报错因为equalsToOriginalName只对ImportSpecifier生效默认导入与命名空间导入不在此列。ignoreGlobals: false默认默认情况下全局变量引用也会被检查。以下代码错误/*eslint camelcase: [error, {ignoreGlobals: false}]*/ /* global no_camelcased */ const foo no_camelcased;测试 tests/lib/rules/camelcase.js 表明通过languageOptions.globals或/* global */指令声明的全局变量只要其名字含下划线且非全大写在ignoreGlobals: false或未配置时都会被报告。ignoreGlobals: true开启后不再对全局变量强制驼峰。以下代码正确/*eslint camelcase: [error, {ignoreGlobals: true}]*/ /* global no_camelcased */ const foo no_camelcased;测试 tests/lib/rules/camelcase.js 中有大量组合验证如var camelCased a_global_variable、a_global_variable.foo()、({ a_global_variable } foo)等在ignoreGlobals: true下均合法。注意ignoreGlobals只管全局变量的引用——如果同一个名字又在本地被声明如var a_global_variable声明与本地引用仍会被报告见 tests/lib/rules/camelcase.js 中ignoreGlobals: true下的错误用例。从源码看该逻辑对应Program处理器lib/rules/camelcase.js!ignoreGlobals时遍历scope.variables配置或指令声明的全局并通过scope.through未定义的全局引用始终进行检查。allowallow接受一个字符串数组列出可被豁免的命名支持正则字符串以/^...$/u语义匹配。典型的应用是 React 生命周期方法如UNSAFE_componentWillMount这类带下划线的历史遗留命名。正确示例——精确字符串匹配/*eslint camelcase: [error, {allow: [UNSAFE_componentWillMount]}]*/ function UNSAFE_componentWillMount() { // ... }正确示例——正则模式匹配/*eslint camelcase: [error, {allow: [^UNSAFE_]}]*/ function UNSAFE_componentWillMount() { // ... } function UNSAFE_componentWillReceiveProps() { // ... }从源码 lib/rules/camelcase.js 看isAllowed对allow中的每一项依次尝试两种匹配先做严格相等比较再做正则匹配name.match(new RegExp(entry, u))。这意味着你可以混用字面量UNSAFE_componentWillMount与正则模式^UNSAFE_、_id$。测试中也展示了allow: [_id$]匹配user_id、allow: [__option_foo__]等场景tests/lib/rules/camelcase.js而allow: [ignored_bar]对not_ignored_foo不生效tests/lib/rules/camelcase.js。实现细节与行为边界源码视角深入源码 lib/rules/camelcase.js 可以梳理出该规则的完整检查面这对理解什么会被检查、什么不会被检查很有帮助会被检查的语法面声明VariableDeclaration、FunctionDeclaration、FunctionExpression、ArrowFunctionExpression、ClassDeclaration、ClassExpression、CatchClause声明的变量lib/rules/camelcase.js声明及其后续引用都会被报告对象/类属性名ObjectExpression、MethodDefinition、PropertyDefinition的非计算属性名以及类的私有标识符PrivateIdentifier使用notCamelCasePrivate消息受properties控制成员表达式赋值目标obj.foo_bar ...这种对非驼峰属性赋值的写法受properties控制只读引用obj.foo_bar不检查import 与 re-exportImportDeclaration的本地绑定名受ignoreImports控制以及ExportAllDeclaration、ExportSpecifier的导出名lib/rules/camelcase.js标签LabeledStatement、BreakStatement、ContinueStatement中的 label 名lib/rules/camelcase.js。被豁免的情况首尾下划线_foo、foo_、全大写常量FOO_BAR函数调用中的标识符do_something()、new do_something()——源码 lib/rules/camelcase.js 注释说明这是为向后兼容保留的行为解构/参数的默认值AssignmentPattern右侧中的引用解构中原样使用属性名的标识符配合ignoreDestructuringimport 属性键Import attribute keys如import foo from foo.json with { my_type: json }中的my_type——源码通过astUtils.isImportAttributeKey判断并始终忽略lib/rules/camelcase.js测试见 tests/lib/rules/camelcase.js计算属性computed中的名称不受properties的驼峰检查相关选择器均带[computed!true]限定allow列表中命中的名称精确匹配或正则匹配。配置示例与使用建议在 flat config 中启用// eslint.config.js export default [ { rules: { camelcase: error, }, }, ];在 eslintrc 配置中启用{ rules: { camelcase: error } }推荐组合示例——适配第三方下划线数据源{ rules: { camelcase: [error, { properties: never, // 属性名可保留下划线对接 API 字段 ignoreDestructuring: true, // 解构出的原始字段名不强制重命名 ignoreImports: true, // 第三方模块的下划线导出直接使用 ignoreGlobals: true, // 不约束外部注入的全局变量 allow: [UNSAFE_, _id$] // 额外豁免指定命名模式 }] } }在单行/文件内豁免个别非驼峰命名const snake_case_value 1; // eslint-disable-line camelcaseWhen Not To Use It何时关闭该规则如果团队已经建立了采用下划线分隔单词的命名规范例如数据序列化字段、与后端数据库列名对齐的场景那么应当关闭此规则。这正是官方文档When Not To Use It一节给出的明确指引也与该规则未纳入eslint:recommended见 tests/conf/eslint-recommended.js、需要显式启用的定位一致。在决定关闭之前建议先评估能否用properties: never、ignoreDestructuring、allow等细粒度选项只豁免必要的场景从而在保留变量/函数驼峰约束的同时兼容下划线数据源。总结camelcase是 ESLint 中覆盖面较广的命名风格规则它同时约束声明、赋值、对象/类属性、解构、导入导出与全局引用。通过properties、ignoreDestructuring、ignoreImports、ignoreGlobals、allow五个子项的组合团队可以在强制驼峰的大前提下为第三方模块、后端字段、历史遗留命名等场景保留合理的豁免通道。如需深入验证规则行为可直接查阅规则实现 lib/rules/camelcase.js 及其 1600 余行的测试套件 tests/lib/rules/camelcase.js。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询