Vue 项目中使用 ESLint 和 Prettier 偏难怪的超深度解析

ESlint 是一种用于识别和报告在Javascript代码中发现的格式错误的工具,其目标是使代码更加一致并避免错误。它类似于JSlint和JSHint,但还有点区别:

  1. ESlint 使用 Espree进行JavaScript解析;

  2. ESlint 使用 AST 来评估代码中的模式;

  3. ESlint 是完全可插拔的,每一条规则都是一个插件,你可以运行时添加更多;

我一开始认为 ESlint 和 webpack 有关系,实则两者是平行关系,ESlint 是可执行的命令行,通 webpack 是一样的,一开始只能对后缀.js 的文件进行处理,之后安装插件后,就能对其他文件进行处理了,这里就.vue 文件的处理插件做下解释说明:

注意:

eslint 中 extends 就像 jquery 中的 extends 一样是用来合并 eslint 中的 plugins,rules 的,碰到子配置中有 extends 会进行递归解构,不断地合并到 plugins 和 rules 两个大字段中;最后处理代码时,extends 字段是没啥作用的;如果 extends 没有路径,只是当前插件的名称,则意味着是将当前插件的 rules 作为最后一个合并对象,用来覆盖之前的所有的配置的意思;官网没有给出明确的

Vue 项目中使用 ESLint 和 Prettier - 知乎

插件中的处理器:

是用来针对不同文件做出响应的配置,细节不用深究,我们又不写 eslint 插件;

一个处理器有前置操作 preprocess 和后置操作 postprocess;

Working with Plugins - ESLint - Pluggable JavaScript linter

module.exports = {
    processors: {
        "processor-name": {
            // takes text of the file and filename
            preprocess: function(text, filename) { 
                // here, you can strip out any non-JS content
                // and split into multiple strings to lint

                return [ // return an array of code blocks to lint
                    { text: code1, filename: "0.js" },
                    { text: code2, filename: "1.js" },
                ];
            },

            // takes a Message[][] and filename
            postprocess: function(messages, filename) {
                // `messages` argument contains two-dimensional array of Message objects
                // where each top-level array item contains array of lint messages related
                // to the text that was returned in array from preprocess() method

                // you need to return a one-dimensional array of the messages you want to keep
                return [].concat(...messages);
            },

            supportsAutofix: true // (optional, defaults to false)
        }
    }
};

以文件扩展名命名的处理器

不以扩展名命名的处理器,理论上每个文件,js 的和非 js 的都会走这个处理器;如果以扩展名命名的,那么只有该扩展名的文件才会走该处理器。

如果处理器名称以 . 开头,则 ESLint 将处理器特别作为以文件扩展名命名的处理器处理,并自动将处理器应用于文件类型。人们不需要在他们的配置文件中指定以文件扩展名命名的处理器。

module.exports = {
    processors: {
        // This processor will be applied to `*.md` files automatically.
        // Also, people can use this processor as "plugin-id/.md" explicitly.
        ".md": {
            preprocess(text, filename) { /* ... */ },
            postprocess(messageLists, filename) { /* ... */ }
        }
    }
}

eslint-plugin-vue 插件的配置截图如下:

这样插件就能处理.vue 结尾的文件了

Vue 项目中使用 ESLint 和 Prettier 偏难怪的超深度解析_第1张图片

如何使用插件?

Plugins - ESLint - Pluggable JavaScript linter

{
    // 第一步 注入插件
    "plugins": [
        "jquery",   // eslint-plugin-jquery
        "@foo/foo", // @foo/eslint-plugin-foo
        "@bar"      // @bar/eslint-plugin
    ],
    "extends": [
      	// 第二步 注入插件的推荐配置信息,该配置信息的key就叫recommend
        "plugin:@foo/foo/recommended", // 这就是寻找插件配置的约定ESlint约定格式
        "plugin:@bar/recommended"
    ],
    "rules": {
        "jquery/a-rule": "error",
        "@foo/foo/some-rule": "error", // 第三步 设置插件下某规则的错误级别
        "@bar/another-rule": "error"
    },
    "env": {
        "jquery/jquery": true,
        "@foo/foo/env-foo": true,
        "@bar/env-bar": true,
    }
    // ...
}

插件中的配置

// eslint-plugin-myPlugin

module.exports = {
    configs: {
        myConfig: {
            plugins: ["myPlugin"],
            env: ["browser"],
            rules: {
                semi: "error",
                "myPlugin/my-rule": "error",
                "eslint-plugin-myPlugin/another-rule": "error"
            }
        },
        myOtherConfig: {
            plugins: ["myPlugin"],
            env: ["node"],
            rules: {
                "myPlugin/my-rule": "off",
                "eslint-plugin-myPlugin/another-rule": "off",
                "eslint-plugin-myPlugin/yet-another-rule": "error"
            }
        }
    }
};

以上配置如何引入到 eslint 中?

{
    "extends": ["plugin:myPlugin/myConfig"] 
    // 看到这里是不是知道recommend的是怎么来的了吗?就是一个推荐配置
  	// 我一开始还以为是command(命令)英语不好,总是会误导思维
  	// 强化计算级专业英语还是比较重要的
}

至此我们来分析下@vue/eslint-config-prettier 这个插件的引入

根据扩展配置的前缀去除法,引入@vue/eslint-config-prettier 可以简写为@vue/prettier

因此,eslintrc.js 中是这样写的

module.exports = {
  root: true,

  env: {
    node: true,
    webextensions: true,
  },

  extends: [
    'plugin:vue/essential', 
    'eslint:recommended', 
    '@vue/prettier' // 这个跳跃性是不是很大,一般人都看不懂点也点不进去
  ],

  parserOptions: {
    parser: 'babel-eslint',
  },

  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'off' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    quotes: ['warn', 'single', 'avoid-escape'],
    semi: ['error', 'never']
  },
}

根据 npm package.json 导出机制我们知道 export 的文件是 index.js,让我们来看看它干了啥

Vue 项目中使用 ESLint 和 Prettier 偏难怪的超深度解析_第2张图片

我们看看 index.js 有啥?

module.exports = {
  plugins: ['prettier'], //
  extends: [
    require.resolve('eslint-config-prettier'),
    require.resolve('eslint-config-prettier/vue') // 这里引入了vue配置
  ],
  rules: {
    'prettier/prettier': 'warn'
  }
}

纳尼?vue 的处理插件怎么没看到?

Vue 项目中使用 ESLint 和 Prettier 偏难怪的超深度解析_第3张图片

根据 eslint-plugin-可省略原则,所以 vue/essential 全称应该是 eslint-plugin-vue/essential,essential 单词的意思是基本的,不可或缺的,这里是不是让你想骂爹,摆明不让你看懂的节奏

Vue 项目中使用 ESLint 和 Prettier 偏难怪的超深度解析_第4张图片

看到这里,就基本清晰了

总结

eslint 引用 vue 插件和 prettier 插件,并且将两者的一些配置进行了合并,避免了冲突,这样就可以让 eslint 碰到 vue 时用 eslint-plugin-vue 插件处理 vue,碰到 js 时用 @vue/prettier 处理 js 的格式,并且使得两者规则不冲突,@vue/prettier 还是 prettier 插件,只不过增加了一些 rules,来保证跟 eslint-plugin-vue 以及 eslint 自身的规则不冲突,所以这个规则要放在最后;

你可能感兴趣的:(Javascript,vue.js,javascript,jquery)