美文网首页前端大宝剑React.js
08-使用Eslint和Editorconfig规范代码

08-使用Eslint和Editorconfig规范代码

作者: 七玄之主 | 来源:发表于2019-07-01 16:46 被阅读15次

    对于正规的团队开发,需要规定统一的编码规范,格式化规范,以便于后期的维护。

    Eslint

    Eslint 是可组装的JavaScript和JSX检查工具,可以通过添加对应的插件来增加对应的javascript代码检测。

    直接运行命令yarn add -D eslint eslint-loader安装。

    在安装eslint相关包过程中出现如下警告

    warning " > eslint-loader@2.1.2" has incorrect peer dependency "eslint@>=1.6.0 <6.0.0".
    

    表示了我们这里安装的eslint包不适用于eslint-loader插件。具体分析请参考 外传系列-各种疑难杂症

    这里我们直接卸载 eslint,安装yarn add -D eslint@5.16.0即可消除此警告。

    接着我们在根目录下新增.eslintrc.js 配置eslint的检测规则。.eslintrc.js包括以下配置项:

    • rules 启用的规则及其各自的错误级别,详细可以参考 eslint规则
    • parser 配置解释器,默认为 Espree,我们也可以配置 babel-eslint 作为解释器。
    • parserOptions 解析器选项,能帮助 ESLint 确定什么是解析错误。
    • env 指定想启用的环境,并设置它们为 true。
    • globals 定义全局变量,这样源文件中使用的全局变量就不会发出警告。
    • plugins 配置第三方插件,插件名称可以省略 eslint-plugin- 前缀。
    • settings 添加共享设置,提供给每一个将被执行的规则。
    • root 设置为 true,停止在父级目录中查找。
    • extends 可以从基础配置中继承已启用的规则。
    • overrides 可以实现精细的配置,比如,如果同一个目录下的文件需要有不同的配置。

    大概就是如下图所示这种感觉了。要深入了解请参考 官方文档

    module.exports = {
        // 停止在父级目录中查找
        "root": true,
        // 启用一系列核心规则
        "extends": "eslint:recommended",
        // 启用的规则及其各自的错误级别
        "rules": {
            "semi": ["error", "always"],
            "quotes": "error",
            // 启用插件专用的规则
            "example-plugin/eqeqeq": "off"
        },
        // 解析器选项
        "parserOptions": {
            // ECMAScript 版本
            "ecmaVersion": 6,
            // 设置为 "script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)
            "sourceType": "module",
            // 使用的额外的语言特性
            "ecmaFeatures": {
                // 启用 JSX
                "jsx": true
            }
        },
        // 一个对Babel解析器的包装,使其能够与 ESLint 兼容
        "parser": "babel-eslint",
        // 全局变量
        "globals": {
            "document": false,
            "window": false,
            "HTMLInputElement": false,
            "HTMLDivElement": false,
            "localStorage": true
        },
        // 指定想启用的环境
        "env": {
            "browser": true,
            "commonjs": true,
            "es6": true,
            "jest": true,
            "node": true,
            // 指定插件专用环境
            "example-plugin/browser": true
        },
        // 配置插件
        "plugins": [
            "example-plugin"
        ],
        // 匹配特定的 glob 模式的文件
        overrides: {
            // 匹配所有.ts .tsx 文件
            files: ['**/*.ts', '**/*.tsx'],
            // 指定解析器
            parser: '@typescript-eslint/parser',
            // 指定解析器选项
            parserOptions: {
              ecmaVersion: 2018,
              sourceType: 'module',
              ecmaFeatures: {
                jsx: true,
              }
            }
        }
    }
    

    自己重新定义eslint 的配置太累,我们可以以共享的配置 为基础,来扩展我们自己的配置,这样最省力,不干重复造轮子的事情。

    本来想直接使用create react app 脚手架所自带的eslint-config-react-app,网上找了下发现这个还不错,打包了格式化插件 prettier,又省事了。
    @stinkstudios/eslint-config-react-app

    按照指南执行如下命令

    yarn add @stinkstudios/eslint-config-react-app babel-eslint@10.x eslint@5.x eslint-config-prettier@4.x eslint-plugin-compat@3.x eslint-plugin-import@2.x eslint-plugin-jest@22.x eslint-plugin-jsx-a11y@6.x eslint-plugin-react@7.x eslint-plugin-unicorn@6.x @typescript-eslint/eslint-plugin@1.x @typescript-eslint/parser@1.x -E -D
    

    安装完成以后,修改 .eslintrc.js 配置

    {
      "extends": "@stinkstudios/eslint-config-react-app"
    }
    

    vscode 安装对应的 eslintprettier 插件后,添加如下配置

    {
        // 开启eslint对javascript文件的检查
        "eslint.enable": true,
        // 开启保存文件时是否启用eslint规则自动修改
        "eslint.autoFixOnSave": true,
        // 配置eslint验证的语言
        "eslint.validate": [
            "javascript",
            "javascriptreact",
            {
                "language": "typescript",
                "autoFix": true
            },
            {
                "language": "typescriptreact",
                "autoFix": true
            }
        ],
        // 关闭保存时格式化文件
        "editor.formatOnSave": false,
        // 开启js文件自动保存格式化
        "[javascript]": {
            "editor.formatOnSave": true
        },
        // 开启jsx文件自动保存格式化
        "[javascriptreact]": {
            "editor.formatOnSave": true
        },
        // 开启ts文件自动保存格式化
        "[typescript]": {
            "editor.formatOnSave": true
        },
        // 开启tsx文件自动保存格式化
        "[typescriptreact]": {
            "editor.formatOnSave": true
        },
        // 开启prettier使用eslint的代码格式进行校验
        "prettier.eslintIntegration": true
    }
    

    这样打开相应的源代码,会出现对应的警告和错误提示


    如果我们想再编译时执行检查,需要另外安装yarn add -D eslint-loader

    并在webpack中添加对应的配置

    // 配置项目处理的不同文件及模块
        module: {
            rules: [
                {
                    test: /\.(ts|tsx|js|jsx)$/,
                    exclude: /node_modules/,
                    include: path.resolve(__dirname, "src"),
                    use: {
                        loader: 'babel-loader'
                    }
                },
                {
                    enforce: 'pre',
                    test: /\.(ts|tsx)$/,
                    exclude: /node_modules/,
                    include: path.resolve(__dirname, "src"),
                    loader: 'eslint-loader',
                },
            ]
        }
    

    enforce: 'pre'保证了,eslint 检查的源代码是在 babel 编译前的代码文件。再执行编译后,控制台输出需要解决的错误与警告。

    yarn run v1.16.0
    $ webpack --config webpack.prod.js
    Hash: 3b26a80a14e418556fee
    Version: webpack 4.35.0
    Time: 18915ms
    Built at: 2019-07-02 5:05:38 PM
     12 assets
    Entrypoint main = manifest.main.f8d73da419e4743861f3.js manifest.main.f8d73da419e4743861f3.js.map verdor.40b18c99978b06ccfb59.js verdor.40b18c99978b06ccfb59.js.map main.2d6862e337695d1c7c2d.js main.2d6862e337695d1c7c2d.js.map
      [5] ./src/constants.ts 348 bytes {1} [built]
      [6] ./node_modules/history/esm/history.js + 2 modules 30.6 KiB {0} [built]
          |    3 modules
     [11] ./node_modules/react-router/esm/react-router.js + 1 modules 27.7 KiB {0} [built]
          |    2 modules
     [30] ./node_modules/react-redux/es/index.js + 15 modules 28.8 KiB {0} [built]
          |    16 modules
     [33] (webpack)/buildin/global.js 472 bytes {0} [built]
     [39] ./node_modules/connected-react-router/esm/index.js + 5 modules 13.3 KiB {0} [built]
          |    6 modules
    [109] (webpack)/buildin/harmony-module.js 573 bytes {0} [built]
    [131] ./src/index.tsx + 7 modules 14 KiB {1} [built] [7 errors]
          | ./src/index.tsx 187 bytes [built]
          | ./src/containers/App.tsx 4.01 KiB [built] [1 error]
          | ./src/store/configureStore.ts 915 bytes [built] [1 error]
          | ./src/containers/Top.tsx 2.72 KiB [built] [1 error]
          | ./src/containers/ErrorBoundary.tsx 3.3 KiB [built] [1 error]
          | ./src/reducers/novel.ts 1.67 KiB [built] [1 error]
          | ./src/middleware/index.ts 503 bytes [built] [1 error]
          |     + 1 hidden module
    [134] ./node_modules/redux-actions/es/handleActions.js + 13 modules 7.25 KiB {0} [built]
          |    14 modules
    [135] ./node_modules/redux-actions/es/createAction.js + 1 modules 1.43 KiB {0} [built]
          |    2 modules
    [136] ./src/containers/About.tsx 141 bytes {3} [built] [1 error]
    [137] ./src/containers/MaterialUI.tsx 2.76 KiB {4} [built] [1 error]
    [138] ./src/containers/NovelContainer.tsx + 4 modules 5.52 KiB {5} [built] [1 warning] [4 errors]
          | ./src/containers/NovelContainer.tsx 1.1 KiB [built] [1 error]
          | ./src/actions/novel.ts 793 bytes [built] [1 warning]
          | ./src/services/novelapi.ts 182 bytes [built] [1 error]
          | ./src/services/api.ts 2.96 KiB [built] [1 error]
          |     + 1 hidden module
        + 142 hidden modules
    

    解释一下下面几个插件的作用:

    • eslint-plugin-compat 根据 browserslist 的配置提示浏览器是否兼容。
    • eslint-plugin-import 支持 ES2015+ (ES6+) import/export语法,并防止文件路径和导入名称错误拼写的问题。
    • eslint-plugin-jest eslint 用来支持jest的插件。
    • eslint-plugin-jsx-a11y 基于JSX元素的可访问性规则的静态AST检查器。
    • eslint-plugin-react 用于react的eslint 规则插件。
    • eslint-plugin-unicorn 使用 xo 打包的一些默认规则。
    • eslint-config-prettier 将 prettier 作为 eslint d的规则来报告相应的问题。

    在此基础上我们可以扩展下我们自己需要的规则,添加额外的插件。例如支持检查 React 16.8 的 Hook 特性的插件。

    安装yarn add -D eslint-plugin-react-hooks插件,添加插件定义的规则。

    module.exports = {
        // 继承已有的共享配置
        "extends": "@stinkstudios/eslint-config-react-app",
        // 启用的规则及其各自的错误级别 0-off 1-warn 2-error
        "rules": {
            // 不禁用console
            'no-console': 0,
            // 防止在React组件定义中丢失props验证
            "react/prop-types": 0,
            // 关闭 ox 规则中的文件名小写
            'unicorn/filename-case': 0,
            // 遵循官方Hook规则的验证
            'react-hooks/exhaustive-deps': 1,
            'react-hooks/rules-of-hooks': 2,
        },
        // 配置插件
        "plugins": [
            "react-hooks"
        ],
    }
    

    如此我们可以通过Eslint来完成项目中的静态检查。

    EditorConfig

    editorconfig 保证了我们在不同的环境,使用不用的编辑器都有统一的规范。比如在 window 上默认换行使用 CRLF, 而在 mac 上的换行风格是 IF ; 有的编辑器默认缩进使用 Tab, 而有的编辑器使用 Space 等。

    vscode 环境需要安装 EditorConfig for VS Code 插件,并在根目录下增加配置文件 .editorconfig

    # 标记此配置文件为最顶层
    root = true
    
    # 匹配所有文件
    [*]
    # 缩进格式 空格
    indent_style = space
    # 缩进格式字符大小
    indent_size = 2
    # 换行格式
    end_of_line = lf
    # 字符编码
    charset = utf-8
    # 去除每行末尾多余空格
    trim_trailing_whitespace = true
    # 在代码末尾添加新行
    insert_final_newline = true
    

    当然我们也可以给不同的文件,赋予特有的规范,只要新增一个匹配加对应规则即可。比如如下所示给所有后缀名为 ts 和 tsx 的文件指定缩进格式为4个空格。

    [*.{ts, tsx}]
    indent_style = space
    indent_size = 4
    

    当插件 EditorConfig for VS Code 检测到项目根目录中的配置文件后,相关配置就会自动生效。

    相关文章

      网友评论

        本文标题:08-使用Eslint和Editorconfig规范代码

        本文链接:https://www.haomeiwen.com/subject/dkugcctx.html