当前位置:   article > 正文

自定义ESLint规则和修复功能_eslint 只修复更改的代码

eslint 只修复更改的代码

这是接上一篇自定义ESLint规则开发与使用的后续扩展,之前文章中详细讲述了怎么创建一个自定义的规则,这篇文章讲述怎么实现ESLint在检测出有问题的代码时,怎么自动fix问题。
比如我们要检测项目中所有http的协议,将其替换为https协议。增加网页的安全性。

项目准备

所用的示例也是和上一篇文章中是一个项目。先进入eslint-plugin-demo的文件夹,使用脚手架回答一些交互式问题,建立ESLint规则文件.
在这里插入图片描述
在这里插入图片描述

创建link

我们在开发npm包的过程中,可以使用npm link将开发的包link到全局上,这样应用工程就可以直接使用了。具体详情请看npm link

我们在 eslint-plugin-diylint 根目录下执行 npm link。可以看到已近建立了全局的软连了
在这里插入图片描述
再cd到demo-app中直接npm link eslint-plugin-diylint 就可以在demo-app/node_modules安装eslint-plugin-diylint 这个插件了,我们可以直接在原文件(node_modules中customer-eslint-demo/eslint-plugin-demo/lib/rules/no-http-protocol.js)中打断点,直接调试会自动映射到node_modules对应的文件中,调试起来非常的方便。

规则实现

在这里插入图片描述
通过解析之后,我们选择’VariableDeclaration VariableDeclarator’作为visitor 来获取变量和变量的值。
将no-http-protocol.js中内容改为如下:

/**
 * @fileoverview 不可使用http协议
 * @author yjian
 */
"use strict";
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
  meta: {
    type: 'problem', // `problem`, `suggestion`, or `layout`
    docs: {
      description: "不可使用http协议",
      recommended: false,
      url: null, // URL to the documentation page for this rule
    },
    fixable: null, // Or `code` or `whitespace`
    schema: [], // Add a schema if the rule has options
    // 报错信息描述
    messages: {
      avoidHttpProtocol: "'{{name}}' value avoid using http protocol.",
    },
  },
  create(context) {
    return {
      // visitor functions for different types of nodes
      'VariableDeclaration VariableDeclarator': (node) => {
        if (node.init && node.init.value && node.init.value.includes('http://')) {
          context.report({
            node,
            messageId: 'avoidHttpProtocol',
            data: {
                name: node.id && node.id.name,
            },
          });
        }
      }
    };
  },
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

rules/index.js中内容改为如下:

/**
 * @fileoverview 自定义eslint规则
 * @author yjian
 */
"use strict";

// import all rules in lib/rules
module.exports = {
  rules: {
        // 项目在使用时,对应的规则名称
      'no-console-error': require('./rules/no-console-error'),
      'no-http-protocol': require('./rules/no-http-protocol'),
  },
  configs: {
      recommended: {
          rules: {
              'demo/no-console-error': 2, // 可以省略 eslint-plugin 前缀
              'demo/no-http-protocol': 2,
          },
      },
  },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

规则使用

在demo-app/eslintrc.json中开启该规则

{
    "env": {
        "browser": true,
        "es2021": true
    },
    "plugins": [
        // 这是此前使用yo eslint:plugin 生成自定义插件的ID
        "diylint"
    ],
    "extends": "standard",
    "overrides": [
    ],
    "parserOptions": {
        "ecmaVersion": "latest"
    },
    "rules": {
        "diylint/no-console-error": 2,
        // 不能使用http协议
        "diylint/no-http-protocol": 2
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

然后重新加载一下vscode,发现我们自定义的lint已近发挥作用,检测出使用http协议的地方了。

在这里插入图片描述
然后我们下一步添加一个自动修改的功能,将使用http协议的全部自动改成https的

ESLint 自动修改

meta 修改

将meta中的fixable的值改为code, 这样在命令行上加上-- fix 参数就会自动修复该问题
在这里插入图片描述

实现fix函数

我们需要再content.report传入的对象参数中,实现一个fix的函数。

context.report({
            node,
            messageId: 'avoidHttpProtocol',
            data: {
                name: node.id && node.id.name,
            },
            fix(fixer) {
              console.log(fixer.insertTextAfter);
              return fixer.replaceText()
            }
          });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我们可以看到fixer中有这些方法。
在这里插入图片描述
这些方法归为三类

  • 增:insertTextAfter、insertTextAfterRange、insertTextBefore、insertTextBeforeRange
  • 删:remove、removeRange
  • 改:replaceText、replaceTextRange

我们在这里需要将原来的http:修改为https:即可,所以使用的是replaceText方法
整个代码入下:

'VariableDeclaration VariableDeclarator': (node) => {
        if (node.init && node.init.value && node.init.value.includes('http://')) {
          // 将http:修改为 https:
          const httpsProtocal = node.init.value.replace(/http:/g, 'https:');
          context.report({
            node,
            messageId: 'avoidHttpProtocol',
            data: {
                name: node.id && node.id.name,
            },
            fix(fixer) {
             return fixer.replaceText(node.init, `'${httpsProtocal}'`)
            }
          });
        }
      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述
在此之前我们再对应的代码处选择快速修复的话,只有上图两个选项是通过改规则的。而没有对应的按照该规则自动修改代码的选项。我们实现上面的方法之后就有了自动修复的选项了,就会按照上面fix函数的逻辑去修复对应的代码。
在这里插入图片描述

效果如下所示:
请添加图片描述
或者在使用命令行加–fix 也是一样的。效果如下:

请添加图片描述
至此我们就完成了一个完整的自定义ESLint规则的编写和自动修复。

参考资料

ESLint 中文文档
ESLint英文文档
AST在线解析
AST语法解析(查看node & token)
ESLint创建规则-中文
ESLint创建规则-英文
RuleTester-中文文档
Babel解析AST 节点

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号