翻译自 《How To Write Your First ESLint Plugin》
推荐理由:言简意骇,是我入门ESLint的启蒙文章👍
本文是ESLint插件(Plugins)的简单介绍指南,包括它们是如何工作的,如何配置、编写和如何使用一个插件的。
什么是ESLint插件
它是ESLint的一个外部拓展,强制执行一些规则(rules),不是写在ESLint核心(core)里的。举个例子,大家都比较熟悉的插件eslint-plugin-babel支持了ESLint核心中没有的实验性功能和linter(改进代码的工具)。🚩插件通常存储为单独的NPM模块,它导出rule对象,其中key是规则名称,value是另一个具有强制执行规则方法的对象:🚩
module.exports = {
rules: {
"rule-name": {
create: function (context) {
// rule implementation ...
}
}
}
};
为什么你需要关心自己去写一个?
NPM已现存有非常多的插件,找到你需要的插件的概率会很高。但是在某些情况下,你可能需要针对你的代码库制定非常具体的规则。
最近,我们的开发团队决定强制执行关于异步函数的命名规范。这意味着,如果某个函数返回一个promise或有一个async声明前缀,那么这个函数命名必须有一个固定Async后缀:function someFunctionAsync()。
让我们以此为例,编写一个可以警告函数命名错误的ESLint插件,
创建一个插件
在本教程中,我们将创建一个本地插件包并在简单的node应用中使用。项目结构如下所示:
plugin-tutorial
│
└───my-eslint-rules
│ │ package.json
│ │ index.js
│
└───node-app
│ package.json
│ index.js
首先创建主文件夹 mkdir plugin-tutorial && cd plugin-tutorial
配置插件包
每一个有效的插件都应该满足以下条件:
- 单独的NPM包
- 遵循
eslint-plugin-<plugin-name>的命名格式 - 导出
rules对象
- 创建插件项目(plugin package):
mkdir my-eslint-rules && cd my-eslint-rules && npm init --yes - 在
package.json中为其命名:{ "name": "eslint-plugin-my-eslint-rules" } - 创建
index.js入口文件并导出自定义规则rules对象,暂命名为async-func-name:
module.exports = {
rules: {
"async-func-name": {
create: function (context) {
return { /* ...rule methods */ }
}
}
}
};
编写rule规则对象
为了构建和测试规则,我们将使用一个工具AST explorer。
AST代表抽象语法树或者语法书,它是源代码的抽象语法结构的树状表现形式。 [注1]
将AST Explorer的解析器(parser)设置为eslint-babel和转换器(transformer)设置为ESLint v4。
现在在资源管理器中可以看到四个窗口:
- 左上角的窗口将用于编写源代码(source code)
- 右上角的窗口是源代码的资源管理器。将鼠标悬停在表达式上时,你可以看到代码中突出显示的部分
- 左下角就是我们要调试编辑的规则代码
- 右下角是规则后的输出,与源代码同步更新运行
https://astexplorer.net/
规则函数会接受一个参数为context的对象,该对象包含了关于规则上下文相关的附加功能和信息。
主要方法是context.report(),
你将使用的主要方法是 context.report(),它用来发布警告或错误(取决于你所使用的配置)。该方法只接收一个参数,是个对象,包含以下属性:message,node, loc, data, fix [注2]
最简单的示例是只使用 node 和 message:
context.report({
node: node,
message: "Async function name must end in 'Async'"
});
该规则必须返回一个对象,其中包含ESLint再遍历源代码语法树时调用的visitor节点的方法。
在我们的示例中,有一个方法FunctionDeclaration,它接受一个node对象参数,该节点对象包含了函数信息,例如type(类型)、name(名称)、body(主体)、locations(每个值的位置)。
要检查函数名称是否具有Async后缀,我们需要访问名称,该名称位于FunctionDeclaration节点的id对象中:node.id.name
所以规则的主要逻辑应该是检查函数是否有async属性,如果不包含Async后缀,则调用context.report()方法。
应用规则后,AST explorer输出警告消息:
rule function
在资源管理器中编写规则并确保它捕获到正确的规则条件后,将逻辑代码复制到插件包的index.js中,即完成插件:
module.exports = {
rules: {
"async-func-name": {
create: function (context) {
return {
FunctionDeclaration(node) {
if (node.async && !/Async$/.test(node.id.name)) {
context.report({
node,
message: "Async function name must end in 'Async'"
});
}
}
}
}
}
}
};
将插件应用到项目中
首先,项目需要这样配置:
- 从
plugin-tutorial执行命令mkdir node-app && cd node-app && npm init --yes && touch index.js,并将AST explorer中的实例代码加入到index.js中:
async function myFunction() {
return "";
}
- 安装ESLint依赖
npm i eslint --save-dev - 安装刚刚创建的插件:
npm i ../my-eslint-rules --save-dev - 通过创建配置文件
.eslintrc告诉应用程序需要使用到的ESLint规则与插件
{
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"my-eslint-rules/async-func-name": "warn"
},
"plugins": ["my-eslint-rules"]
}
- 在项目应用程序文件夹中打开终端并运行ESLint命令:
./node_modules/.bin/eslint index.js
差不多就是这样。如何您为异步函数设置了错误的名称,您应该在终端中运行它后看到ESLint警告。
在项目中使用插件的重要部分是.eslintrc配置文件。插件的命名规则应该遵循"<plugin-name>/<rule-name>": [warn/error]。插件名称应添加到数组plugins字段中。












网友评论