如何配置ESLint规则以实现将函数统一放在末尾且支持--fix自动修复?
实现方案
可以实现该需求,ESLint暂无内置对应规则,你可以通过编写自定义规则达成效果,且完全支持--fix自动修复能力。
规则核心逻辑
利用函数声明存在变量提升的特性,规则只处理function关键字开头的函数声明(不处理箭头函数、函数表达式赋值场景),针对每个作用域(顶层作用域、块级作用域、函数内部作用域)执行以下逻辑:
- 收集当前作用域内所有的函数声明节点
- 校验所有函数声明是否都位于当前作用域内其他可执行代码的后方
- 不符合规则的场景触发报错,自动修复时将收集到的函数声明按原有顺序统一移动到对应作用域的末尾
自定义规则示例代码
module.exports = { meta: { fixable: 'code', type: 'layout', }, create(context) { const sourceCode = context.getSourceCode() function checkScope(scope) { const funcDeclarations = [] const otherStatements = [] // 遍历当前作用域的顶级语句 scope.block.body.forEach(statement => { if (statement.type === 'FunctionDeclaration') { funcDeclarations.push(statement) } else { otherStatements.push(statement) } }) // 已经符合要求就跳过 if (funcDeclarations.length === 0 || otherStatements.length === 0) return const firstFuncIndex = scope.block.body.findIndex(s => s.type === 'FunctionDeclaration') const lastOtherIndex = scope.block.body.findLastIndex(s => s.type !== 'FunctionDeclaration') if (firstFuncIndex < lastOtherIndex) { context.report({ node: scope.block, message: '所有函数声明必须放在当前作用域的末尾', fix(fixer) { const newBody = [ ...otherStatements.map(s => sourceCode.getText(s)), ...funcDeclarations.map(f => sourceCode.getText(f)) ].join('\n') return fixer.replaceTextRange(scope.block.body.range, newBody) } }) } // 递归检查子作用域 scope.childScopes.forEach(checkScope) } return { Program() { checkScope(context.getScope()) } } } }
配置方法
- 将上述代码保存为ESLint自定义规则文件,比如
rules/function-declaration-at-end.js - 在ESLint配置文件中引入自定义规则并开启:
{ "rules": { "your-custom/function-declaration-at-end": "error" } }
配置完成后执行eslint --fix即可自动将所有函数声明移动到对应作用域的末尾,和需求给出的正确示例效果完全一致。
提示:如果需要兼容
export function这类带导出的函数声明,只需在规则的节点判断逻辑中额外匹配导出类型节点即可,可根据业务场景灵活调整。
内容的提问来源于stack exchange,提问作者Luke Miles
相关产品推荐
相关产品推荐

