十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

ESLint `lines-between-class-members` 规则详解:精确控制类成员间的空行布局

ESLint `lines-between-class-members` 规则详解:精确控制类成员间的空行布局 ESLintlines-between-class-members规则详解精确控制类成员间的空行布局【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslintlines-between-class-members是 ESLint 内置的 layout布局类规则用于强制或禁止 class 成员字段与方法之间的空行帮助开发者保持类结构的视觉分组与可读性。本文基于当前仓库的官方文档、规则实现源码与单元测试完整讲解该规则的两种配置模式字符串模式与enforce精细模式、第二选项exceptAfterSingleLine的语义以及底层基于 Token 的空白判断原理读完即可在真实项目中落地这套类内排版规范。规则概览该规则的核心作用是通过约束类成员之间的空行数量来提升代码可读性。它只关心成员与成员之间的间隔而不会检查第一个成员之前的空行也不会检查最后一个成员之后的空行——这一部分由同仓库中的 padded-blocks 规则负责该规则通过{ classes: always }等选项控制类体开头与结尾的留白。两者一内一外共同构成完整的类排版约束。从当前仓库源码看该规则在 lib/rules/lines-between-class-members.js 中实现并通过 lib/rules/index.js 以懒加载方式注册为lines-between-class-members。规则的元数据定义如下摘自 规则源码type: layout属于布局类规则不涉及逻辑正确性fixable: whitespace支持自动修复--fix可以自动补插或删除空行非recommended规则需要显式配置开启。基本行为与代码示例启用方式always为默认值即使不写也等同于开启/* eslint lines-between-class-members: [error, always] */不正确的代码成员之间没有空行/* eslint lines-between-class-members: [error, always]*/ class MyClass { x; foo() { //... } bar() { //... } }正确的代码每个成员之间都有一行空行/* eslint lines-between-class-members: [error, always]*/ class MyClass { x; foo() { //... } bar() { //... } }值得注意的一个边界示例在无分号风格semicolon-less style下如果前一个字段以分号结尾、且该分号单独出现在下一行行首规则会将这个分号视为下一个成员的一部分从而正确判断空行。以下代码在该规则下是正确的/* eslint lines-between-class-members: [error, always]*/ class MyClass { x 1 ;in 2 }选项详解该规则接受两个选项第一个选项可以是字符串或对象第二个选项是对象第一个选项字符串always/never取值说明always默认要求每个类成员之后有一个空行never禁止类成员之后出现空行字符串模式实际上会被内部转换为{ blankLine: 选项值, prev: *, next: * }的配置项即对任意前后成员组合都生效见 源码。always的错误示例缺少空行/* eslint lines-between-class-members: [error, always]*/ class Foo{ x; bar(){} baz(){} }never的错误示例不应出现空行/* eslint lines-between-class-members: [error, never]*/ class Bar{ x; bar(){} baz(){} }always的正确示例/* eslint lines-between-class-members: [error, always]*/ class Foo{ x; bar(){} baz(){} }never的正确示例/* eslint lines-between-class-members: [error, never]*/ class Bar{ x; bar(){} baz(){} }第一个选项对象enforce精细匹配模式当需要对不同类别的成员组合施加不同规则时使用对象形式。它含有一个enforce属性其值是一个对象数组每个对象包含三个必填属性属性可选值说明blankLinealways/never要求或禁止指定成员对之间出现空行prevmethod/field/*前一个类成员的类型method指方法field指类字段*匹配任意成员nextmethod/field/*后一个类成员的类型取值同prev关键规则见 官方文档 与 源码可以任意数量地配置如果一个成员对同时匹配多条配置以最后一条匹配的配置为准源码中getPaddingType从配置数组尾部向前遍历命中即返回如果一个成员对不匹配任何配置则跳过不检查。示例一仅禁止方法之间出现空行// disallows blank lines between methods /*eslint lines-between-class-members: [ error, { enforce: [ { blankLine: never, prev: method, next: method } ] }, ]*/ class MyClass { constructor(height, width) { this.height height; this.width width; } fieldA Field A; #fieldB Field B; method1() {} get area() { return this.method1(); } method2() {} }这段代码不正确因为method1()与get area()、get area()与method2()之间都属于method → method组合却被空行隔开。示例二要求字段周围有空行、同时禁止方法之间有空行// requires blank lines around fields, disallows blank lines between methods /*eslint lines-between-class-members: [ error, { enforce: [ { blankLine: always, prev: *, next: field }, { blankLine: always, prev: field, next: * }, { blankLine: never, prev: method, next: method } ] }, ]*/ class MyClass { constructor(height, width) { this.height height; this.width width; } fieldA Field A; #fieldB Field B; method1() {} get area() { return this.method1(); } method2() {} }这段代码不正确constructor与fieldA之间*→field组合缺少空行fieldA与#fieldB、#fieldB与method1()之间也缺少空行field→*组合。对应的正确版本如下字段被空行包围方法之间则保持紧凑// requires blank lines around fields, disallows blank lines between methods /*eslint lines-between-class-members: [ error, { enforce: [ { blankLine: always, prev: *, next: field }, { blankLine: always, prev: field, next: * }, { blankLine: never, prev: method, next: method } ] }, ]*/ class MyClass { constructor(height, width) { this.height height; this.width width; } fieldA Field A; #fieldB Field B; method1() {} get area() { return this.method1(); } method2() {} }第二个选项exceptAfterSingleLine第二个选项是对象仅含一个布尔属性exceptAfterSingleLine取值说明false默认单行类成员之后同样要求空行不豁免true跳过对单行类成员之后空行的检查多行成员之后仍要求空行正确示例开启exceptAfterSingleLine后单行成员x、bar(){}之后无需空行但多行成员baz(){...}之后仍必须有空行/* eslint lines-between-class-members: [error, always, { exceptAfterSingleLine: true }]*/ class Foo{ x; // single line class member bar(){} // single line class member baz(){ // multi line class member } qux(){} }从 源码 看判断单行成员的依据是成员的第一个 Token 与最后一个 Token 是否位于同一行!astUtils.isTokenOnSameLine(curFirst, curLast)随后通过!isMulti options[1].exceptAfterSingleLine决定是否跳过always检查。组合使用enforceexceptAfterSingleLine两者可以叠加使用。下面的配置要求方法前后有空行、字段之间有空行同时豁免单行成员之后的空行检查/*eslint lines-between-class-members: [ error, { enforce: [ { blankLine: always, prev: *, next: method }, { blankLine: always, prev: method, next: * }, { blankLine: always, prev: field, next: field } ] }, { exceptAfterSingleLine: true } ]*/ class MyClass { constructor(height, width) { this.height height; this.width width; } fieldA Field A; #fieldB Field B; method1() {} get area() { return this.method1(); } method2() {} }该示例是正确的fieldA与#fieldB、#fieldB与method1()之间虽然紧邻但fieldA、#fieldB、method1()都是单行成员被exceptAfterSingleLine: true豁免而多行的get area()之后仍保留了空行。源码实现原理Token 边界与空行判定该规则在ClassBody访问器中遍历body数组对每对相邻成员执行检查见 源码。理解其实现有助于预判各类边界行为成员类型匹配源码定义了三类匹配器lib/rules/lines-between-class-members.js#L23-L27——*恒真field要求节点类型为PropertyDefinitionmethod要求节点类型为MethodDefinition。这也说明enforce模式下的prev/next是基于 AST 节点类型判断的。边界 Token 的确定getBoundaryTokens默认取当前节点最后一个 Token与下一节点第一个 Token作为边界。唯一的例外是无分号风格如果当前节点以分号结尾、且该分号与前一 Token 不在同一行、却与下一成员的第一个 Token 在同一行如x 1换行后;in 2则把分号视为下一个成员的一部分见 源码注释与实现这正是文档中那个特殊正确示例的原理。连续 Token 的合并findLastConsecutiveTokenAfter与findFirstConsecutiveTokenBefore会向前/向后吞并行距不超过阈值此处为 1 行的连续 Token并包含注释从而把位于两成员之间的注释纳入空行区域计算。空行判定通过afterPadding.loc.start.line - beforePadding.loc.end.line 1判断是否存在空行hasTokenOrCommentBetween用于检测边界之间是否还夹着注释或 Token。修复逻辑fixernever且存在空行时用\n替换边界之间的文本区间删除多余空行always且无空行、且未被exceptAfterSingleLine豁免时在curLineLastToken之后插入一个\n若空行区域中夹着注释或 Token则返回null不自动修复避免破坏注释排版见 lib/rules/lines-between-class-members.js#L326-L351。测试用例佐证该规则的完整行为由 tests/lib/rules/lines-between-class-members.js共 2600 行验证测试基于ecmaVersion: 2022运行。以下几类关键场景均有覆盖字符串模式always的自动修复输出如class foo{ bar(){}\nbaz(){}}修复为中间加空行、never的删除空行修复注释与分号成员间夹//、/* */注释、孤立分号;、;;的多种组合字段与私有字段field1、#field1、field1 () {...}等字段场景enforce组合对method→method、method→field、field→method、field→field、*→method、method→*、*→field、field→*、*→*等所有 prev/next 组合的 valid/invalid 用例多配置优先级测试中特意把never系列配置写在always系列之前验证后写的配置优先最后一个匹配的配置生效的语义见测试文件中multiple configurations段落exceptAfterSingleLine组合验证单行成员豁免、多行成员仍被检查的行为。规则的弃用与迁移需要特别说明该规则在ESLint v8.53.0 起被标记为弃用availableUntil: 11.0.0原因是格式化类规则正在被移出 ESLint 核心见 lib/rules/lines-between-class-members.js#L35-L56。官方推荐迁移至ESLint Stylistic维护的替代实现即stylistic/eslint-plugin中的同名规则lines-between-class-members配置语法保持一致。如果你正在维护旧项目且无法升级该规则在当前核心版本中依然可用若为新项目建议直接采用 ESLint Stylistic 方案。何时不使用该规则如果你不希望强制类成员之间存在空行直接关闭此规则即可/* eslint lines-between-class-members: off */兼容性该规则的灵感来源是 JSCS 的两条规则requirePaddingNewLinesAfterBlocksdisallowPaddingNewLinesAfterBlocks这两条规则只提供了始终要求/始终禁止的二元能力而 ESLint 的lines-between-class-members通过enforce对象扩展出了按成员类型方法/字段/任意与方向prev/next精细配置的能力同时补上了exceptAfterSingleLine单行豁免选项功能上更贴近现代 class 语法字段、私有字段、getter 等的实际排版需求。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表