ESLint space-before-function-paren 规则完全指南:统一函数定义括号前的空格风格 ESLint space-before-function-paren 规则完全指南统一函数定义括号前的空格风格【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本指南系统讲解 ESLint 内置布局规则space-before-function-paren它用于强制函数名或function关键字与左括号(之间空格的统一风格覆盖函数声明、函数表达式、类方法与 async 箭头函数等全部函数形态。读完本文你将掌握该规则的全部配置方式字符串选项与对象选项、各选项下的正确/错误代码形态、其源码实现原理与自动修复边界并能据此在团队中落地一致的函数括号间距规范。规则概述检查什么、何时生效在书写函数时函数名或function关键字与左括号之间允许存在空白。命名函数还要求function关键字与函数名之间有一个空格而匿名函数则无此要求。例如function withoutSpace(x) { // ... } function withSpace (x) { // ... } var anonymousWithoutSpace function() {}; var anonymousWithSpace function () {};不同风格指南对“匿名函数的function关键字后是否要留空格”“函数名后是否要留空格”存在不同约定。space-before-function-paren规则的目的就是强制函数括号前的空白与配置偏好保持一致一旦不一致即报告警告。从规则元数据lib/rules/space-before-function-paren.js可以看到它的定位规则类型typelayout属于排版/格式类规则不涉及逻辑正确性recommendedfalse未收录进eslint:recommended与核心配置tests/conf 中也没有它的条目需要团队显式开启fixablewhitespace可通过--fix自动修复行注释场景除外详见后文消息 IDunexpectedSpace“Unexpected space before function parentheses.”与missingSpace“Missing space before function parentheses.”。规则详解节点识别与命名判定逻辑从源码的create(context)看lib/rules/space-before-function-paren.js规则监听三类 AST 节点FunctionDeclaration函数声明如function foo () {}FunctionExpression函数表达式如var bar function () {}ArrowFunctionExpression箭头函数如async () 1。对于每一个函数节点规则首先要判定它是“命名函数”还是“匿名函数”对应源码中的isNamedFunctionlib/rules/space-before-function-paren.js函数节点自身带有id如function foo() {}、var bar function foo() {}或父节点是MethodDefinition如class Foo { constructor() {} }中的构造器与方法或父节点是Property且为get/set访问器或方法简写如var baz { bar() {} }。满足上述任一条件即视为命名函数。也就是说类构造器、类方法、对象字面量中的方法简写与访问器都会按named分支处理。随后getConfigForFunctionlib/rules/space-before-function-paren.js为每个函数选择生效的配置按优先级分为四个分支async 箭头函数带括号使用overrideConfig.asyncArrow || baseConfig命名函数使用overrideConfig.named || baseConfig匿名函数且非生成器使用overrideConfig.anonymous || baseConfig其他情况一律ignore包括普通非 async箭头函数、无括号的单参数箭头函数如async foo bar、以及匿名生成器函数function* () {}源码注释说明这是为了避免与generator-star-spacing规则职责重叠。配置选项详解该规则支持字符串选项或对象选项两种写法lib/rules/space-before-function-paren.js 中的 schema 使用oneOf限定{ space-before-function-paren: [error, always], // or space-before-function-paren: [error, { anonymous: always, named: always, asyncArrow: always }], }字符串选项取值与含义如下取值含义always默认要求参数左括号(前必须有一个空格never禁止参数左括号(前存在任何空格需要注意字符串选项不检查 async 箭头函数表达式这是为了向后兼容而保留的行为。对象选项则允许针对每种函数类型分别配置其中每个子选项可取always、never或ignore默认值为always子选项适用对象示例anonymous匿名函数表达式function () {}named命名函数表达式、函数声明、类方法与访问器function foo () {}asyncArrowasync 箭头函数表达式async () {}ignore表示对该类函数不施加任何约束两种写法都被接受。字符串选项 always默认不正确的代码默认always下报missingSpace/*eslint space-before-function-paren: error*/ function foo() { // ... } var bar function() { // ... }; var bar function foo() { // ... }; class Foo { constructor() { // ... } } var baz { bar() { // ... } }; var baz async() 1正确的代码/*eslint space-before-function-paren: error*/ function foo () { // ... } var bar function () { // ... }; var bar function foo () { // ... }; class Foo { constructor () { // ... } } var baz { bar () { // ... } }; var baz async () 1注意上面示例中async () 1也被纳入always检查这是因为文档示例直接使用了对象语义默认值。而使用字符串always时 async 箭头函数不会被检查详见 tests/lib/rules/space-before-function-paren.js其中async() 1配always是有效代码。字符串选项 never不正确的代码报unexpectedSpace/*eslint space-before-function-paren: [error, never]*/ function foo () { // ... } var bar function () { // ... }; var bar function foo () { // ... }; class Foo { constructor () { // ... } } var baz { bar () { // ... } }; var baz async () 1正确的代码/*eslint space-before-function-paren: [error, never]*/ function foo() { // ... } var bar function() { // ... }; var bar function foo() { // ... }; class Foo { constructor() { // ... } } var baz { bar() { // ... } }; var baz async() 1同样async() 1在这里作为正确代码出现是因为字符串never同样不检查 async 箭头函数测试用例见 tests/lib/rules/space-before-function-paren.js。对象选项按函数类型差异化配置当团队内部对“函数声明/方法”“匿名函数表达式”“async 箭头函数”持有不同风格偏好时用对象选项可以精细区分。{anonymous: always, named: never, asyncArrow: always}该配置要求匿名函数与 async 箭头函数括号前有空格命名函数括号前无空格。不正确的代码/*eslint space-before-function-paren: [error, {anonymous: always, named: never, asyncArrow: always}]*/ function foo () { // ... } var bar function() { // ... }; class Foo { constructor () { // ... } } var baz { bar () { // ... } }; var baz async(a) await a正确的代码/*eslint space-before-function-paren: [error, {anonymous: always, named: never, asyncArrow: always}]*/ function foo() { // ... } var bar function () { // ... }; class Foo { constructor() { // ... } } var baz { bar() { // ... } }; var baz async (a) await a{anonymous: never, named: always}匿名函数括号前无空格命名函数含类构造器与对象方法括号前有空格。不正确的代码/*eslint space-before-function-paren: [error, { anonymous: never, named: always }]*/ function foo() { // ... } var bar function () { // ... }; class Foo { constructor() { // ... } } var baz { bar() { // ... } };正确的代码/*eslint space-before-function-paren: [error, { anonymous: never, named: always }]*/ function foo () { // ... } var bar function() { // ... }; class Foo { constructor () { // ... } } var baz { bar () { // ... } };{anonymous: ignore, named: always}匿名函数完全不检查有无空格均可命名函数要求括号前有空格。不正确的代码只有命名函数会被报告/*eslint space-before-function-paren: [error, { anonymous: ignore, named: always }]*/ function foo() { // ... } class Foo { constructor() { // ... } } var baz { bar() { // ... } };正确的代码/*eslint space-before-function-paren: [error, { anonymous: ignore, named: always }]*/ var bar function() { // ... }; var bar function () { // ... }; function foo () { // ... } class Foo { constructor () { // ... } } var baz { bar () { // ... } };上方示例中两个var bar ...匿名函数一个有空格、一个无空格均被ignore放行。源码视角配置解析与空格检测流程create(context)开头对选项做了归一化lib/rules/space-before-function-paren.jsconst baseConfig typeof context.options[0] string ? context.options[0] : always; const overrideConfig typeof context.options[0] object ? context.options[0] : {};传字符串时baseConfig即该字符串overrideConfig为空对象传对象时baseConfig回落到always各子选项从overrideConfig读取未传任何选项时退化为always。真正的检测逻辑集中在checkFunctionlib/rules/space-before-function-paren.js核心步骤为通过getConfigForFunction(node)拿到该函数应遵循的always/never/ignore若为ignore直接返回否则用astUtils.isOpeningParenToken找到函数节点的第一个左括号 tokenrightToken再用sourceCode.getTokenBefore(rightToken)取其前一个 tokenleftToken通过sourceCode.isSpaceBetween(leftToken, rightToken)判断两者之间是否存在空白若存在空白且配置为never报告unexpectedSpace定位范围是leftToken.loc.end到rightToken.loc.start若不存在空白且配置为always报告missingSpace定位在rightToken.loc。自动修复--fix与边界情况该规则标记为fixable: whitespace在eslint . --fix或 IDE 保存修复时会自动处理always缺失空格直接调用fixer.insertTextAfter(leftToken, )在左侧 token 之后插入一个空格。例如测试中的function foo() {}→function foo () {}tests/lib/rules/space-before-function-paren.jsfunction foo/* */() {}→function foo /* */() {}never多余空格先取出左右 token 之间的注释若存在行注释comment.type Line即//形式则返回null放弃修复——因为删除换行会把行注释后方的代码注释掉例如function foo//\n() {}与function foo // line comment \n () {}的测试输出都是nulltests/lib/rules/space-before-function-paren.js若无行注释则用fixer.replaceTextRange删除leftToken.range[1]到rightToken.range[0]之间的空白同时把块注释/* */保留并拼接回来。多块注释压缩的修复在测试中也有体现tests/lib/rules/space-before-function-paren.js// 修复前 function foo/* 1 */ /* 2 */ /* 3 */ /* 4 */ () {} // 修复后never function foo/* 1 *//* 2 *//* 3 *//* 4 */() {}特殊场景生成器函数与无括号箭头函数从getConfigForFunction的分支可以确认两类“天然豁免”的函数匿名生成器函数function* () {}源码注释明确写道“generator-star-spacingshould warn anonymous generators”即该场景交由generator-star-spacing规则管理本规则返回ignore测试中var foo function *() {};在always下属于有效代码tests/lib/rules/space-before-function-paren.js非 async 箭头函数与无括号箭头函数如() 1、async a a无论asyncArrow怎么配置都不被检查tests/lib/rules/space-before-function-paren.js。asyncArrow只作用于带括号的 async 箭头函数即async () 1/async() 1这类形态。与 keyword-spacing 的关系该规则的元数据中声明了related_rules: keyword-spacing见文档 front matter 与 lib/rules/space-before-function-paren.js。keyword-spacingkeyword-spacing 规则文档负责function、if、else等关键字与其后 token 之间的间距而本规则专门负责括号前的空白。两者配合可以完整覆盖“函数定义处的空白风格”例如function关键字后、函数名后、左括号前的空格分别由两条规则协同约束。在需要完整格式化函数定义时可同时启用这两条规则。弃用说明与迁移需要特别留意的是该规则已在ESLint v8.53.0 被标记为弃用源码 lib/rules/space-before-function-paren.js 中的deprecated.deprecatedSince: 8.53.0并计划在v11.0.0 从核心中移除availableUntil: 11.0.0。弃用原因是“格式类规则正在移出 ESLint 核心”。官方推荐的替代方案是使用stylistic/eslint-plugin插件中同名规则space-before-function-paren迁移时配置键与语义保持一致。对于仍在使用该内置规则的既有项目建议尽早规划迁移。何时不使用此规则如果你不关心函数括号前空格的一致性或者团队采用混合风格且不希望被约束可以关闭该规则。考虑到它属于纯排版规则、且已被标记弃用也可以直接改用stylistic/eslint-plugin的同名规则继续获得相同的检查能力。参考实现与测试规则源码lib/rules/space-before-function-paren.js含完整 schema、isNamedFunction/getConfigForFunction/checkFunction实现与自动修复逻辑规则测试tests/lib/rules/space-before-function-paren.js638 行覆盖字符串选项、对象选项组合、注释场景、async 箭头函数与自动修复的全部用例规则文档docs/src/rules/space-before-function-paren.md相关规则文档keyword-spacing。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考