ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

ESLint multiline-ternary 规则详解:掌控三元表达式换行风格

ESLint multiline-ternary 规则详解:掌控三元表达式换行风格 ESLint multiline-ternary 规则详解掌控三元表达式换行风格【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint三元表达式ternary expression是 JavaScript 中最常用的条件表达式之一而它的换行风格直接影响代码的可读性。ESLint 内置的multiline-ternary规则rule_type 为layout专门用于强制或禁止三元表达式操作数之间的换行帮助你建立统一、可维护的写法规范。本文以 ESLint 仓库中的规则文档 docs/src/rules/multiline-ternary.md 为主体结合规则实现源码 lib/rules/multiline-ternary.js 与测试用例 tests/lib/rules/multiline-ternary.js完整讲解该规则的三种配置模式、可自动修复特性、与operator-linebreak规则的配合方式以及何时应当关闭它。为什么需要规范三元表达式的换行JavaScript 语法上允许三元表达式的操作数之间出现换行合理利用换行可以显著提升程序的可读性。例如下面这行代码把所有操作数挤在一行var foo bar baz ? value1 : value2;可以改写为以下任意一种多行形式让各操作数test、consequent、alternate在视觉上更清晰地区分开var foo bar baz ? value1 : value2; var foo bar baz ? value1 : value2;第二种写法运算符?与:行首对齐是社区中更常见的风格也是operator-linebreak规则默认配置所推荐的写法。multiline-ternary规则的价值在于它不关心你采用哪种多行排布只约束是否换行从而让团队代码保持一致。规则详情与三种配置模式该规则接受一个字符串选项共有三个取值选项行为always默认强制三元表达式的操作数之间必须有换行always-multiline仅当表达式本身跨越多行时强制操作数之间换行never禁止操作数之间出现换行从源码 lib/rules/multiline-ternary.js 可以看到三个选项在实现中的实际含义const option context.options[0]; const multiline option ! never; const allowSingleLine option always-multiline;即always与always-multiline共享同一套要求换行的检查逻辑区别仅在于always-multiline额外允许整个表达式保持单行allowSingleLine为true时若node.loc.start.line node.loc.end.line则直接跳过检查。需要特别注意的是本规则不约束?与:运算符本身的位置。如果你还想强制运算符换行位置行尾还是行首需要配合 operator-linebreak 规则使用后文会详细说明。always默认模式always是默认选项要求三元表达式的 test、consequent、alternate 三个操作数之间必须换行。使用always时的错误代码示例/*eslint multiline-ternary: [error, always]*/ foo bar ? value1 : value2; foo bar ? value : value2; foo bar ? value : value2;以上三种写法分别违反了test 与 consequent 之间换行或consequent 与 alternate 之间换行的约定。使用always时的正确代码示例/*eslint multiline-ternary: [error, always]*/ foo bar ? value1 : value2; foo bar ? (baz qux ? value1 : value2) : value3; foo bar ? (baz qux ? value1 : value2) : value3;注意后两个示例展示了一个关键行为嵌套的三元表达式同样适用该规则。只要表达式整体跨行每一层三元操作数之间都必须换行。ConditionalExpression访问器在遇到嵌套表达式时会为每一层分别触发检查。always-multilinealways-multiline是更温和的模式单行三元表达式完全合法但一旦表达式跨越多行操作数之间就必须换行。使用always-multiline时的错误代码示例/*eslint multiline-ternary: [error, always-multiline]*/ foo bar ? value1 : value2; foo bar ? value1 : value2; foo bar bar baz ? value1 : value2;前两例属于表达式已跨行但操作数之间未换行第三例虽然条件部分test自身是多行的但整个三元表达式的操作数都位于同一行同样违规。使用always-multiline时的正确代码示例/*eslint multiline-ternary: [error, always-multiline]*/ foo bar ? value1 : value2; foo bar ? value1 : value2; foo bar ? (baz qux ? value1 : value2) : value3; foo bar ? (baz qux ? value1 : value2) : value3; foo bar bar baz ? value1 : value2; foo bar ? baz qux ? value1 : value2 : value3;从这些正确示例可以看出always-multiline的判定粒度判断依据是整个三元表达式节点的起止行号node.loc.start.line node.loc.end.line而非操作数内部是否多行。因此foo bar \n bar baz ? value1 : value2;这种条件本身跨行但三元表达式收尾在同一行的写法是违规的而把?、:和 consequent 换行后则合法同理(baz qux ? value1 : value2)作为子表达式整体位于一行时完全允许因为内层三元表达式自身没有跨行。nevernever是严格风格禁止操作数之间出现任何换行整个三元表达式必须保持单行允许操作数自身内部换行例如括号内的内容。使用never时的错误代码示例/*eslint multiline-ternary: [error, never]*/ foo bar ? value : value2; foo bar ? value : value2; foo bar ? value1 : value2;前两例分别在 consequent 与 alternate 之间、test 与 consequent 之间出现了换行第三例在 test 内部换行后紧跟?换行同样违规。使用never时的正确代码示例/*eslint multiline-ternary: [error, never]*/ foo bar ? value1 : value2; foo bar ? (baz qux ? value1 : value2) : value3; foo bar ? ( baz qux ? value1 : value2 ) : value3;注意第三例consequent 是一对括号包裹的多行表达式但操作数之间没有换行因此合法。测试用例 tests/lib/rules/multiline-ternary.js 中never模式的合法用例如(a\n) ? b : c、a ? (\nb) : c也印证了这一点——换行发生在操作数内部括号内时不触发规则。在项目中启用规则multiline-ternary不是eslint:recommended中的默认规则docs.recommended为false见 lib/rules/multiline-ternary.js需要显式配置才会生效。在 flat configeslint.config.js中的典型写法export default [ { rules: { multiline-ternary: [error, always] } } ];将选项替换为always-multiline或never即可切换模式[warn, always]则将该规则的违规降级为警告。该规则注册于 lib/rules/index.js可通过规则名multiline-ternary直接引用。自动修复行为与源码实现解析该规则可自动修复meta.fixable: whitespace见 lib/rules/multiline-ternary.js即使用eslint --fix可以自动调整三元表达式的换行。从实现看规则监听ConditionalExpression节点lib/rules/multiline-ternary.js核心逻辑是通过sourceCode.getTokenAfter定位?questionToken和:colonToken其中astUtils.isNotClosingParenToken用于跳过 test 或 consequent 结尾的右括号正确处理(a)\n? b\n: c这类带括号的写法分别取 test 的末 token、consequent 的首末 token、alternate 的首 token用astUtils.isTokenOnSameLine判断?与:两侧是否同行根据选项决定是报告expectedTestCons/expectedConsAlt期望换行还是unexpectedTestCons/unexpectedConsAlt不应换行。在要求换行模式下autofix 会在缺失换行的位置插入\n通过fixer.replaceTextRange将空白区间替换为换行符在never模式下autofix 会删除多余换行通过fixer.removeRange移除跨行空白。一个重要的边界行为当三元表达式内部存在注释时规则不会执行自动修复。源码通过sourceCode.getCommentsInside(node)检测注释const hasComments !!sourceCode.getCommentsInside(node).length;一旦hasComments为true所有 fix 函数直接返回null仅报告错误而不做任何自动修改。测试用例对此有专门验证tests/lib/rules/multiline-ternary.js// 报告 expectedConsAlt 错误但 output 为 null不自动修复 code: a ? // comment\nb : c;, output: null,这一设计是为了避免自动重排时破坏注释与操作数的对应关系。自动修复会生成多条消息。例如在always模式下a ? b : c会被同时报告expectedTestCons与expectedConsAlt两条错误并修复为a\n? b\n: c见 tests/lib/rules/multiline-ternary.js嵌套表达式a ? (b ? c : d) : e则会为内层三元表达式再报告两条错误一次性修复为多层换行结构。与 operator-linebreak 规则协同使用官方文档明确指出multiline-ternary只约束是否换行不约束运算符换行位置。如果你希望同时规范?和:的位置需要启用 operator-linebreak 规则。operator-linebreak的默认配置是after, { overrides: { ?: before, :: before } }——即大多数运算符换行放在运算符之后但三元运算符?和:特例为换行放在运算符之前。这与multiline-ternary的always模式结合可以强制出如下行首对齐的经典风格answer everything ? 42 : foo;如果团队更喜欢行尾风格运算符放在行尾则可以为operator-linebreak显式配置export default [ { rules: { multiline-ternary: [error, always], operator-linebreak: [error, after, { overrides: { ?: after, :: after } }] } } ];两个规则职责互补multiline-ternary负责三操作数两两不同行operator-linebreak负责运算符在行首还是行尾配合使用即可完全锁定三元表达式的排版风格。何时不使用此规则如果你所在的项目对三元表达式操作数是否换行没有严格的统一约定例如已经通过 Prettier 等格式化工具管理排版或团队习惯单行三元表达式且不需要强制可以安全地关闭此规则。关闭方式很简单不在eslint.config.js中配置该规则或将规则值设为off。弃用状态与迁移说明从源码头部的 deprecated 元数据lib/rules/multiline-ternary.js可以确认该规则自 ESLint v8.53.0 起被弃用可用至 v11.0.0理由是格式化类规则正被移出 ESLint 核心。被弃用的格式化规则由stylistic/eslint-plugin接手维护其中multiline-ternary的等价规则位于该插件的同名规则中。如果你的 ESLint 版本已高于 v8.53.0建议在迁移期内逐步从 ESLint 核心规则切换到stylistic/eslint-plugin提供的同名规则以保证在 v11.0.0 之后仍能获得相同的检查能力。兼容性该规则源自 JSCS 的requireMultiLineTernary规则参见原文档 Compatibility 一节行为上与其保持兼容即强制三元表达式操作数换行。如果你正在从 JSCS 迁移到 ESLint可以在迁移映射表中将 JSCS 的该规则直接映射为multiline-ternary: [error, always]。小结multiline-ternary是 ESLint 布局类规则中对三元表达式排版约束最直接的规则三个选项覆盖了从强制多行到强制单行的完整光谱并支持--fix自动修复注释存在时除外。理解其只管换行、不管运算符位置的边界配合operator-linebreak规则即可构建完整、可自动化的三元表达式排版方案。需要注意的是其弃用状态在新项目中建议直接使用stylistic/eslint-plugin提供的等价规则。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表