eslint 經常使用配置

前言

在團隊協做開發中,爲了統一代碼風格,避免一些低級錯誤,應該設有團隊成員統一遵照的編碼規範。不少語言都提供了Lint工具來實現這樣的功能,JavaScript也有相似的工具:ESLint。除了能夠集成到構建工具中(如:Gulp)在構建過程當中檢查代碼風格之外;還能夠經過將ESLint和代碼編輯器相結合以提供代碼風格的實時校驗。這裏將介紹如何在Visual Studio Code使用ESLint來提供代碼風格的實時校驗。node

配置原則

  1. 可以幫助發現代碼錯誤的規則,所有開啓
  2. 配置不該該依賴於某個具體項目,而應儘量的合理
  3. 幫助保持團隊的代碼風格統一,而不是限制開發體驗

配置解讀

  1. 每一條配置都有註釋說明此配置的用途
  2. 對於理解困難的配置,都在註釋中有舉例
  3. 對於有爭議的配置,都在註釋中說明了爲何要這麼配置的緣由
  4. 對於關閉掉的配置,都在註釋中有對應的緣由說明,以及 @off 的標識
  5. 對於可以 autofix 的配置,都在註釋中有標註 @autofix

EsLint提供如下支持:

  1. ES6
  2. AngularJS
  3. JSX
  4. Style檢查
  5. 自定義錯誤和提示

EsLint提供如下幾種校驗:

1.語法錯誤校驗
2.不重要或丟失的標點符號,如分號
3.無法運行到的代碼塊(使用過WebStorm的童鞋應該瞭解)
4.未被使用的參數提醒
5.漏掉的結束符,如}
6.確保樣式的統一規則,如sass或者less
7.檢查變量的命名react

詳細的配置內容在這裏:git

/**
 * AlloyTeam ESLint 規則 - React
 *
 * 包含全部 ESLint 規則,以及全部 eslint-plugin-react 規則
 * 使用 babel-eslint 做爲解析器
 *
 * @fixable 表示此配置支持 --fix
 * @off 表示此配置被關閉了,而且後面說明了關閉的緣由
 */

module.exports = {
    extends: [
        './index.js',
    ],
    plugins: [
        'react'
    ],
    rules: {
        // 布爾值類型的 propTypes 的 name 必須爲 is 或 has 開頭
        // @off 不強制要求寫 propTypes
        'react/boolean-prop-naming': 'off',
        // 一個 defaultProps 必須有對應的 propTypes
        // @off 不強制要求寫 propTypes
        'react/default-props-match-prop-types': 'off',
        // 組件必須有 displayName 屬性
        // @off 不強制要求寫 displayName
        'react/display-name': 'off',
        // 禁止在自定義組件中使用一些指定的 props
        // @off 不必限制
        'react/forbid-component-props': 'off',
        // 禁止使用一些指定的 elements
        // @off 不必限制
        'react/forbid-elements': 'off',
        // 禁止使用一些指定的 propTypes
        // @off 不強制要求寫 propTypes
        'react/forbid-prop-types': 'off',
        // 禁止直接使用別的組建的 propTypes
        // @off 不強制要求寫 propTypes
        'react/forbid-foreign-prop-types': 'off',
        // 禁止使用數組的 index 做爲 key
        // @off 太嚴格了
        'react/no-array-index-key': 'off',
        // 禁止使用 children 作 props
        'react/no-children-prop': 'error',
        // 禁止使用 dangerouslySetInnerHTML
        // @off 不必限制
        'react/no-danger': 'off',
        // 禁止在使用了 dangerouslySetInnerHTML 的組建內添加 children
        'react/no-danger-with-children': 'error',
        // 禁止使用已廢棄的 api
        'react/no-deprecated': 'error',
        // 禁止在 componentDidMount 裏面使用 setState
        // @off 同構應用須要在 didMount 裏寫 setState
        'react/no-did-mount-set-state': 'off',
        // 禁止在 componentDidUpdate 裏面使用 setState
        'react/no-did-update-set-state': 'error',
        // 禁止直接修改 this.state
        'react/no-direct-mutation-state': 'error',
        // 禁止使用 findDOMNode
        'react/no-find-dom-node': 'error',
        // 禁止使用 isMounted
        'react/no-is-mounted': 'error',
        // 禁止在一個文件建立兩個組件
        // @off 有一個 bug https://github.com/yannickcr/eslint-plugin-react/issues/1181
        'react/no-multi-comp': 'off',
        // 禁止在 PureComponent 中使用 shouldComponentUpdate
        'react/no-redundant-should-component-update': 'error',
        // 禁止使用 ReactDOM.render 的返回值
        'react/no-render-return-value': 'error',
        // 禁止使用 setState
        // @off setState 很經常使用
        'react/no-set-state': 'off',
        // 禁止拼寫錯誤
        'react/no-typos': 'error',
        // 禁止使用字符串 ref
        'react/no-string-refs': 'error',
        // 禁止在組件的內部存在未轉義的 >, ", ' 或 }
        'react/no-unescaped-entities': 'error',
        // @fixable 禁止出現 HTML 中的屬性,如 class
        'react/no-unknown-property': 'error',
        // 禁止出現未使用的 propTypes
        // @off 不強制要求寫 propTypes
        'react/no-unused-prop-types': 'off',
        // 定義過的 state 必須使用
        // @off 沒有官方文檔,而且存在不少 bug: https://github.com/yannickcr/eslint-plugin-react/search?q=no-unused-state&type=Issues&utf8=%E2%9C%93
        'react/no-unused-state': 'off',
        // 禁止在 componentWillUpdate 中使用 setState
        'react/no-will-update-set-state': 'error',
        // 必須使用 Class 的形式建立組件
        'react/prefer-es6-class': [
            'error',
            'always'
        ],
        // 必須使用 pure function
        // @off 不必限制
        'react/prefer-stateless-function': 'off',
        // 組件必須寫 propTypes
        // @off 不強制要求寫 propTypes
        'react/prop-types': 'off',
        // 出現 jsx 的地方必須 import React
        // @off 已經在 no-undef 中限制了
        'react/react-in-jsx-scope': 'off',
        // 非 required 的 prop 必須有 defaultProps
        // @off 不強制要求寫 propTypes
        'react/require-default-props': 'off',
        // 組件必須有 shouldComponentUpdate
        // @off 不必限制
        'react/require-optimization': 'off',
        // render 方法中必須有返回值
        'react/require-render-return': 'error',
        // @fixable 組件內沒有 children 時,必須使用自閉和寫法
        // @off 不必限制
        'react/self-closing-comp': 'off',
        // @fixable 組件內方法必須按照必定規則排序
        'react/sort-comp': 'error',
        // propTypes 的熟悉必須按照字母排序
        // @off 不必限制
        'react/sort-prop-types': 'off',
        // style 屬性的取值必須是 object
        'react/style-prop-object': 'error',
        // HTML 中的自閉和標籤禁止有 children
        'react/void-dom-elements-no-children': 'error',
        // @fixable 布爾值的屬性必須顯式的寫 someprop={true}
        // @off 不必限制
        'react/jsx-boolean-value': 'off',
        // @fixable 自閉和標籤的反尖括號必須與尖括號的那一行對齊
        'react/jsx-closing-bracket-location': [
            'error',
            {
                nonEmpty: false,
                selfClosing: 'line-aligned'
            }
        ],
        // @fixable 結束標籤必須與開始標籤的那一行對齊
        // @off 已經在 jsx-indent 中限制了
        'react/jsx-closing-tag-location': 'off',
        // @fixable 大括號內先後禁止有空格
        'react/jsx-curly-spacing': [
            'error',
            {
                when: 'never',
                attributes: {
                    allowMultiline: true
                },
                children: true,
                spacing: {
                    objectLiterals: 'never'
                }
            }
        ],
        // @fixable props 與 value 之間的等號先後禁止有空格
        'react/jsx-equals-spacing': [
            'error',
            'never'
        ],
        // 限制文件後綴
        // @off 不必限制
        'react/jsx-filename-extension': 'off',
        // @fixable 第一個 prop 必須得換行
        // @off 不必限制
        'react/jsx-first-prop-new-line': 'off',
        // handler 的名稱必須是 onXXX 或 handleXXX
        // @off 不必限制
        'react/jsx-handler-names': 'off',
        // @fixable jsx 的 children 縮進必須爲四個空格
        'react/jsx-indent': [
            'error',
            4
        ],
        // @fixable jsx 的 props 縮進必須爲四個空格
        'react/jsx-indent-props': [
            'error',
            4
        ],
        // 數組中的 jsx 必須有 key
        'react/jsx-key': 'error',
        // @fixable 限制每行的 props 數量
        // @off 不必限制
        'react/jsx-max-props-per-line': 'off',
        // jsx 中禁止使用 bind
        // @off 太嚴格了
        'react/jsx-no-bind': 'off',
        // 禁止在 jsx 中使用像註釋的字符串
        'react/jsx-no-comment-textnodes': 'error',
        // 禁止出現重複的 props
        'react/jsx-no-duplicate-props': 'error',
        // 禁止在 jsx 中出現字符串
        // @off 不必限制
        'react/jsx-no-literals': 'off',
        // 禁止使用 target="_blank"
        // @off 不必限制
        'react/jsx-no-target-blank': 'off',
        // 禁止使用未定義的 jsx elemet
        'react/jsx-no-undef': 'error',
        // 禁止使用 pascal 寫法的 jsx,好比 <TEST_COMPONENT>
        'react/jsx-pascal-case': 'error',
        // @fixable props 必須排好序
        // @off 不必限制
        'react/jsx-sort-props': 'off',
        // @fixable jsx 的開始和閉合處禁止有空格
        'react/jsx-tag-spacing': [
            'error',
            {
                closingSlash: 'never',
                beforeSelfClosing: 'always',
                afterOpening: 'never'
            }
        ],
        // jsx 文件必須 import React
        'react/jsx-uses-react': 'error',
        // 定義了的 jsx element 必須使用
        'react/jsx-uses-vars': 'error',
        // @fixable 多行的 jsx 必須有括號包起來
        // @off 不必限制
        'react/jsx-wrap-multilines': 'off'
    }
};

使用方法

標準規則
安裝
npm install --save-dev eslint-config-alloy babel-eslint

配置 .eslintrc.jses6

在你的項目根目錄下建立 .eslintrc.js,並將如下內容複製到文件中:github

module.exports = {  
    extends: [
        'eslint-config-alloy',
    ],
    globals: {
        // 這裏填入你的項目須要的全局變量
        // 這裏值爲 false 表示這個全局變量不容許被從新賦值,好比:
        //
        // jQuery: false,
        // $: false
    },
    rules: {
        // 這裏填入你的項目須要的個性化配置,好比:
        //
        // // @fixable 一個縮進必須用兩個空格替代
        // 'indent': [
        //     'error',
        //     2,
        //     {
        //         SwitchCase: 1,
        //         flatTernaryExpressions: true
        //     }
        // ]
    }
};
React 版

安裝npm

npm install --save-dev eslint-config-alloy eslint-plugin-react babel-eslint

配置 .eslintrc.jsjson

在你的項目根目錄下建立 .eslintrc.js,並將如下內容複製到文件中:api

安裝完成後咱們能夠看到除了ESLint命令行工具爲咱們生成的ESLint依賴包,還有一個特殊的.eslintrc.json文件,該文件是ESLint的配置文件,以下所示:數組

{
    "extends": "standard",
    "installedESLint": true,
    "plugins": [
        "standard"
    ]
}

配置文件中除了聲明咱們所使用的代碼風格之外,咱們還能夠定製本身的規則,好比:聲明全局變量或者規定字符串引號的風格,以及其餘任何ESLint支持的規則都是能夠配置的,下面是一個簡單的示例:sass

{
    "extends": "standard",
    "installedESLint": true,
    "plugins": [
        "standard"
    ],
    "rules": {
        //關閉額外的分號檢查
        //0:關閉,1:警告,2:異常
        "semi": 0,
        //字符串必須使用單引號
        "quotes": [
            "error",
            "single"
        ]
    }
}

配置文件中除了聲明咱們所使用的代碼風格之外,咱們還能夠定製本身的規則,好比:聲明全局變量或者規定字符串引號的風格,以及其餘任何ESLint支持的規則都是能夠配置的,下面是一個簡單的示例:

module.exports = {
    extends: [
        'eslint-config-alloy/react',
    ],
    globals: {
        // 這裏填入你的項目須要的全局變量
        // 這裏值爲 false 表示這個全局變量不容許被從新賦值,好比:
        //
        // React: false,
        // ReactDOM: false
    },
    rules: {
        // 這裏填入你的項目須要的個性化配置,好比:
        //
        // // @fixable 一個縮進必須用兩個空格替代
        // 'indent': [
        //     'error',
        //     2,
        //     {
        //         SwitchCase: 1,
        //         flatTernaryExpressions: true
        //     }
        // ],
        // // @fixable jsx 的 children 縮進必須爲兩個空格
        // 'react/jsx-indent': [
        //     'error',
        //     2
        // ],
        // // @fixable jsx 的 props 縮進必須爲兩個空格
        // 'react/jsx-indent-props': [
        //     'error',
        //     2
        // ]
    }
};

代碼改造經驗

若是是一個新項目,應用一個比較嚴格的 ESLint 規則並非一件難事。

可是若是是一個已經維護多年的老項目,那麼忽然引入 ESLint 就會有成千上萬個錯誤。這個時候該如何改造呢?

1. 將全部報錯的配置都關閉

運行 ESLint 以後,會有不少錯誤,這時候咱們能夠把他們先暫時關閉掉。

因爲項目還在不停地迭代,這樣能夠保證其餘不會報錯的規則可以應用到新增的文件上。

這時你的 .eslintrc.js 應該相似與下面的樣子:

module.exports = {
    extends: [
        '@alloyteam/eslint-config-standard',
    ],
    globals: {
        React: false,
        jQuery: false,
        $: false
    },
    rules: {
        'no-dupe-keys': 'off',
        'no-var': 'off',
        'complexity': 'off',
        'indent': 'off'
    }
};

小技巧:若是報錯的規則太多了,能夠在運行 ESLint 的時候,加上參數 -f json,這樣的話會以 json 格式輸出,而後稍做處理就能夠直接獲得全部報錯的規則了。

注意:一開始不要開啓 --fix,由於修復的太多了,就難以 review 代碼了。

相關文章
相關標籤/搜索