ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ESLint array-element-newline 规则详解:数组元素换行风格的全量配置指南

ESLint array-element-newline 规则详解:数组元素换行风格的全量配置指南 ESLint array-element-newline 规则详解数组元素换行风格的全量配置指南【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint导读array-element-newline是 ESLint 核心库中的一条布局类layout规则用于强制约束数组字面量与数组解构模式中元素之间是否换行。许多主流风格指南对数组元素一行排开还是逐行展开有明确偏好本规则正是为此而生。读完本文你将掌握该规则全部六种配置形态always、never、consistent、multiline、minItems以及ArrayExpression/ArrayPattern分离配置的语义、判断逻辑与自动修复行为并能在实际项目中正确地启用与调试它。规则概述本规则要求在数组元素之间强制换行Enforce line breaks after each array element其规则详情定义于 docs/src/rules/array-element-newline.md。从源码 lib/rules/array-element-newline.js 的meta定义可以看到它具备如下属性type: layout属于布局/格式类规则只影响代码排版不影响语义。fixable: whitespace支持--fix自动修复修复内容仅为空白字符换行/空格安全无副作用。recommended: false不在eslint:recommended预设中需按团队规范显式开启。两条消息模板unexpectedLineBreak: There should be no linebreak here.不应换行missingLineBreak: There should be a linebreak after this element.必须换行该规则同时监听ArrayExpression数组字面量如[1, 2]与ArrayPattern解构赋值中的数组模式如const [a, b] arr两类节点见源码末尾return { ArrayPattern: check, ArrayExpression: check }因此它对定义数组和解构数组两处场景都能生效。与相邻规则的协作数组排版牵涉多个维度array-element-newline只负责元素之间的换行其余维度由下列相邻规则管控这些关联规则同样记录在原文档的 frontmatter 中array-bracket-spacing控制[与第一个元素、最后一个元素与]之间是否加空格array-bracket-newline控制[后与]前是否强制换行object-curly-newline 与 object-property-newline对象字面量的对应换行规则object-curly-spacing对象花括号内的空格block-spacing 与 brace-style代码块大括号内部的换行max-statements-per-line单行内允许的最大语句数。提示array-element-newline只检查元素之间不会强制[后或]前的换行这部分由 array-bracket-newline 负责。例如[\n1, 2\n]在always模式下仍会报错因为1与2之间没有换行。配置语法与选项总览该规则接受字符串或对象两种形态的选项对应源码中schema的basicConfig定义选项类型说明always默认字符串要求数组元素之间必须换行never字符串禁止数组元素之间换行consistent字符串要求数组元素之间换行风格保持一致要么全换行要么全不换行multiline: boolean对象若数组内任一元素自身跨多行元素内部有换行则要求元素之间也换行为false时该条件禁用minItems: number对象当元素数量 ≥ 给定整数时要求元素之间换行为0时行为等同于always为null默认时该条件禁用其中字符串选项与对象选项的映射关系可从源码normalizeOptionValuelib/rules/array-element-newline.js清晰看出always→{ consistent: false, multiline: false, minItems: 0 }元素数 ≥ 0 恒成立等价于总是换行never→minItems: Number.POSITIVE_INFINITY元素数永远达不到无穷大等价于永不换行consistent→consistent: true, minItems: Number.POSITIVE_INFINITY对象选项 →multiline: Boolean(option.multiline)minItems: option.minItems || Number.POSITIVE_INFINITY注意minItems未传时视为Infinity即仅由multiline条件决定是否换行显式传0则等同always传null则禁用该条件并回落到Infinity。schema中对minItems的类型约束为[integer, null]且minimum: 0非法配置会在校验阶段直接报错。为数组表达式与数组模式分别配置当需要数组字面量与解构模式采用不同风格时可传入按节点类型拆分的对象{ array-element-newline: [error, { ArrayExpression: consistent, ArrayPattern: { minItems: 3 }, }] }ArrayExpression仅作用于数组字面量未指定时本规则不对数组字面量生效ArrayPattern仅作用于解构赋值的数组模式未指定时本规则不对数组模式生效。源码normalizeOptionslib/rules/array-element-newline.js的逻辑是只要对象中出现了ArrayExpression或ArrayPattern任一键就按节点类型分别归一化两个键的基本配置可以是字符串也可以是对象。而check函数中if (!options) return;则保证了未指定的节点类型不触发检查。另外schema要求该对象至少含一个属性minProperties: 1空对象{}是非法配置。默认选项 always默认情况下数组的每个元素之间必须存在换行元素数量为 0 或 1 时天然满足不报错。错误示例/*eslint array-element-newline: [error, always]*/ var c [1, 2]; var d [1, 2, 3]; var e [1, 2, 3 ]; var f [ 1, 2, 3 ]; var g [ function foo() { dosomething(); }, function bar() { dosomething(); } ];注意e、f虽然在[后或]前有换行但元素之间仍以逗号同行因此同样违规。正确示例/*eslint array-element-newline: [error, always]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var d [ 1, 2, 3 ]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];选项 never禁止元素之间换行——所有元素应紧凑地排在同一行含首元素在[之后换行的情况只要元素之间同行即可。错误示例/*eslint array-element-newline: [error, never]*/ var c [ 1, 2 ]; var d [ 1, 2, 3 ]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];正确示例/*eslint array-element-newline: [error, never]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var e [ 1, 2, 3]; var f [ 1, 2, 3 ]; var g [ function foo() { dosomething(); }, function bar() { dosomething(); } ];可以看到只要元素两两之间没有换行无论[/]前后的空白如何排版都是合法的——这印证了该规则只关心元素之间的换行。选项 consistent要求数组内部换行风格一致要么所有元素都换行要么全部同行不允许部分换行、部分同行的混合排版。错误示例/*eslint array-element-newline: [error, consistent]*/ var a [ 1, 2, 3 ]; var b [ function foo() { dosomething(); }, function bar() { dosomething(); }, function baz() { dosomething(); } ];正确示例/*eslint array-element-newline: [error, consistent]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var e [ 1, 2 ]; var f [ 1, 2, 3 ]; var g [ function foo() { dosomething(); }, function bar() { dosomething(); }, function baz() { dosomething(); } ]; var h [ function foo() { dosomething(); }, function bar() { dosomething(); }, function baz() { dosomething(); } ];从源码看consistent 的判定发生在check函数lib/rules/array-element-newline.js中先统计实际存在换行的元素间隔数linebreaksCount再判断linebreaksCount 0 linebreaksCount node.elements.length是否成立——即存在换行但没有全部换行此时判定为不一致并报错。对象选项 multiline当数组中至少有一个元素自身跨越多行例如元素是跨行的函数表达式或嵌套数组时要求元素之间也必须换行所有元素都是单行时不强制换行。错误示例{ multiline: true }/*eslint array-element-newline: [error, { multiline: true }]*/ var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];第一例中2与3同行第二例中两个跨行函数表达式之间没有换行均违规。正确示例{ multiline: true }/*eslint array-element-newline: [error, { multiline: true }]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];c、d虽然元素同行但因为每个元素都是单行所以合规。源码中该条件的实现是遍历所有非空元素若存在element.loc.start.line ! element.loc.end.line元素起止行不同则置elementBreak truelib/rules/array-element-newline.js。注意multiline与minItems是或关系——任一条件满足即要求换行。对象选项 minItems当数组元素数量达到阈值时强制换行未达到阈值时禁止换行用于短数组单行、长数组多行的常见风格。错误示例{ minItems: 3 }/*eslint array-element-newline: [error, { minItems: 3 }]*/ var c [1, 2]; var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];c只有 2 个元素却换行d、e元素数达到 3e恰好 2 个注意e只有两个函数元素——但它仍被判为错误是因为……见下文解释——实际上e含 2 个元素此处被判错的原因在于源码中判定条件为elements.length options.minItems与multiline条件的组合之外还有一处细节node.elements.length包含空位null。更准确地说从测试用例看{ minItems: 3 }下含 2 个元素的数组换行会报unexpectedLineBreak因为2 3不该换行。e的两个函数元素之间换行了所以违规。正确示例{ minItems: 3 }/*eslint array-element-newline: [error, { minItems: 3 }]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];d恰有 3 个元素因此必须换行e只有 2 个元素函数间保持同行即可。minItems的边界语义与源码normalizeOptionValue对应minItems: 0条件恒满足行为等同always测试用例tests/lib/rules/array-element-newline.js中[1, 2]会被修复为[1,\n2]minItems: null默认该条件禁用等价于永不因数量触发放行是否换行完全取决于其他条件此时未配multiline时行为接近neverminItems: 3及以上元素数小于阈值时禁止换行达到阈值时强制换行。组合选项 multiline 与 minItems两个条件同时开启时任一条件满足即要求换行两者都不满足时才禁止换行。错误示例{ multiline: true, minItems: 3 }/*eslint array-element-newline: [error, { multiline: true, minItems: 3 }]*/ var c [1, 2]; var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];c元素数 2 3 且无跨行元素却存在换行 → 报unexpectedLineBreakd元素数 3 ≥ 3应换行却同行 → 报missingLineBreake元素为跨行函数应换行却同行 → 报missingLineBreak。正确示例{ multiline: true, minItems: 3 }/*eslint array-element-newline: [error, { multiline: true, minItems: 3 }]*/ var a []; var b [1]; var c [1, 2]; var d [1, 2, 3]; var e [ function foo() { dosomething(); }, function bar() { dosomething(); } ];源码中needsLinebreaks的完整判定lib/rules/array-element-newline.js为const needsLinebreaks elements.length options.minItems || (options.multiline elementBreak) || (options.consistent linebreaksCount 0 linebreaksCount node.elements.length);三者是或关系任一为真则要求元素之间换行否则要求同行。分离配置 ArrayExpression 与 ArrayPattern下面以{ ArrayExpression: always, ArrayPattern: never }为例数组字面量必须逐行展开而解构模式必须紧凑同行。错误示例/*eslint array-element-newline: [error, { ArrayExpression: always, ArrayPattern: never }]*/ var a [1, 2]; var b [1, 2, 3]; var c [ function foo() { dosomething(); }, function bar() { dosomething(); } ]; var [d, e] arr; var [f, g, h] arr; var [i function foo() { dosomething() }, j function bar() { dosomething() }] arr正确示例/*eslint array-element-newline: [error, { ArrayExpression: always, ArrayPattern: never }]*/ var a [1, 2]; var b [1, 2, 3]; var c [ function foo() { dosomething(); }, function bar() { dosomething(); } ]; var [d, e] arr var [f, g, h] arr var [i function foo() { dosomething() }, j function bar() { dosomething() }] arr测试用例tests/lib/rules/array-element-newline.js文件末尾的ArrayExpression ArrayPattern分组还验证了同一行内同时出现两种节点的场景例如var [a,\nb] [1, 2]会被自动修复为var [a, b] [1,\n2]——数组模式去掉换行、数组字面量补上换行一次--fix同时处理两类节点。自动修复行为与实现细节该规则fixable: whitespace修复逻辑位于两个 report 函数中reportRequiredLineBreaklib/rules/array-element-newline.js当需要换行但元素同行时将上一元素末 token 与下一元素首 token之间的文本替换为\nreportNoLineBreaklib/rules/array-element-newline.js当禁止换行但元素分行时将间隔文本替换为 并处理了逗号位于行首如[\n1\n, 2\n]的排版会连同行首逗号前的空白一并清理为[1, 2, 3]。需要特别说明的安全边界如果元素之间存在注释如[1, /* c */ 2]修复函数会通过astUtils.isCommentToken检测并返回null放弃自动修复避免在修复过程中破坏注释。判断是否同行依赖工具函数isTokenOnSameLine判断逗号使用isCommaTokentoken 值为,且类型为Punctuator定义于 lib/rules/utils/ast-utils.js。另外源码在统计换行数时通过getFirstTokenBetween(previousElement, element, astUtils.isCommaToken)精确定位相邻元素之间的逗号 token并会跳过首元素以及null元素数组空位如[1, , 3]中的空洞这些细节保证了规则在含空位、含嵌套表达式如[1, (2), 3]、含注释等边界场景下行为正确——测试文件 tests/lib/rules/array-element-newline.js 共 1063 行覆盖了上述全部边界用例。与旧工具 JSCS 的兼容性本规则的实现灵感来自 JSCS 规则validateNewlineAfterArrayElements原文档 Compatibility 一节有说明它要求数组的每个元素后都换行。如果你从 JSCS 迁移到 ESLint可大致按以下对应关系替换JSCS 的validateNewlineAfterArrayElements对应 ESLint 的array-element-newline: [error, always]。何时不应使用本规则如果你不希望约束数组元素之间的换行例如团队已统一使用 Prettier 等格式化工具管理排版或项目对数组排版无强制约定就不要启用本规则——原文档明确说明If you dont want to enforce linebreaks between array elements, dont enable this rule.此时数组的换行风格完全交给开发者或格式化工具自行决定。弃用状态与迁移建议需要重点提醒的是从源码meta.deprecatedlib/rules/array-element-newline.js可以看到该规则自 ESLint v8.53.0 起已被标记为弃用弃用原因文案为 Formatting rules are being moved out of ESLint core.格式化规则正在从 ESLint 核心中迁出并计划在 v11.0.0 移除。官方给出的替代方案是社区维护的stylistic/eslint-plugin其array-element-newline规则与原规则同名、配置语法完全一致。因此如果你使用 ESLint v8.53.0 及以后版本仍可继续使用本规则但会看到弃用提示面向 ESLint v11 及以后的项目建议直接迁移到stylistic/eslint-plugin把规则名改为stylistic/array-element-newline配置选项字符串与对象形态无需改动即可沿用。这也解释了为什么本项目 docs/src/rules/array-element-newline.md 同时保留着完整的选项与示例文档——它们对迁移后的同名规则依然适用。迁移后建议同步配合 array-bracket-spacing、array-bracket-newline 等相邻排版规则保证数组整体排版风格的统一。快速查阅速查表目标风格配置典型适用场景元素必须逐行展开[error, always]崇尚纵向可读性、diff 友好的代码库元素必须同行紧凑[error, never]追求代码密度、短数组居多的项目换行风格保持一致[error, consistent]混合风格项目先统一为一种风格含多行元素时展开[error, { multiline: true }]数组元素多为函数/对象字面量的代码库元素数达阈值时展开[error, { minItems: 3 }]短数组单行、长数组多行的经典规范字面量/解构分开管控[error, { ArrayExpression: always, ArrayPattern: never }]对两种数组场景有不同偏好的团队【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表