ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

掌握 ESLint quote-props:对象字面量属性引号风格的完整配置指南

掌握 ESLint quote-props:对象字面量属性引号风格的完整配置指南 掌握 ESLint quote-props对象字面量属性引号风格的完整配置指南【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint对象字面量属性名既可以用裸标识符书写也可以加引号书写两种写法在大多数场景下完全等价却容易在团队协作中引发风格混乱。ESLint 的quote-props规则正是为此而生——它强制对象字面量属性名的引号使用风格并提供always、as-needed、consistent、consistent-as-needed四种模式及keywords、unnecessary、numbers三个细粒度开关甚至能自动修复违规代码。本文将以 quote-props.md 文档为主体结合仓库内规则实现与测试用例为你完整讲解该规则的选项语义、底层判定逻辑、边界情况处理与迁移方案。为什么需要给对象属性名加引号对象字面量的属性名有两种定义方式使用字面量裸标识符或使用字符串。例如下面两个对象完全等价var object1 { property: true }; var object2 { property: true };大多数情况下选择标识符还是字符串并无实质差别但为了保持代码风格统一团队往往会约定一种固定写法。此外存在两种必须加引号的场景ES3 遗留环境如果目标运行环境是 ECMAScript 3 引擎如 IE8使用if这类关键字作为属性名时必须加引号。该限制在 ECMAScript 5 中被移除。非标识符字符属性名包含非标识符字符时无法用裸标识符书写例如含空格的one two。还有一种引号切实影响正确性的场景——数字字面量作为属性键var object { 1e2: 1, 100: 2 };这段代码表面上看起来没问题但在 ECMAScript 5 严格模式下会抛出语法错误。原因在于1e2和100会先被强制转换为字符串再作为属性名使用而String(1e2)与String(100)恰好都等于100从而触发 Duplicate data property in object literal not allowed in strict mode 错误。这类问题极难排查因此部分团队选择要求所有属性名一律加引号。规则概览与开启方式quote-props规则要求或禁止对象字面量属性名使用引号规则类型为suggestion且声明为可自动修复fixable: code详见 lib/rules/quote-props.js。它不在eslint:recommended中recommended: false需要显式开启// eslint.config.js扁平配置 export default [ { rules: { quote-props: [error, always] } } ];或者在内联注释中配置/*eslint quote-props: [error, always]*/Options 详解该规则接受两类配置一个字符串选项和一个对象选项。规则的模式校验schema定义在 lib/rules/quote-props.js字符串选项必须是四种模式之一对象选项只能包含keywords、unnecessary、numbers三个布尔属性不允许额外属性additionalProperties: false。字符串选项选项行为always默认要求所有对象字面量属性名都加引号as-needed禁止给非必需属性名加引号能不加就不加consistent强制同一对象内引号风格一致要么全部加引号要么全部不加consistent-as-needed若对象中任一属性名严格需要引号则全部加引号否则全部不加对象选项选项行为适用模式keywords: true要求对象属性名中的语言关键字必须加引号as-needed、consistent-as-neededunnecessary: true默认禁止给非必需属性名加引号as-neededunnecessary: false允许给非必需属性名加引号as-needednumbers: true要求用作属性名的数字必须加引号as-needed从源码可以看出默认值逻辑为CHECK_UNNECESSARY !context.options[1] || context.options[1].unnecessary ! false即只要未显式传unnecessary: false就会检查冗余引号lib/rules/quote-props.js。四种模式的行为差异与示例always默认错误示例/*eslint quote-props: [error, always]*/ var object { foo: bar, baz: 42 };正确示例/*eslint quote-props: [error, always]*/ var object1 { foo: bar, baz: 42, qux-lorem: true }; var object2 { foo: bar, baz: 42, qux-lorem: true }; var object3 { foo() { return; } };注意object3方法定义method不需要加引号。源码中checkOmittedQuotes会跳过node.method、node.computed、node.shorthand的属性lib/rules/quote-props.js。另外always模式下数字字面量键也会被要求加引号且修复时会输出其十进制字符串形式——例如0x123会被修复为291见 tests/lib/rules/quote-props.js。as-needed错误示例/*eslint quote-props: [error, as-needed]*/ var object { a: 0, 0: 0, true: 0, null: 0 };正确示例/*eslint quote-props: [error, as-needed]*/ var object1 { a-b: 0, 0x0: 0, 1e2: 0 }; var object2 { foo: bar, baz: 42, true: 0, 0: 0, qux-lorem: true }; var object3 { foo() { return; } };这里的关键是冗余引号的判定a-b、0x0、1e2的引号是必需的无法作为裸标识符或数字字面量表达而a、0、true、null的引号是冗余的会被报告为unnecessarilyQuotedProperty。判定逻辑位于areQuotesRedundantlib/rules/quote-props.js它用espree.tokenize将键值字符串重新词法分析只有当 token 恰好一个、从位置 0 覆盖到末尾且类型属于Identifier、Keyword、Null、Boolean或未跳过数字检查时Numeric且String(value) value时才认为引号冗余。这就是为什么0x0不能去引号——String(0x0)会变成0改变属性名语义而1e2去引号后变为1e2String(1e2)是100同样与原文语义不符。consistent错误示例/*eslint quote-props: [error, consistent]*/ var object1 { foo: bar, baz: 42, qux-lorem: true }; var object2 { foo: bar, baz: 42 };正确示例/*eslint quote-props: [error, consistent]*/ var object1 { foo: bar, baz: 42, qux-lorem: true }; var object2 { foo: bar, baz: 42 }; var object3 { foo: bar, baz: 42 };consistent模式下只要对象内出现引号混用就会报告inconsistentlyQuotedProperty并把未加引号的属性修复为加引号因为qux-lorem必须加引号所以整组对象向加引号方向统一。实现上由checkConsistency负责遍历node.properties收集quotedProps与unquotedProps若两类都非空则将未加引号的属性修复为加引号lib/rules/quote-props.js。consistent-as-needed错误示例/*eslint quote-props: [error, consistent-as-needed]*/ var object1 { foo: bar, baz: 42, qux-lorem: true }; var object2 { foo: bar, baz: 42 };正确示例/*eslint quote-props: [error, consistent-as-needed]*/ var object1 { foo: bar, baz: 42, qux-lorem: true }; var object2 { foo: bar, baz: 42 };consistent-as-needed是按需一致对象中只要存在一个必须加引号的属性如qux-lorem那么所有属性都要加引号object1反之若没有任何属性必须加引号则所有冗余引号都会被移除object2中foo、baz被修复为裸标识符。实现时checkConsistency会以第二个参数开启冗余检查checkQuotesRedundancy借助areQuotesRedundant判断是否存在必要引号若完全不存在必要引号则报告redundantQuoting并批量去引号lib/rules/quote-props.js。三个对象选项keywords、unnecessary、numberskeywords只在使用as-needed或consistent-as-needed时生效。默认情况下未开启keywordsas-needed允许关键字作为属性名时不加引号开启后则强制加引号。as-needed, { keywords: true }的错误示例/*eslint quote-props: [error, as-needed, { keywords: true }]*/ var x { while: 1, volatile: foo };consistent-as-needed, { keywords: true }的错误示例/*eslint quote-props: [error, consistent-as-needed, { keywords: true }]*/ var x { prop: 1, bar: foo };这里对象中出现了裸关键字键necessaryQuotes被置为 true导致整个对象必须全部加引号。规则使用的关键字列表是ES3 保留字全集见 lib/rules/utils/keywords.js——包含abstract、boolean、break、class、enum、volatile、while等 60 个词。之所以沿用 ES3 列表正是为了兼容文档开头提到的 ES3 引擎如 IE8场景。报告中对应的消息为unquotedReservedProperty未加引号的保留字键与requireQuotesDueToReservedWord因保留字存在而要求其余键也加引号。unnecessary只在as-needed模式下生效。默认unnecessary: true会禁止一切冗余引号设为false则允许保留冗余引号。正确示例/*eslint quote-props: [error, as-needed, { keywords: true, unnecessary: false }]*/ var x { while: 1, foo: bar // Would normally have caused a warning };上面代码中foo的引号本应触发警告但因为unnecessary: false而被放行while则因keywords: true必须加引号此时若写成裸while反而会报错。源码中CHECK_UNNECESSARY标志正是控制这一分支的唯一开关lib/rules/quote-props.js。numbers只在as-needed模式下生效。开启后数字字面量作为属性键时必须加引号。错误示例/*eslint quote-props: [error, as-needed, { numbers: true }]*/ var x { 100: 1 }此时会报告unquotedNumericProperty并自动修复为100。注意numbers选项与areQuotesRedundant中的skipNumberLiterals参数联动当numbers: true时即使100这类数字串满足可去引号的数值条件也会被保留引号lib/rules/quote-props.js。源码实现消息、遍历与自动修复该规则针对 AST 节点类型Property对象属性和ObjectExpression对象表达式注册了监听器lib/rules/quote-props.js按模式分发到三个核心函数checkOmittedQuotesalways模式报告unquotedPropertyFound用getQuotedKey给键补上双引号若键本身已是字符串字面量则保留原有引号风格。checkUnnecessaryQuotesas-needed模式先跳过方法/计算属性/简写属性再对字符串键做冗余判定报告unnecessarilyQuotedProperty对关键字键开启keywords时报告unquotedReservedProperty对数字键开启numbers时报告unquotedNumericProperty。checkConsistencyconsistent与consistent-as-needed模式按上述规则报告inconsistentlyQuotedProperty、redundantQuoting、requireQuotesDueToReservedWord。规则声明的全部消息 ID 共 7 个requireQuotesDueToReservedWord、inconsistentlyQuotedProperty、unnecessarilyQuotedProperty、unquotedReservedProperty、unquotedNumericProperty、unquotedPropertyFound、redundantQuotinglib/rules/quote-props.js。由于规则标记为fixable: code上述所有报告均附带fix修复器运行eslint --fix即可自动统一引号风格。边界情况与测试验证仓库的测试用例覆盖了大量边界场景tests/lib/rules/quote-props.js理解这些有助于避免误判BigInt 键1n在always模式下修复为1在as-needed下若未开启numbers则无需引号({ 1n: 1 })合法tests/lib/rules/quote-props.js。数字分隔符1_0修复为10、0b1_000修复为8、1_2.3_4e0_2修复为1234即自动修复会把各种字面量形态统一成十进制字符串tests/lib/rules/quote-props.js。十六进制与科学计数法0x123→291、1e2→100、5.→5再次印证去引号必须以String(value) value为前提否则会改变键的语义。特殊字符键 0、0 、hey//meh、hey/*meh*/等含空白、注释符的键在as-needed下均为合法去引号会破坏语义见 tests/lib/rules/quote-props.js。计算属性与简写[x]、{ x }、{ ...x }展开运算符以及方法b(){}在各模式下都会被跳过不参与引号判定tests/lib/rules/quote-props.js。注释保留带注释的修复会精确替换键部分而保留周边注释与引号风格tests/lib/rules/quote-props.js。同语义数字冲突1_000与1_000在consistent-as-needed下会因1_000的十进制形式1000与1_000不同而被判定为不一致tests/lib/rules/quote-props.js。历史沿革与废弃迁移quote-props的历史可追溯到更早的no-reserved-keys规则——conf/replacements.json 中记录了no-reserved-keys被quote-props取代且该迁移关系也体现在 conf/rule-type-list.json。需要特别说明的是该规则属于 ESLint 核心中的格式化stylistic类规则已在ESLint v8.53.0 标记为废弃并计划在 v11.0.0 前移除availableUntil: 11.0.0。废弃元数据位于 lib/rules/quote-props.js推荐迁移到由 ESLint Stylistic 维护的stylistic/eslint-plugin插件中的同名quote-props规则。如果你正在使用较新的 ESLint 版本并希望继续启用该风格检查请安装对应插件npm install --save-dev stylistic/eslint-plugin// eslint.config.js import stylistic from stylistic/eslint-plugin; export default [ { plugins: { stylistic: stylistic }, rules: { stylistic/quote-props: [error, consistent-as-needed] } } ];什么时候不应该使用该规则如果你不关心对象属性名是否统一加引号也不面向遗留的 ES3 环境可以直接关闭此规则。事实上由于该规则已被标记废弃并移出 ESLint 核心仅做风格约束、不涉及正确性——真正关乎正确性的仅有 ES3 关键字键与严格模式下的重复数字键两个场景——因此新项目建议直接采用stylistic/eslint-plugin中的迁移版本或与团队约定后在eslint.config.js中显式关闭它交由代码格式化工具如 Prettier统一处理。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表