- 插件的意义
eslint定义规则:插件允许你自定义规则,通过插件加入到eslint,确保团队成员遵守统一的代码约定,提高代码质量和可维护性- 支持特定技术栈:插件可以提供针对特定技术栈的规则和配置选项。
eslint-plugin-vue提供了用于 Vue.js 开发的规则 - 处理特定语言特性:插件可以添加针对特定语言特性的检查规则。
slint-plugin-import可以处理模块导入/导出相关的问题 - 提供辅助功能:插件可以为规则提供辅助功能,例如自动修复或给出更详细的错误消息。
- eslint插件中文文档 eslint.nodejs.cn/docs/latest…
- 举例
- 实现一个给每一个函数添加注释(注释模版 === 开发者名称,开发时间,函数描述)
// 使用eslint 规则修复和添加这个注释
/**
*
* @constructor
* @param {string} title - 名称
* @param {string} author - 作者
*
*/
function name(params) {
console.log(111)
}
- 初始化插件的开发环境
pnpm i -g yo
pnpm i -g generator-eslint
// 生成项目框架
yo eslint:plugin
- 填写一些基本信息,如下
yo eslint:rule
What is your name? 随便写个你的名字
What is the plugin ID? 你的插件的id,推荐(eslint-plugin-xxx)的命名方式
Type a short description of this plugin: 描述你的插件是干啥的
Does this plugin contain custom ESLint rules? Yes
Does this plugin contain one or more processors? No (这里我们用不到处理器,就直接选No)
- 创建一条规则
npx yo eslint:rule
├── README.md 这是你的插件的描述文档,包括如何安装使用等
├── docs
│ └── rules 这是你的自定义规则的描述文档
│ └── my-custom-rules1.md
├── lib 源码目录
│ ├── index.js 插件的入口
│ └── rules 这里放你的每一条自定义规则
│ └── my-custom-rules1.js
├── package.json
├── pnpm-lock.yaml
└── tests 测试目录
└── lib
└── rules
└── my-custom-rules1.js
- rule的格式
module.exports = {
// meta里面的元数据,对于我们自定义规则,其实只关心schema就行了
meta: {
// 规则的类型problem|suggestion|layout
// problem: 这条规则识别的代码可能会导致错误或让人迷惑。应该优先解决这个问题
// suggestion: 这条规则识别的代码不会导致错误,但是建议用更好的方式
// layout: 表示这条规则主要关心像空格、分号等这种问题
type: "suggestion",
// 对于自定义规则,docs字段是非必须的
docs: {
description: "描述你的规则是干啥的",
// 规则的分类,假如你把这条规则提交到eslint核心规则里,那eslint官网规则的首页会按照这个字段进行分类展示
category: "Possible Errors",
// 假如你把规则提交到eslint核心规则里
// 且像这样extends: ['eslint:recommended']继承规则的时候,这个属性是true,就会启用这条规则
recommended: true,
// 你的规则使用文档的url
url: "https://eslint.org/docs/rules/no-extra-semi"
},
// 标识这条规则是否可以修复,假如没有这属性,即使你在下面那个create方法里实现了fix功能,eslint也不会帮你修复
fixable: "code",
// 这里定义了这条规则需要的参数
// 比如我们是这样使用带参数的rule的时候,rules: { myRule: ['error', param1, param2....]}
// error后面的就是参数,而参数就是在这里定义的
schema: [],
// 信息模版
messages: {
noDescMessage: '请添加注释解析 方法名称为 {{ type }}',
}
},
create: function(context) {
// 这是最重要的方法,我们对代码的校验就是在这里做的
return {
// callback functions
};
}
};
- create
create方法接受一个context参数,用于提供规则执行所需的上下文信息。通过context对象,你可以访问到当前解析的代码的 AST(抽象语法树)、配置选项等。- 说下eslint 校验文件的流程
- 具体如何解析ast 语法书请看 astexplorer.net/
create方法的入参context
parserOptions-编译器选项,就是我们.eslintrc.js里的那个id-规则idoptions-通过这个可以拿到规则传进来的参数getFilename()-返回源文件文件名getScope()- 返回当前遍历节点的作用域getSourceCode()- 返回SourceCode对象,就是源码对象,很有用report()- 当校验不通过的时候,通过这个方法输出错误信息
- 注意这里你们可以自己在 vscode 上自己用 JavaScript Debug Terminal 调试代码
- 开始写我们上面eslint 插件
- 我写的这个插件是给每一个函数都想有一个注释解析,方便减轻后期维护人员的维护成本
- 判断每一个函数是不是都有注释
- 没有注释给一个提示
每一个函数都应该有自己的注释解析 - 可以提示修复(加上注释
功能描述,作者,参数名称,返回值说明)如下所示
/**
* 函数功能描述
* @desc { title } 作者
* @param {type} 参数名 参数说明
* @return {type} 返回值说明
*/
function name(params) {
}
- 具体插件实现
/**
* @fileoverview 添加注释
* @author eslint-plugin-desc
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion', // `problem`, `suggestion`, or `layout`
docs: {
description: "添加注释",
recommended: false,
url: null, // URL to the documentation page for this rule
},
fixable: 'code', // Or `code` or `whitespace`
schema: [], // Add a schema if the rule has options
messages: {
noDescMessage: '请添加注释解析 方法名称为 {{ type }}',
}
},
// eslint-disable-next-line no-unused-vars
/**
* 第一步获取 当前代码的前一步代码
* 第二部判断 代码有没有注释 没有注释加入注释 有注释判断下符合格式不
*
* @param {*} context
* @return {*}
*/
create(context) {
const sourceCode = context.getSourceCode();
function getFunctionParamsLoc(node) {
return {
start: node.loc.start,
};
}
return {
/**
*判断当前节点有没有 有 就进一步判断当前节点是不是type:Block
*
* @param {*} node
* @return {*}
*/
FunctionDeclaration(node) {
let FunctionDeclarationDesc = []
FunctionDeclarationDesc = sourceCode.getCommentsBefore(node)
if (!FunctionDeclarationDesc[0]) {
context.report({
node,
loc: getFunctionParamsLoc(node),
data: {
type: node.id.name
},
messageId: 'noDescMessage',
fix(fixer) {
return fixer.insertTextBefore(node, `/**
* 函数功能描述
* @desc { title } 作者
* @param {type} 参数名 参数说明
* @return {type} 返回值说明
*/
`)
}
})
}
},
};
},
};
- pnpm 构建本地测试环境
- 在刚写好的eslint插件同级目录下新建一个文件
eslint_test - 安装eslint
pnpm init
pnpm i eslint -D // 安装eslint
pnpm create @eslint/config //初始化eslint配置文件
pnpm i eslint-plugin-desc@workspace -W // 这里可以回报错 说没有什么根文件
- 新建
pnpm-workspace.yaml建好过后运行 在eslint_test文件下安装pnpm i eslint-plugin-desc@workspace -W
4. 在
eslint_test文件下的 .eslintrc.js 引入刚才写好的规则
module.exports = {
"env": {
"browser": true,
"es2021": true
},
// "extends": "eslint:recommended",
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": module
}
}
],
"parserOptions": {
"ecmaVersion": "latest"
},
// 用到的规则
"rules": {
'desc/eslint-plugin-desc': ['error']
},
// 插件名称
plugins: ['desc'],
}
- 新建index.js测试文件