一文带你搞懂Eslint 自定义规则那些事

162 阅读4分钟

一、什么是eslint自定义规则

ESLint 自定义规则是一种让你能够根据项目需求创建特定代码检查规则的机制。来帮助我们规范我们的代码。今天的例子就是通过一个规则来规范我们vue项目组件文件名必须是以短横线连接的形式:xx-xx-xx

二、目录结构

目录结构很简单lib下放的是index和rules。index.js内是入口文件,方便我们集中把我们自定义的规则暴露出去。rules文件下放置的是单独的自定义规则。当然我们还可以有相关规则的测试代码文件,本文暂未涉及。故没有。需要注意的是package.json文件是必须的,因为我们需要发包到npm,执行npm init 即可生成该文件。

├── README.md 这是你的插件的描述文档,包括如何安装使用等
├── lib 源码目录
│   ├── index.js 插件的入口
│   └── rules 这里放你的每一条自定义规则
│       └── xxx-xxx-xxx.js
├── package.json

三、自定义一个检查文件名是否以短横线连接的规则

3.1 模板

首先,eslint为我们定制化了规则模板,我们按照模板规则补充我们自己相应的逻辑即可

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: "xxxx"
        },
        // 标识这条规则是否可以修复,假如没有这属性,即使你在下面那个create方法里实现了fix功能,eslint也不会帮你修复
        fixable: "code",
        // 这里定义了这条规则需要的参数
        // 比如我们是这样使用带参数的rule的时候,rules: { myRule: ['error', param1, param2....]}
        // error后面的就是参数,而参数就是在这里定义的
        schema: []
    },
    create: function(context) {
        // 这是最重要的方法,我们对文件名的检查就是在这里做的
        return {
            // callback functions
        };
    }
};

3.2 检查文件名是否以短横线连接的规则


module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: '强制文件名使用 kebab-case 格式',
      category: 'Possible Errors',
      recommended: true,
    },
    fixable: null,
  },
  create: function (context) {
    return {
      Program: function (node) {
        const filename = context.getFilename();
        if (!filename.endsWith('.vue')) return; // 只检查 .vue 文件

        const nameWithoutExtension = filename.split('/').pop().split('.').slice(0, -1).join('.');
        const kebabCaseRegex = /^[a-z]+(-[a-z]+)*$/;
        if (!kebabCaseRegex.test(nameWithoutExtension)) {
          context.report({
            node: node,
            message: 'Vue 文件名应该使用短横线连接的小写字母 (kebab-case)。',
          });
        }
      },
    };
  },
};

3.3 入口文件


/**
 * @fileoverview 校验文件是否是短横线连接
 */
 
'use strict';

module.exports = {
  rules: {
    // 项目在使用时,对应的规则名称
    'kebab-case-filename': require('./rules/kebab-case-filename'),
  },
  configs: {
    recommended: {
      rules: {
        'rules/kebab-case-filename': 'error'
      },
    },
  },
};

四、自定义规则的使用

上述就是我们自定义一个eslint规则,再次之后,我们就可以发布了。

  • 执行npm login
  • 登录后执行 npm publish
  • 发布成功后,我们可以通过在项目内通过npm install xxx(我们发的包名)

之后我们需要在项目的eslint配置文件内使用该规则.

需要注意的是,我们的包名通常会是eslint-plugin-xx-rules.


// .eslintrc.js
module.exports = {
    // 你的插件
    plugins: ['xx-rules'], //这里就是包名 忽略掉前边的eslint-plugin-
    rules: {
        'xx-rules/kebab-case-filename':'error' //这里就是插件名/rules下的具体规则名字
    },
};

五、ending

上述我们自定义规则的一套流程就完成了,值得一提的是,有些小伙伴想在把规则写在项目内,直接在本地引入使用。我也尝试过此类想法,遗憾的是,这种想法没有实现,会有各类eslint的错误。找不到我们自定义的规则。折腾一天,尝试了网上的各种办法,最终都是行不通的,没有解决办法,所以采用了发包形式。这种方式也有优点,发包之后可以再不同项目内使用。本地引用的方式如果有小伙伴有实现方式欢迎讨论。