资讯动态

ESLint sort-keys 规则详解:强制对象属性名按字母序排列的完整配置指南

发布时间:2026/9/12 9:35:07 来源:尧图企业网站定制
ESLint sort-keys 规则详解强制对象属性名按字母序排列的完整配置指南【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本文以 ESLint 仓库中的 sort-keys 官方文档 为核心结合 规则源码 与 单元测试 编写。sort-keys是 ESLint 内置的 suggestion建议类规则用于检查对象字面量中属性定义的顺序要求所有属性名按字母顺序排序。读完本文你将掌握该规则的六大配置项asc/desc、caseSensitive、natural、minKeys、allowLineSeparatedGroups、ignoreComputedKeys的精确语义与典型用法理解计算属性、展开属性Spread等边界情况的处理规则并能根据团队偏好自由定制排序策略。规则简介与设计动机在声明多个对象属性时部分开发者倾向于将属性名按字母顺序排列以便后续更容易查找属性、或进行代码 diff合并冲突时按字母序排列的属性顺序冲突更少、更易定位另一部分开发者则认为这增加了书写复杂度并成为维护负担。sort-keys规则正是为前一种偏好提供的自动化保障——它不再依赖人工自觉而是通过 lint 在构建阶段强制属性顺序同时提供多种配置以适配不同团队的代码风格。该规则在仓库元数据中的定义位于 conf/rule-type-list.jsonsuggestion类型相关规则还包括sort-imports对 import 语句排序与sort-vars对变量声明排序三者共同构成 ESLint 的排序规则族。规则源码 lib/rules/sort-keys.js 中标记recommended: false与frozen: true表示它不会出现在eslint:recommended预设中且属于冻结规则其行为与选项集合保持稳定不随版本随意变动需要使用时须在配置中显式开启。Rule Details规则检查什么本规则检查所有对象表达式Object Expression中的属性定义并验证所有属性名是否按字母顺序排列。它逐对比较相邻属性一旦发现后一个属性名应排在前一个之前就报告一个错误。不正确的代码示例默认配置即升序/*eslint sort-keys: error*/ const obj1 {a: 1, c: 3, b: 2}; const obj2 {a: 1, c: 3, b: 2}; // Case-sensitive by default默认大小写敏感。 const obj3 {a: 1, b: 2, C: 3}; // Non-natural order by default默认非自然序10 按字典序排在 2 之前。 const obj4 {1: a, 2: c, 10: b}; // 本规则同样检查拥有简单名Simple Name的计算属性。 // 简单名指由 Identifier 节点或 Literal 节点表达的名称。 const S Symbol(s) const obj5 {a: 1, [c]: 3, b: 2}; const obj6 {a: 1, [S]: 3, b: 2};正确的代码示例/*eslint sort-keys: error*/ const obj1 {a: 1, b: 2, c: 3}; const obj2 {a: 1, b: 2, c: 3}; // Case-sensitive by default大写字母 C 排在所有小写字母之前。 const obj3 {C: 3, a: 1, b: 2}; // Non-natural order by default1 10 2 为字典序。 const obj4 {1: a, 10: b, 2: c}; // 本规则同样检查拥有简单名的计算属性。 const obj5 {a: 1, [b]: 2, c: 3}; const obj6 {a: 1, [b]: 2, c: 3}; // 本规则忽略拥有非简单名的计算属性。 const obj7 {a: 1, [c d]: 3, b: 2}; const obj8 {a: 1, [c d]: 3, b: 2}; const obj9 {a: 1, [${c}]: 3, b: 2}; const obj10 {a: 1, [tagc]: 3, b: 2}; // 本规则不报告被展开属性Spread分隔开的未排序属性。 const obj11 {b: 1, ...c, a: 2};三类特殊属性节点理解规则的三个忽略/重置边界从上面的示例中可以提炼出三个关键边界它们在 lib/rules/sort-keys.js 中有精确的源码实现非简单名的计算属性直接忽略。源码中getPropertyName(node)先调用astUtils.getStaticPropertyName实现在 lib/rules/utils/ast-utils.js若拿不到静态名则回退取node.key.name两者都拿不到如[c d]、[${c}]、[tagc]则返回null。当thisName null时规则直接return不参与排序比较也不影响前后属性的比较。简单名的计算属性参与排序。[c]、[S]Symbol 变量等可以被静态求值的键名照常参与字母序比较。展开属性Spread重置排序基准。源码中的SpreadElement(node)处理器在父节点是ObjectExpression时将stack.prevName置为null因此{b: 1, ...c, a: 2}中b与a不再被比较。测试文件 tests/lib/rules/sort-keys.js 中大量验证了这一行为例如{a:1, ...z, b:1}、{b:1, ...z, a:1}、{...a, b:1, ...c, d:1}均为合法用例而{...z, a:1, b:1}这类未被展开属性分隔的仍会被检查。Options 配置项详解规则完整配置格式如下{ sort-keys: [error, asc, {caseSensitive: true, natural: false, minKeys: 2}] }第 1 个选项为asc或descasc默认—— 强制属性按升序排列desc—— 强制属性按降序排列。第 2 个选项是一个对象包含以下属性配置项类型默认值含义caseSensitivebooleantrue若为true强制属性按大小写敏感的字典序排列false则忽略大小写统一转为小写后比较minKeysinteger最小值为 22指定对象需要拥有的最小键数键数少于该值的对象即使未排序也不会报错naturalbooleanfalse若为true按自然序排序见下文默认的字母序下数字按字典序排列allowLineSeparatedGroupsbooleanfalse若为true允许通过空行把对象键分成多个组空行会重置排序状态ignoreComputedKeysbooleanfalse若为true忽略所有计算键且计算键会重置其后非计算键的排序以上默认值与 schema 校验定义在 lib/rules/sort-keys.js 的defaultOptions与schema字段中minKeys的minimum: 2保证不会出现低于 2 的无意义配置additionalProperties: false拒绝未知选项。自然序natural到底是什么意思natural自然序是指以人类直觉的方式比较同时包含字母与数字的字符串它基本按数值而非字母表排序。例如对键名1, 3, 6, 8, 10natural: true时的顺序1 → 3 → 6 → 8 → 10数字按数值大小natural: false时默认字典序1 → 10 → 3 → 6 → 810的首字符1小于3故排在前面。源码中该功能由natural-compare库实现lib/rules/sort-keys.js第 13 行的require(natural-compare)比较函数形如naturalCompare(a, b) 0。desc 选项示例不正确的代码[error, desc]/*eslint sort-keys: [error, desc]*/ const obj1 {b: 2, c: 3, a: 1}; const obj2 {b: 2, c: 3, a: 1}; // Case-sensitive by default大小写敏感C 作为最大项应在最前。 const obj3 {C: 1, b: 3, a: 2}; // Non-natural order by default字典序下 10 应排在 2 与 1 之前。 const obj4 {10: b, 2: c, 1: a};正确的代码/*eslint sort-keys: [error, desc]*/ const obj1 {c: 3, b: 2, a: 1}; const obj2 {c: 3, b: 2, a: 1}; // Case-sensitive by default。 const obj3 {b: 3, a: 2, C: 1}; // Non-natural order by default。 const obj4 {2: c, 10: b, 1: a};caseSensitive 选项示例不正确的代码[error, asc, {caseSensitive: false}]/*eslint sort-keys: [error, asc, {caseSensitive: false}]*/ const obj1 {a: 1, c: 3, C: 4, b: 2}; const obj2 {a: 1, C: 3, c: 4, b: 2};正确的代码/*eslint sort-keys: [error, asc, {caseSensitive: false}]*/ const obj1 {a: 1, b: 2, c: 3, C: 4}; const obj2 {a: 1, b: 2, C: 3, c: 4};当caseSensitive: false时源码会选择带Iinsensitive后缀的比较函数例如ascI(a, b)内部执行a.toLowerCase() b.toLowerCase()。注意此时a b c C与a b C c两种排列都合法因为忽略大小写后c与C视为相等谁前谁后规则不干预。natural 选项示例不正确的代码[error, asc, {natural: true}]/*eslint sort-keys: [error, asc, {natural: true}]*/ const obj {1: a, 10: c, 2: b};正确的代码/*eslint sort-keys: [error, asc, {natural: true}]*/ const obj {1: a, 2: b, 10: c};minKeys 选项示例不正确的代码[error, asc, {minKeys: 4}]对象键数达到 4 个或更多才会报错/*eslint sort-keys: [error, asc, {minKeys: 4}]*/ // 4 keys const obj1 { b: 2, a: 1, // not sorted correctly (should be 1st key) c: 3, d: 4, }; // 5 keys const obj2 { 2: a, 1: b, // not sorted correctly (should be 1st key) 3: c, 4: d, 5: e, };正确的代码键数不足 4 时不受检查/*eslint sort-keys: [error, asc, {minKeys: 4}]*/ // 3 keys const obj1 { b: 2, a: 1, c: 3, }; // 2 keys const obj2 { 2: b, 1: a, };minKeys的默认值为2意味着默认情况下所有含未排序键的对象都会产生 lint 错误将其调大可避免对小型对象如两三个键的配置对象强制执行排序减少对既有代码风格的干扰。源码中numKeys minKeys的判断lib/rules/sort-keys.js直接使用了ObjectExpression节点的properties.length作为键数。allowLineSeparatedGroups 选项示例当allowLineSeparatedGroups: true时空行成为分组的边界属性后的空行会重置排序状态空行之后的新组重新开始排序。这对按语义分组组织对象键的写法非常友好。不正确的代码[error, asc, {allowLineSeparatedGroups: true}]/*eslint sort-keys: [error, asc, {allowLineSeparatedGroups: true}]*/ // 同一组内仍有未排序键b、c、a 同组且无空行分隔。 const obj1 { b: 1, c () { }, a: 3 } // 第二组z、y内部未排序。 const obj2 { b: 1, c: 2, z () { }, y: 3 } // 注释不构成分组边界z 与 y 仍在同一组。 const obj3 { b: 1, c: 2, z () { }, // comment y: 3, } // 逗号前的注释同样不能分隔组。 const obj4 { b: 1 // comment before comma , a: 2 };正确的代码/*eslint sort-keys: [error, asc, {allowLineSeparatedGroups: true}]*/ // 空行将键分为 e/f/g 与 a/b/c 两组组内各自有序。 const obj1 { e: 1, f: 2, g: 3, a: 4, b: 5, c: 6 } // 空行后新组从 a 开始重新排序。 const obj2 { b: 1, // comment a: 4, c: 5, } // 方法定义也可以作为组内成员参与排序。 const obj3 { c: 1, d: 2, b () { }, e: 3, } // 空行前后的连续注释均不构成组内分隔b 组仍有序。 const obj4 { c: 1, d: 2, // comment // comment b() { }, e: 4 } // 非简单名的计算属性不会破坏分组逻辑。 const obj5 { b, [foo bar]: 1, a } // 空行出现在逗号之前同样构成分组边界。 const obj6 { b: 1 // comment before comma , a: 2 }; // 空行分隔的两个组各自有序组内展开属性后的排序照常处理。 const obj7 { b: 1, a: 2, ...z, c: 3 }该选项的实现细节在源码中相当考究规则通过sourceCode.getTokensBetween(prevNode, node, { includeComments: true })取出相邻属性之间的全部 Token含注释再逐一比较相邻 Token 的行号差只要存在行号差大于 1即存在空行的情况就判定为空行分隔。三处检查分别覆盖Token 之间、当前节点与最后一个 Token 之间、第一个 Token 与上一个节点之间见 lib/rules/sort-keys.js 的Property处理器因此即使空行出现在注释与逗号之间这种特殊位置也能被识别。测试文件中也覆盖了b: 1后换行、注释后再接,a: 2等组合场景。ignoreComputedKeys 选项示例当ignoreComputedKeys: true时规则忽略所有计算键并且不会报告被计算键分隔开的未排序属性——计算键同样起到重置排序的作用。正确的代码[error, asc, {ignoreComputedKeys: true}]/*eslint sort-keys: [error, asc, {ignoreComputedKeys: true}]*/ // 计算键位于对象开头重置后 a 开始新组。 const obj1 { [b]: 1, a: 2 } // 计算键 [b] 分隔开 c 与 a二者不再比较。 const obj2 { c: 1, [b]: 2, a: 3 } // 字符串字面量计算键同样被忽略。 const obj3 { c: 1, [b]: 2, a: 3 }源码中对应逻辑为if (ignoreComputedKeys node.computed) { stack.prevName null; return; }即遇到计算键先重置排序基准并跳过比较。注意它与默认行为默认会检查简单名计算键的差异默认配置下{c: 1, [b]: 2, a: 3}会因为c b a的乱序而报错开启本选项后才被放行。底层实现原理八个比较函数与状态栈理解 lib/rules/sort-keys.js 的实现能帮你更精确地预判规则的每一个判断。核心有三块比较函数矩阵源码维护了一个isValidOrders对象由升/降序 × 大小写敏感 × 自然序组合出 8 个比较函数——asc、ascI、ascN、ascIN、desc、descI、descN、descINI后缀表示不区分大小写N后缀表示自然序。运行时通过order (insensitive ? I : ) (natural ? N : )拼接出函数名并调用因此所有配置组合的行为都是确定的、可预期的。状态栈stack规则在进入ObjectExpression时压入一个栈帧记录prevName上一个有效属性名、prevNode上一个属性节点、prevBlankLine是否空行分隔、numKeys属性总数退出对象时弹出。嵌套对象互不干扰每个对象字面量都有独立的排序上下文。报告消息当相邻键违反顺序时规则在node.key.loc位置报告消息Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. {{thisName}} should be before {{prevName}}.消息中会动态带上natural、insensitive、ascending/descending等修饰词方便开发者一眼看出违反了哪条排序策略。在真实项目中如何配置由于该规则不在eslint:recommended预设中需要在 ESLint 配置flat config 或 eslintrc中显式开启。例如在 flat config 中// eslint.config.js export default [ { rules: { sort-keys: [error, asc, { caseSensitive: true, natural: false, minKeys: 2, allowLineSeparatedGroups: false, ignoreComputedKeys: false }] } } ];实践建议希望按语义分组组织大型对象如国际化文案、表单配置可开启allowLineSeparatedGroups: true与minKeys: 4既保持分组可读性又避免对小型对象过度约束项目中存在大量数字后缀键名如item1、item10推荐natural: true否则字典序会把item10排在item2之前产生大量误报计算属性较多且无法静态求值如[keyName]动态键可开启ignoreComputedKeys: true避免误报只想约束团队书写习惯、不阻塞 CI可将error降级为warn。When Not To Use It何时不该使用如果你不想让规则提醒属性的排列顺序可以放心地关闭此规则{ rules: { sort-keys: off } }例如团队已经约定按业务重要程度或写入顺序组织对象键排序反而会制造噪音此时关闭sort-keys不会影响任何其他功能。Compatibility兼容性该规则的设计理念与JSCS的validateOrderInObjectKeys规则一脉相承JSCS 是 ESLint 的前身生态之一其排序语义与选项粒度在此基础上做了扩展如natural、minKeys、allowLineSeparatedGroups、ignoreComputedKeys均为后续新增能力。在从 JSCS 迁移到 ESLint 的工程中sort-keys可以作为validateOrderInObjectKeys的替代方案建议对照上述选项语义逐一映射再通过本仓库的 测试用例共 2556 行、覆盖默认行为到全部选项的合法/非法场景验证迁移后的行为是否符合预期。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价