为 ESLint 编写本地规则
ESLint 是一款很棒的工具,它让我能够遵循既定的代码规范和语法原则,编写出更优质的代码。然而,你可能会遇到一些情况,即现有的 ESLint 包和规则无法正常工作(例如,由于某些业务需求,你的代码需要替换)。几周前,我就遇到了这种情况。
我需要创建一个 ESLint 规则,将一个字符串(包的导入语句)替换成另一个字符串(我自定义的)。这看起来似乎很简单。于是,我做了所有开发者可能都会做的事:搜索“ESLint 替换导入语句”,结果却发现找不到任何相关的资源,这让我大吃一惊。也许是我搜索的方式不对,或者相关的文章或文档已经存在,总之,我只能靠猜测(JavaScript 也帮不上忙)自己编写了以下代码。
因此,您将在下面看到一个代码示例,这是一个本地 ESLint 规则,允许您将一个导入语句替换为另一个导入语句(由您定义)。
代码
首先,我们来安装一个允许我们编写本地规则的软件包:
yarn add --dev eslint-plugin-local-rules # npm install --save-dev eslint-plugin-local-rules
这将允许我们编写本地规则,而无需将其发布为 npm 包。
接下来,我们把它添加到插件数组中。
// .eslintrc.js
module.exports = {
plugins: ['eslint-plugin-local-rules'],
};
现在,我们来看一下本地规则本身。这是教程代码中最大的部分,所以我将尝试逐步解释每个部分,以便您能理解我当初通过猜测验证的内容 :D。最后,您将看到一个完整的文件,其中包含本地规则正常运行所需的所有声明。
首先,在文件顶部你会看到一个module.exports,里面有一个名为 的字符串键replace-bad-import。这是你的本地规则的名称,稍后会在 eslintrc 文件中用到。
// eslint-local-rules.js
module.exports = {
'replace-bad-import': {},
};
在元配置中,我们可以定义本地模块的信息,例如描述、类别等。这种方式信息量更大,所以目前来说并不那么重要。
// eslint-local-rules.js
module.exports = {
'replace-bad-import': {
meta: {
fixable: "code",
docs: {
description: 'My awesome ESLint local rule that will replace an import declaration with something else',
category: 'Possible Errors',
recommended: false,
},
schema: [],
},
},
};
现在,进入本地规则的最后一部分,即create方法:
// eslint-local-rules.js
module.exports = {
'replace-bad-import': {
create(context) {
return {
ImportDeclaration(node) {
if(node.source.value.includes('bad-import-declaration')) {
context.report({
node,
message: 'Use proper import',
fix: fixer => fixer.replaceText(node, node.specifiers.map(specifier =>`import ${specifier.local.name} from 'good-import-declaration';`,).join('\n'))
});
}
},
};
},
},
};
让我们一步一步地来看一下这里的所有东西:
create该方法将接受一个context参数,该参数稍后将用于创建有关已发现问题的报告。- 此方法将返回一条新
ImportDeclaration规则。如果您想了解其他规则,请查看官方文档。 - 我们正在检查某个节点导入是否包含查询(在本例中
bad-import-declaration)。 - 在这个 if 语句中,我们通过调用上下文对象中的一个方法来生成一份新报告,并传递以下参数:
node:触发该规则的实际节点(类似堆栈跟踪)位置message:运行规则并发现问题后应显示的消息。fix:一个用于修复导入语句的修复方法。在本例中,该方法使用一个fixer参数,然后fixer调用此方法replaceText,传入当前节点和一个应该替换该节点的新值。
下面显示的是该规则的完整代码:
// eslint-local-rules.js
module.exports = {
'replace-bad-import': {
meta: {
fixable: "code",
docs: {
description: 'My awesome ESLint local rule that will replace an import declaration with something else',
category: 'Possible Errors',
recommended: false,
},
schema: [],
},
create(context) {
return {
ImportDeclaration(node) {
if(node.source.value.includes('bad-import-declaration')) {
context.report({
node,
message: 'Use proper import',
fix: fixer => fixer.replaceText(node, node.specifiers.map(specifier =>`import ${specifier.local.name} from 'good-import-declaration';`,).join('\n'))
});
}
},
};
},
},
};
最后一步是将我们的规则添加到.eslintrc.js文件中。
// .eslintrc.js
module.exports = {
rules: {
'local-rules/replace-bad-import': 'warn',
},
};
如果我们正确地执行了以下所有步骤:
应替换为如下所示的内容:
概括
做得好!您刚刚创建了一条本地 ESLint 规则,可以将一段文本替换为另一段文本。请记住,这只是 ESLint 强大功能的冰山一角,但这应该能为您构建本地规则打下坚实的基础。
文章来源:https://dev.to/jacobandrewsky/writing-local-rules-for-eslint-58bl


