news 2026/9/10 15:40:16

ESLint array-bracket-newline 规则详解:掌控数组方括号内换行排版

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESLint array-bracket-newline 规则详解:掌控数组方括号内换行排版

ESLint array-bracket-newline 规则详解:掌控数组方括号内换行排版

【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint

本篇技术指南围绕 ESLint 核心仓库中的array-bracket-newline规则展开,该规则用于强制(或禁止)在数组方括号[之后与]之前添加换行符,是团队统一数组字面量与解构赋值排版风格的关键 layout 类规则。读完本文,你将完整掌握其字符串选项("always"/"never"/"consistent")与对象选项(multiline/minItems)的全部语义、默认值、判定逻辑与自动修复行为,并能够结合源码理解其底层实现。

规则概览

许多风格指南会要求或禁止在数组方括号内部出现换行。array-bracket-newline规则正是为此而生:它强制在开方括号之后闭方括号之前执行换行策略。

  • 规则类型layout(排版布局类),在 lib/rules/array-bracket-newline.js 中声明;
  • 可自动修复fixable: "whitespace",即所有报错均可通过eslint --fix自动修正;
  • 适用节点:同时作用于ArrayExpression(数组字面量)与ArrayPattern(ES6 解构赋值模式),见 lib/rules/array-bracket-newline.js;
  • 默认行为:未配置任何选项时,等价于{ "multiline": true },即"元素或元素之间出现换行时,括号内也需要换行";
  • 关联规则array-bracket-spacing(控制方括号内部空格),两者常配合使用,详见 docs/src/rules/array-bracket-spacing.md。

注意:该规则自 ESLintv8.53.0起被标记为废弃(deprecated),原因与理由见下文"当前仓库中的废弃状态"一节。

选项详解

本规则接受字符串选项对象选项两种形式。

字符串选项

选项含义
"always"要求方括号内部必须有换行
"never"禁止方括号内部出现换行
"consistent"要求每一对方括号的换行使用保持一致:若一对括号中某一侧有换行而另一侧没有,则报错

对象选项

对象选项采用"任一条件满足则要求换行,否则禁止换行"的组合逻辑:

属性默认值含义
multilinetrue若元素内部或元素之间存在换行,则要求括号内换行;设为false时该条件禁用
minItemsnull当元素数量达到给定整数时要求括号内换行;设为0时行为与"always"相同;设为null(默认)时该条件禁用

字符串选项实战

always

配置方式:/*eslint array-bracket-newline: ["error", "always"]*/

不正确的代码

/*eslint array-bracket-newline: ["error", "always"]*/ const a = []; const b = [1]; const c = [1, 2]; const d = [1, 2]; const e = [function foo() { dosomething(); }];

正确的代码

/*eslint array-bracket-newline: ["error", "always"]*/ const a = [ ]; const b = [ 1 ]; const c = [ 1, 2 ]; const d = [ 1, 2 ]; const e = [ function foo() { dosomething(); } ];

可以看到,"always"强制每个数组(包括空数组[])都在[之后和]之前换行。测试用例 tests/lib/rules/array-bracket-newline.js 验证了var foo = [[1,2]]var foo = []"always"下会自动修复为逐层换行的形式。

never

配置方式:/*eslint array-bracket-newline: ["error", "never"]*/

不正确的代码

/*eslint array-bracket-newline: ["error", "never"]*/ const a = [ ]; const b = [ 1 ]; const c = [ 1, 2 ]; const d = [ 1, 2 ]; const e = [ function foo() { dosomething(); } ];

正确的代码

/*eslint array-bracket-newline: ["error", "never"]*/ const a = []; const b = [1]; const c = [1, 2]; const d = [1, 2]; const e = [function foo() { dosomething(); }];

"never""always"完全相反:括号必须紧贴元素(元素内部自身换行不受限制,例如[function foo() {\n...\n}]中的函数体换行是允许的,只要[与函数开头、函数结尾与]在同一行即可)。

consistent

配置方式:/*eslint array-bracket-newline: ["error", "consistent"]*/

不正确的代码(括号两侧换行不一致):

/*eslint array-bracket-newline: ["error", "consistent"]*/ const a = [1 ]; const b = [ 1]; const c = [function foo() { dosomething(); } ] const d = [ function foo() { dosomething(); }]

正确的代码

/*eslint array-bracket-newline: ["error", "consistent"]*/ const a = []; const b = [ ]; const c = [1]; const d = [ 1 ]; const e = [function foo() { dosomething(); }]; const f = [ function foo() { dosomething(); } ];

"consistent"的核心思想是"开括号后换行,则闭括号前也必须换行":左侧[之后有换行而右侧]之前没有(或反之)即为违规。测试 tests/lib/rules/array-bracket-newline.js 覆盖了空数组、单元素数组以及嵌套数组等多种形态。

对象选项实战

multiline

配置方式:/*eslint array-bracket-newline: ["error", { "multiline": true }]*/(这也是规则的默认行为)

不正确的代码

/*eslint array-bracket-newline: ["error", { "multiline": true }]*/ const a = [ ]; const b = [ 1 ]; const c = [ 1, 2 ]; const d = [1, 2]; const e = [function foo() { dosomething(); }];

正确的代码

/*eslint array-bracket-newline: ["error", { "multiline": true }]*/ const a = []; const b = [1]; const c = [1, 2]; const d = [ 1, 2 ]; const e = [ function foo() { dosomething(); } ];

注意这里的微妙之处:{ "multiline": true }只要求当数组内容本身跨行(即首尾元素之间不在同一行)时,括号才需要换行。因此:

  • [1, 2]单行数组 → 不要求换行,正确;
  • [\n1\n]单元素数组虽然内容只有一行,但括号换行了而内容没有跨行,反而被判定为不正确——因为"元素之间没有换行,括号却换行了",此时规则要求移除多余换行;
  • [\n1,\n2\n]内容跨行 → 必须换行,正确。

也就是说,multiline: true检查的是"换行是否必要":内容未跨行时,多余的括号换行会被报错并自动移除。这一点从源码的判定条件可以清楚看出(见下文实现解析)。

minItems

配置方式:/*eslint array-bracket-newline: ["error", { "minItems": 2 }]*/

不正确的代码

/*eslint array-bracket-newline: ["error", { "minItems": 2 }]*/ const a = [ ]; const b = [ 1 ]; const c = [1, 2]; const d = [1, 2]; const e = [ function foo() { dosomething(); } ];

正确的代码

/*eslint array-bracket-newline: ["error", { "minItems": 2 }]*/ const a = []; const b = [1]; const c = [ 1, 2 ]; const d = [ 1, 2 ]; const e = [function foo() { dosomething(); }];

minItems: 2的含义是:元素数量达到 2 个及以上时要求括号内换行,少于 2 个时禁止括号内换行。因此:

  • [][1](元素数量 < 2)→ 必须单行书写;
  • [1, 2][1,\n2](元素数量 ≥ 2)→ 必须写成[\n1, 2\n][\n1,\n2\n]形式;
  • [function foo() {...}]虽然元素只有 1 个,但元素数量未达阈值,括号必须贴紧(函数体内部换行不受影响)。

multiline 与 minItems 组合

配置方式:/*eslint array-bracket-newline: ["error", { "multiline": true, "minItems": 2 }]*/

不正确的代码

/*eslint array-bracket-newline: ["error", { "multiline": true, "minItems": 2 }]*/ const a = [ ]; const b = [ 1 ]; const c = [1, 2]; const d = [1, 2]; const e = [function foo() { dosomething(); }];

正确的代码

/*eslint array-bracket-newline: ["error", { "multiline": true, "minItems": 2 }]*/ const a = []; const b = [1]; const c = [ 1, 2 ]; const d = [ 1, 2 ]; const e = [ function foo() { dosomething(); } ];

组合使用时采用"或"逻辑:multiline条件或minItems条件任一满足即要求换行。因此示例中的e虽只有 1 个元素,但因函数体跨行使multiline条件成立,括号必须换行。

默认行为(未配置选项)

不写选项时,规则等价于{ "multiline": true }。其源码归一化逻辑位于 lib/rules/array-bracket-newline.js:当option为空时,multiline = trueminItems = Number.POSITIVE_INFINITY(即minItems条件永远不触发)。测试 tests/lib/rules/array-bracket-newline.js 的 valid 用例验证了默认情况下[][1][1, 2]均为合法,而[\n1, 2\n]这类内容跨行的写法必须保持括号换行。

源码级实现解析

选项归一化:字符串如何映射为对象

normalizeOptionValue函数(lib/rules/array-bracket-newline.js)将各种选项形态统一归一化为{ consistent, multiline, minItems }三要素:

传入选项consistentmultilineminItems
(未传)falsetrueInfinity
"always"falsefalse0
"never"falsefalseInfinity
"consistent"truefalseInfinity
{ minItems: 0 }falsefalse0
{ multiline: true }等对象falseBoolean(option.multiline)option.minItems \|\| Infinity

关键设计:

  • "always"{ minItems: 0 }殊途同归——minItems归零意味着"元素数量 ≥ 0 恒成立",即永远要求换行;
  • "never""consistent"都将minItems设为Infinity(阈值永不可达),两者差异仅在于consistent标志位;
  • option.minItems || Number.POSITIVE_INFINITY这一写法使得minItems: null也会落到Infinity,与文档所述默认值一致。

判定逻辑:什么时候需要换行

核心判定在check函数(lib/rules/array-bracket-newline.js)中完成,needsLinebreaks为真时要求括号换行,为假时禁止换行:

const needsLinebreaks = elements.length >= options.minItems || (options.multiline && elements.length > 0 && firstIncComment.loc.start.line !== lastIncComment.loc.end.line) || (elements.length === 0 && firstIncComment.type === "Block" && firstIncComment.loc.start.line !== lastIncComment.loc.end.line && firstIncComment === lastIncComment) || (options.consistent && openBracket.loc.end.line !== first.loc.start.line);

四个条件逐一解读:

  1. 元素数量达到minItems阈值
  2. multiline: true且元素数 > 0 且首尾 token(含注释)跨行——这是默认模式的核心判定;
  3. 空数组但包含跨行的块注释(如[/* \n多行注释\n */]),此时视为"内容跨行",要求括号换行;
  4. consistent模式下开括号行尾与首个 token 行首不在同一行——即"开括号后换行了,则闭括号前也必须换行"。

实现中特意区分了"判断是否多行"与"判断是否需要换行"所用的 token 集合:注释被计入多行判定,但换行必要性判定只基于真实 token。源码注释中的示例说明这一设计允许以下写法(在[后紧跟行注释再换行):

var arr = [ // eslint-disable-line foo 'a' ]

自动修复:插入与删除换行

四条报告路径对应四个messageId,全部支持自动修复(lib/rules/array-bracket-newline.js):

messageId触发场景修复动作
unexpectedOpeningLinebreak[之后不应有换行fixer.removeRange删除[与下一 token 之间空白
unexpectedClosingLinebreak]之前不应有换行fixer.removeRange删除上一 token 与]之间空白
missingOpeningLinebreak[之后缺少换行fixer.insertTextAfter(token, "\n")插入换行
missingClosingLinebreak]之前缺少换行fixer.insertTextBefore(token, "\n")插入换行

值得注意的边界处理:在删除换行时,如果紧邻的 token 是注释(通过astUtils.isCommentToken判断,见 lib/rules/utils/ast-utils.js),修复函数会返回null放弃修复——这是为了避免删除注释与其所属代码之间的换行导致注释错位。测试 tests/lib/rules/array-bracket-newline.js 中对嵌套数组的 autofix 输出(如var foo = [[2,\n3]]var foo = [\n[\n2,\n3\n]\n])精确验证了每一层括号的修复结果。

覆盖 ArrayPattern:解构赋值同样受控

check同时挂载在ArrayPatternArrayExpression上,因此解构赋值同样适用本规则:

/*eslint array-bracket-newline: ["error", "always"]*/ // 正确 var [ a, b ] = foo;

测试文件在 tests/lib/rules/array-bracket-newline.js 中为ArrayPattern场景(需ecmaVersion: 6)逐一验证了默认、"always""consistent"{ multiline: true }等选项。

与 array-bracket-spacing 配合使用

array-bracket-newline的关联规则array-bracket-spacing(见 docs/src/rules/array-bracket-spacing.md)控制的是空格而非换行,两者互补:

  • array-bracket-newline:控制[后与]前是否换行;
  • array-bracket-spacing:控制[后与]前是否留空格。

一个常见的组合是"允许换行但不允许空格"——array-bracket-spacing: ["error", "never"]的默认内置例外就允许括号内换行(这是常见书写模式),而换行的具体策略交给array-bracket-newline裁决。例如:

// array-bracket-spacing: ["error", "never"] + array-bracket-newline: ["error", "multiline"] var arr = [ 'foo', 'bar' ]; // 正确:无多余空格,内容跨行故括号换行

何时不使用此规则

如果你不关心数组方括号前后是否换行,或者项目已经采用 Prettier 等格式化工具统一排版,可以关闭本规则。文档原话为:"If you don't want to enforce line breaks after opening and before closing array brackets, don't enable this rule."

兼容性

该规则的前身来自 JSCS 的 validateNewlineAfterArrayElements 检查项,ESLint 将其纳入核心规则集并扩展出"always"/"never"/"consistent"及对象选项等更丰富的配置形态。

当前仓库中的废弃状态

从源码元数据看,该规则自ESLint v8.53.0起被标记为废弃(lib/rules/array-bracket-newline.js),废弃原因是"格式化类规则正在移出 ESLint 核心",并计划在 v11.0.0 之前从核心移除。官方建议的迁移路径是使用 ESLint Stylistic 项目维护的@stylistic/eslint-plugin插件,其中的array-bracket-newline规则提供了同名替代实现。因此在现有新代码库中,更推荐直接采用@stylistic/eslint-plugin的对应规则来管理数组括号换行风格。

参考路径

  • 规则文档:docs/src/rules/array-bracket-newline.md
  • 规则实现:lib/rules/array-bracket-newline.js
  • 规则测试:tests/lib/rules/array-bracket-newline.js
  • 辅助工具:lib/rules/utils/ast-utils.js
  • 关联规则文档:docs/src/rules/array-bracket-spacing.md

【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:40:01

2023年技术趋势:AI工程化与效能提升实践

1. 2023年技术趋势全景观察作为从业十余年的技术观察者&#xff0c;每年我都会系统梳理行业动向。2023年尤为特殊&#xff0c;这是后疫情时代首个完整年度&#xff0c;技术演进呈现出明显的"务实化"特征。从年初ChatGPT引爆AI军备竞赛&#xff0c;到年末AI芯片禁令重…

作者头像 李华
网站建设 2026/9/10 15:39:48

CANN/GE获取输出格式API

aclmdlGetOutputFormat 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、Ten…

作者头像 李华
网站建设 2026/9/10 15:39:30

Gogs 二进制移动到新目录后 Git hooks 引用失效路径如何修复

Gogs 二进制移动到新目录后 Git hooks 引用失效路径如何修复 【免费下载链接】gogs The painless way to host your own Git service 项目地址: https://gitcode.com/GitHub_Trending/go/gogs 当你把 Gogs 的二进制文件从原安装位置移动到新目录&#xff08;例如整理目录…

作者头像 李华