ESLint裡的規則教會我,無規矩 不程式設計

chenhongdong發表於2018-05-21

程式設計風格要統一

程式設計風格這個東西,說實在的對於剛加入團隊的新成員來說還是很難讓人完全適應的。因為每人的程式設計風格都不同,完全是各有千秋的既視感啊

到了新公司後團隊中的每個人也都有各自一套的程式設計習慣,擼起程式碼來是擋也擋不住啊,什麼都別問,老夫就是幹,哈哈,每個coder的程式碼風格都大相徑庭

不過話說回來,在團隊開發中,所有的程式碼看起來風格一致是極其重要的,所以我們也需要一些程式碼檢查工具,從JSLint,JSHint到今天的主角ESLint,都是非常好用的檢查工具

那麼閒言少敘,直接進入主題,投入ESLint的懷抱吧!!!

ESLint是偉大的作品

放眼望去,在前端,但凡有個專案,無論大小,都會看到它的身影。並非為了提高比格,讓別人暗贊專業,而是它確確實實幫我們檢測出不易察覺的錯誤,避免N多個線上bug

也通過其規則,讓整個團隊有了整齊劃一的程式碼輸出風格,也有業界的最佳實踐寫法,深入其中,受益匪淺.....好處優點不多說,用過都說好

既然都說好了,那還廢話那麼多,小二趕緊上菜啊

安裝ESLint

現在前端專案開發中,都用到了webpack此等屌屌的構建工具(如果有對webpack不熟悉使用的可移步這裡),那麼就結合著一起來看下如何使用到專案裡吧

  1. 首先安裝一下
// 安裝eslint
// 安裝eslint-loader 在webpack中解析
// 安裝babel-eslint  對Babel解析器的包裝與ESLint相容
// -D 安裝在開發依賴環境 devDependencies 原--save-dev的簡寫
npm i eslint eslint-loader babel-eslint -D
複製程式碼

友情提示:ESLint是基於Node的(當然webpack也是),所以在使用之前,請確保Node已經安裝

  1. 建立.eslintrc.js配置檔案(預設是.eslintrc檔案)
// .eslintrc.js
module.exports = {
    // 指定解析器
    'parse': '',
    // 指定解析器選項
    'parserOptions': {},
    // 指定指令碼的執行環境
    'env': {},
    // 別人可以直接使用你配置好的ESLint
    'root': true,
    // 指令碼在執行期間訪問的額外的全域性變數
    'globals': {},
    // 啟用的規則及其各自的錯誤級別
    'rules': {}
};
複製程式碼
  1. 將配置好的規則新增到webpack中對js檔案檢查
// webpack.config.js

module.exports = {
    entry: '',
    output: {},
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader', 'eslint-loader']
            }
        ]
    },
    plugins: [],
    devServer: {}
};
複製程式碼

按照上面的三步曲寫完後,應該給自己撒花的,哈哈

ESLint裡的規則教會我,無規矩 不程式設計
再放一張打包的index.js主檔案的程式碼
ESLint裡的規則教會我,無規矩 不程式設計
該配置的都配置完了,那就迫不及待的執行npm run dev吧,看看是不是完全OK的編譯成功呢?

然並卵啊,高興的太早了

ESLint裡的規則教會我,無規矩 不程式設計
上圖之所以會有error和warning的報錯提示,是因為參照了下面我在公司中使用的ESLint配置規則導致的,那麼就趕緊進入下一環節,看看這些規則吧

工作中用到的規則

正所謂人在江湖飄啊,哪有不挨刀的道理。誰敢說寫的程式碼放到ESLint裡完全不報錯,報錯純屬正常,沒必要慌張

現在針對一些比較常見的規範來簡單梳理一下,這麼多規則,其實看的我也吃了一鯨

現在來看看編譯過程中報錯的規則吧

非友情提示:每個規則對應的0,1,2分別表示off, warning, error三個錯誤級別

  • no-unused-vars
    • 定義了變數卻沒有在程式碼中使用,這是防止產生多餘沒用的變數
  • semi
    • 缺少分號,行尾必須使用分號,這是為了在壓縮程式碼的時候出現意外情況
  • no-console
    • 禁止使用 console,提醒開發者,上線時要去掉,因為是warning不會導致編譯的js出問題
  • consistent-this
    • this的別名規則,只允許self和that,防止有些人寫成_this或者me等等,哈哈
  • curly
    • if 後必須包含 { ,單行 if 除外,也是為了方便閱讀程式碼
    // 錯誤寫法
    function fn (key) {
       if (key === 'a') 
           return 1;
    }
    fn('a');
    // 正確寫法
    function fn (key) {
       if (key === 'a') {
           return 1;
       }
       if (key === 'b') return 2;
    }
    fn('a');
    複製程式碼
  • default-case
    • switch 語句必須包含 default
    // 錯誤寫法
    function fn (key) {
        let str = '';
    
        switch (key) {
            case 'a':
                str = 'a';
                break;
            case 'b':
                str = 'b';
                break;
        }
        return str;
    }
    // 正確寫法
    function fn (key) {
        let str = '';
    
        switch(key) {
            case 'a':
                str = 'a';
                break;
            case 'b':
                str = 'b';
                break;
            default:
                str = 'c';
                break;
        }
        return str;
    }
    複製程式碼
  • eqeqeq
    • 必須使用全等===進行比較,防止隱式轉換帶來的意外問題
  • guard-for-in
    • for in時需檢測hasOwnProperty,避免遍歷到繼承來的屬性方法
  • max-depth
    • 最大塊巢狀不能超過5層
    // 正確寫法
    if () {
        if () {
            if () {
                if () {
                    if () {
                        
                    }
                }
            }
        }
    }
    複製程式碼
  • max-params
    • 函式的形參不能多於8個,如果形參過多,我們現在可以用擴充套件運算子...來代替後面多餘的形參
  • new-cap
    • new關鍵字後類名應首字母大寫,區分類和函式
  • no-array-constructor
    • 禁止使用Array建構函式,定義陣列直接用最快捷的方式[1, 2, 3]
  • no-await-in-loop
    • 禁止將await寫在迴圈裡,迴圈屬於同步操作,不該將await非同步操作寫在內部
  • no-caller
    • 禁止使用arguments.caller和arguments.callee,ES6中廢棄了
  • no-const-assign
    • 禁止對const定義重新賦值
  • no-delete-var
    • 禁止對變數使用delete關鍵字,delete只適用於物件的屬性,提醒使用的範圍
  • no-dupe-args
    • 函式引數禁止重名
  • no-empty-function
    • 禁止空的function,保證寫的每一個function都有用
  • no-eval
    • 禁止使用eval,eval是“魔鬼”,所以在開發中避免
  • no-extra-semi
    • 禁止額外的分號,有些地方沒必要加分號比如if () {};這樣就是錯誤的
  • no-global-assign
    • 禁止對全域性變數賦值

好了還有一些就需要大家在使用中來去體會了,下面我將我司工作當中用到的ESLint規則貼出來,方便大家去做程式碼檢查了

// .eslintrc.js
module.exports = {
    // 解析ES6
    'parser': 'babel-eslint',
    'parserOptions': {
        // 啟用ES8語法支援
        'ecmaVersion': 2017,    
        // module表示ECMAScript模組
        'sourceType': 'module',
        // 使用額外的語言特性
        'ecmaFeatures': {
            'experimentalObjectRestSpread': true,
            'jsx': true,
            'modules': true,
        }
    },
    // 這些環境並不是互斥的,所以你可以同時定義多個
    'env': {
        'browser': true,
        'jquery': true,
        'node': true,
        'commonjs': true,
        'es6': true,
    },
    'root': true,
    // 當訪問當前原始檔內未定義的變數時,no-undef 規則將發出警告
    // 所以需要定義這些額外的全域性變數
    'globals': {
        'OnlySVG': true,
        'monitor': true,
        'CanvasRender': true,
        'Vue': true,
        'VueRouter': true
    },
    'rules': {
        // 設定了 setter ,必須相應設定 getter ,反之不必須
        'accessor-pairs': 2,

        // 陣列方括號前後的換行符使用規則
        // @off 不關心
        'array-bracket-newline': 0,

        // 陣列方括號前後的空格使用規則
        // @off 不關心
        'array-bracket-spacing': 0,

        // 陣列的 map、filter、sort 等方法,回撥函式必須有返回值
        'array-callback-return': 2,

        // 每個陣列項是否獨佔一行
        // @off 不關心
        'array-element-newline': 0,

        // 箭頭函式的書寫規則
        // @off 不限制
        'arrow-body-style': 0,

        // 箭頭函式的圓括號使用規則
        // @off 不限制
        'arrow-parens': 0,

        // 箭頭函式的空格使用規則
        // @off 不限制
        'arrow-spacing': 0,

        // 不能在塊外使用塊作用域內 var 定義的變數
        'block-scoped-var': 2,

        // 程式碼塊花括號前後的空格規則
        // @off 不關心
        'block-spacing': 0,

        // if else 的花括號換行規則
        // @off 不關心
        'brace-style': 0,

        // callback 之後必須立即 return
        // @off 沒必要
        'callback-return': 0,

        // 變數名必須使用駝峰式
        // @off 暫不限制
        'camelcase': 0,

        // 註釋的首字母應該大寫
        // @off 沒必要
        'capitalized-comments': 0,

        // class 的非靜態方法必須包含 this 關鍵字
        'class-methods-use-this': 2,

        // 物件的最後一項後面是否寫逗號
        // @off 此專案不關心
        // @fixable 對於 PC 專案考慮相容性時需要設定
        'comma-dangle': 0,

        // 逗號前後是否有空格
        // @off 不關心
        'comma-spacing': 0,

        // 逗號寫在行首還是行尾
        // @off 不關心
        'comma-style': 0,

        // 禁止函式 if ... else if ... else 的複雜度超過 20
        'complexity': 2,

        // 使用方括號訪問物件屬性時,方括號前後的空格規則
        // @off 不關心
        'computed-property-spacing': 0,

        // 禁止函式在不同條件下返回不同型別的值
        // @off 有時候會希望通過引數獲取不同型別的返回值
        'consistent-return': 0,

        // this 的別名規則,只允許 self 或 that
        'consistent-this': [2, 'self', 'that'],

        // 建構函式中必須呼叫 super
        // @off 沒必要
        'constructor-super': 0,

        // if 後必須包含 { ,單行 if 除外
        'curly': [2, 'multi-line', 'consistent'],

        // switch 語句必須包含 default
        'default-case': 2,

        // 鏈式操作時,點的位置,是在上一行結尾還是下一行開頭
        // @off 不關心
        'dot-location': 0,

        // 檔案最後必須有空行
        // @off 不限制
        'eol-last': 0,

        // 必須使用 === 和 !== ,和 null 對比時除外
        'eqeqeq': [2, 'always', { 'null': 'ignore' }],

        // for 迴圈不得因方向錯誤造成死迴圈
        'for-direction': 2,

        // 執行函式的圓括號前後的空格規則
        // @off 不關心
        'func-call-spacing': 0,

        // 把函式賦給變數或物件屬性時,函式名和變數名或物件屬性名必須一致
        // @off 不限制
        'func-name-matching': 0,

        // 不允許匿名函式
        // @off 不限制
        'func-names': 0,

        // 必須只使用函式申明或只使用函式表示式
        // @off 不限制
        'func-style': 0,

        // generator 的 * 前後空格使用規則
        // @off 不限制
        'generator-star-spacing': 0,

        // getter 必須有返回值,允許返回 undefined
        'getter-return': [2, { allowImplicit: true }],

        // require 必須在全域性作用域下
        // @off 條件載入很常見
        'global-require': 0,

        // for in 時需檢測 hasOwnProperty
        'guard-for-in': 2,

        // callback 中的 err、error 引數和變數必須被處理
        'handle-callback-err': 2,

        // id 黑名單
        // @off 暫時沒有
        'id-blacklist': 0,

        // 變數名長度限制
        // @off 長度不是重點,清晰易讀才是關鍵
        'id-length': 0,

        // 限制變數名必須匹配指定的正規表示式
        // @off 沒必要限制變數名
        'id-match': 0,

        // 縮排使用 tab 還是空格
        // @off 不關心
        'indent': 0,

        // 變數必須在定義的時候賦值
        // @off 先定義後賦值很常見
        'init-declarations': 0,

        // jsx 語法中,屬性的值必須使用雙引號
        'jsx-quotes': [2, 'prefer-double'],

        // 物件字面量冒號前後的空格使用規則
        // @off 不關心
        'key-spacing': 0,

        // 關鍵字前後必須有空格
        'keyword-spacing': 2,

        // 換行符使用規則
        // @off 不關心
        'linebreak-style': 0,

        // 單行註釋必須寫在前一行還是行尾
        // @off 不限制
        'line-comment-position': 0,

        // 註釋前後是否要空一行
        // @off 不限制
        'lines-around-comment': 0,

        // 最大塊巢狀深度為 5 層
        'max-depth': [2, 5],

        // 限制單行程式碼的長度
        // @off 不限制
        'max-len': 0,

        // 限制單個檔案最大行數
        // @off 不限制
        'max-lines': 0,

        // 最大回撥深度為 3 層
        'max-nested-callbacks': [2, 3],

        // 函式的形參不能多於8個
        'max-params': [2, 8],

        // 限制一行中的語句數量
        // @off 沒必要限制
        'max-statements-per-line': 0,

        // 限制函式塊中的語句數量
        // @off 沒必要限制
        'max-statements': 0,

        // 三元表示式的換行規則
        // @off 不限制
        'multiline-ternary': 0,

        // new關鍵字後類名應首字母大寫
        'new-cap': [2, {
            'capIsNew': false, // 允許大寫開頭的函式直接執行
        }],

        // new 關鍵字後類應包含圓括號
        'new-parens': 2,

        // 鏈式呼叫是否要換行
        // @off 不限制
        'newline-per-chained-call': 0,

        // 禁止 alert,提醒開發者,上線時要去掉
        'no-alert': 1,

        // 禁止使用 Array 建構函式,使用 Array(num) 直接建立長度為 num 的陣列時可以
        'no-array-constructor': 2,

        // 禁止將 await 寫在迴圈裡
        'no-await-in-loop': 2,

        // 禁止位運算
        // @off 不限制
        'no-bitwise': 0,

        // 禁止在 Node.js 中直接呼叫 Buffer 建構函式
        'no-buffer-constructor': 2,

        // 禁止使用 arguments.caller 和 arguments.callee
        'no-caller': 2,

        // switch的條件中出現 var、let、const、function、class 等關鍵字,必須使用花括號把內容括起來
        'no-case-declarations': 2,

        // catch中不得使用已定義的變數名
        'no-catch-shadow': 2,

        // class定義的類名不得與其它變數重名
        'no-class-assign': 2,

        // 禁止與 -0 做比較
        'no-compare-neg-zero': 2,

        // 禁止在 ifforwhile 中出現賦值語句,除非用圓括號括起來
        'no-cond-assign': [2, 'except-parens'],

        // 禁止出現難以理解的箭頭函式,除非用圓括號括起來
        'no-confusing-arrow': [2, { 'allowParens': true }],

        // 禁止使用 console,提醒開發者,上線時要去掉
        'no-console': 1,

        // 禁止使用常量作為判斷條件
        'no-constant-condition': [2, { 'checkLoops': false }],

        // 禁止對 const 定義重新賦值
        'no-const-assign': 2,

        // 禁止 continue
        // @off 很常用
        'no-continue': 0,

        // 禁止正規表示式中出現 Ctrl 鍵的 ASCII 表示,即/\x1f/
        'no-control-regex': 2,

        // 禁止 debugger 語句,提醒開發者,上線時要去掉
        'no-debugger': 1,

        // 禁止對變數使用 delete 關鍵字,刪除物件的屬性不受限制
        'no-delete-var': 2,

        // 禁止在正規表示式中出現形似除法操作符的開頭,如 let a = /=foo/
        // @off 有程式碼高亮的話,在閱讀這種程式碼時,也完全不會產生歧義或理解上的困難
        'no-div-regex': 0,

        // 函式引數禁止重名
        'no-dupe-args': 2,

        // 禁止物件出現重名鍵值
        'no-dupe-keys': 2,

        // 類方法禁止重名
        'no-dupe-class-members': 2,

        // 禁止 switch 中出現相同的 case
        'no-duplicate-case': 2,

        // 禁止重複 import
        'no-duplicate-imports': 2,

        // 禁止出現 if (cond) { return a } else { return b },應該寫為 if (cond) { return a } return b
        // @off 有時前一種寫法更清晰易懂
        'no-else-return': 0,

        // 正規表示式中禁止出現空的字符集[]
        'no-empty-character-class': 2,

        // 禁止空的 function
        // 包含註釋的情況下允許
        'no-empty-function': 2,

        // 禁止解構中出現空 {} 或 []
        'no-empty-pattern': 2,

        // 禁止出現空程式碼塊
        'no-empty': [2, { 'allowEmptyCatch': true }],

        // 禁止 == 和 != 與 null 做比較,必須用 === 或 !==
        // @off 非嚴格相等可以同時判斷 null 和 undefined
        'no-eq-null': 0,

        // 禁止使用 eval
        'no-eval': 2,

        // catch 定義的引數禁止賦值
        'no-ex-assign': 2,

        // 禁止擴充套件原生物件
        'no-extend-native': [2, { 'exceptions': ['Array', 'Object'] }],

        // 禁止額外的 bind
        'no-extra-bind': 2,

        // 禁止額外的布林值轉換
        'no-extra-boolean-cast': 2,

        // 禁止額外的 label
        'no-extra-label': 2,

        // 禁止額外的括號,僅針對函式體
        'no-extra-parens': [2, 'functions'],

        // 禁止額外的分號
        'no-extra-semi': 2,

        // 每一個 switch 的 case 都需要有 break, return 或 throw
        // 包含註釋的情況下允許
        'no-fallthrough': [2, { 'commentPattern': '.' }],

        // 不允許使用 2. 或 .5 來表示數字,需要用 2、2.0、0.5 的格式
        'no-floating-decimal': 2,

        // 禁止對函式宣告重新賦值
        'no-func-assign': 2,

        // 禁止對全域性變數賦值
        'no-global-assign': 2,

        // 禁止使用隱式型別轉換
        'no-implicit-coercion': [2, {
            'allow': ['+', '!!'] // 允許 + 轉數值 '' + 轉字串和 !! 轉布林值
        }],

        // 禁止在 setTimeout 和 setInterval 中傳入字串,因會觸發隱式 eval
        'no-implied-eval': 2,

        // 禁止隱式定義全域性變數
        'no-implicit-globals': 2,

        // 禁止行內註釋
        // @off 很常用
        'no-inline-comments': 0,

        // 禁止在塊作用域內使用 var 或函式宣告
        'no-inner-declarations': [2, 'both'],

        // 禁止使用非法的正規表示式
        'no-invalid-regexp': 2,

        // 禁止在類之外的地方使用 this
        // @off this 的使用很靈活,事件回撥中可以表示當前元素,函式也可以先用 this,等以後被呼叫的時候再 call
        'no-invalid-this': 0,

        // 禁止使用不規範空格
        'no-irregular-whitespace': [2, {
            'skipStrings': true, // 允許在字串中使用
            'skipComments': true, // 允許在註釋中使用
            'skipRegExps': true, // 允許在正規表示式中使用
            'skipTemplates': true, // 允許在模板字串中使用
        }],

        // 禁止使用 __iterator__
        'no-iterator': 2,

        // label 不得與已定義的變數重名
        'no-label-var': 2,

        // 禁止使用 label
        // @off 禁止了將很難 break 多重迴圈和多重 switch
        'no-labels': 0,

        // 禁止使用無效的塊作用域
        'no-lone-blocks': 2,

        // 禁止 else 中只有一個單獨的 if
        // @off 單獨的 if 可以把邏輯表達的更清楚
        'no-lonely-if': 0,

        // 禁止 for (var i) { function() { use i } },使用 let 則可以
        'no-loop-func': 2,

        // 禁止魔法數字
        'no-magic-numbers': 0,

        // 禁止使用混合的邏輯判斷,必須把不同的邏輯用圓括號括起來
        'no-mixed-operators': [2, {
            "groups": [
                ["&&", "||"]
            ]
        }],

        // 相同型別的 require 必須放在一起
        // @off 不限制
        'no-mixed-requires': 0,

        // 禁止混用空格和 tab 來做縮排,必須統一
        'no-mixed-spaces-and-tabs': 2,

        // 禁止連等賦值
        'no-multi-assign': 2,

        // 禁止使用連續的空格
        'no-multi-spaces': 2,

        // 禁止使用 \ 來定義多行字串,統一使用模板字串來做
        'no-multi-str': 2,

        // 連續空行的數量限制
        'no-multiple-empty-lines': [2, {
            max: 3, // 檔案內最多連續 3 個
            maxEOF: 1, // 檔案末尾最多連續 1 個
            maxBOF: 1 // 檔案頭最多連續 1 個
        }],

        // 禁止 if 中出現否定表示式 !==
        // @off 否定的表示式可以把邏輯表達的更清楚
        'no-negated-condition': 0,

        // 禁止巢狀的三元表示式
        // @off 沒有必要限制
        'no-nested-ternary': 0,

        // 禁止 new Function
        // @off 有時會用它來解析非標準格式的 JSON 資料
        'no-new-func': 0,

        // 禁止使用 new Object
        'no-new-object': 2,

        // 禁止使用 new require
        'no-new-require': 2,

        // 禁止使用 new Symbol
        'no-new-symbol': 2,

        // 禁止 new Boolean、Number 或 String
        'no-new-wrappers': 2,

        // 禁止 new 一個類而不儲存該例項
        'no-new': 2,

        // 禁止把原生物件 Math、JSON、Reflect 當函式使用
        'no-obj-calls': 2,

        // 禁止使用八進位制轉義符
        'no-octal-escape': 2,

        // 禁止使用0開頭的數字表示八進位制
        'no-octal': 2,

        // 禁止使用 __dirname + 'file' 的形式拼接路徑,應該使用 path.join 或 path.resolve 來代替
        'no-path-concat': 2,

        // 禁止對函式的引數重新賦值
        'no-param-reassign': 2,

        // 禁止 ++ 和 --
        // @off 很常用
        'no-plusplus': 0,

        // 禁止使用 process.env.NODE_ENV
        // @off 使用很常見
        'no-process-env': 0,

        // 禁止使用 process.exit(0)
        // @off 使用很常見
        'no-process-exit': 0,

        // 禁止使用 hasOwnProperty, isPrototypeOf 或 propertyIsEnumerable
        // @off 與 guard-for-in 規則衝突,且沒有必要
        'no-prototype-builtins': 0,

        // 禁止使用 __proto__
        'no-proto': 2,

        // 禁止重複宣告
        'no-redeclare': 2,

        // 禁止在正規表示式中出現連續空格
        'no-regex-spaces': 2,

        // 禁止特定的全域性變數
        // @off 暫時沒有
        'no-restricted-globals': 0,

        // 禁止 import 特定的模組
        // @off 暫時沒有
        'no-restricted-imports': 0,

        // 禁止使用特定的模組
        // @off 暫時沒有
        'no-restricted-modules': 'off',

        // 禁止特定的物件屬性
        // @off 暫時沒有
        'no-restricted-properties': 0,

        // 禁止使用特定的語法
        // @off 暫時沒有
        'no-restricted-syntax': 0,

        // 禁止在return中賦值
        'no-return-assign': 2,

        // 禁止在 return 中使用 await
        'no-return-await': 2,

        // 禁止 location.href = 'javascript:void'
        'no-script-url': 2,

        // 禁止將自己賦值給自己
        'no-self-assign': 2,

        // 禁止自己與自己作比較
        'no-self-compare': 2,

        // 禁止逗號操作符
        'no-sequences': 2,

        // 禁止使用保留字作為變數名
        'no-shadow-restricted-names': 2,

        // 禁止在巢狀作用域中出現重名的定義,如 let a; function b() { let a }
        'no-shadow': 2,

        // 禁止陣列中出現連續逗號
        'no-sparse-arrays': 2,

        // 禁止使用 node 中的同步的方法,比如 fs.readFileSync
        // @off 使用很常見
        'no-sync': 0,

        // 禁止使用 tabs
        // @off 不限制
        'no-tabs': 0,

        // 禁止普通字串中出現模板字串語法
        'no-template-curly-in-string': 2,

        // 禁止三元表示式
        // @off 很常用
        'no-ternary': 0,

        // 禁止在建構函式的 super 之前使用 this
        'no-this-before-super': 2,

        // 禁止 throw 字面量,必須 throw 一個 Error 物件
        'no-throw-literal': 2,

        // 禁止行尾空格
        'no-trailing-spaces': [2, {
            "skipBlankLines": true, // 不檢查空行
            "ignoreComments": true // 不檢查註釋
        }],

        // 禁止將 undefined 賦值給變數
        'no-undef-init': 2,

        // 禁止訪問未定義的變數或方法
        'no-undef': 2,

        // 禁止使用 undefined,如需判斷一個變數是否為 undefined,請使用 typeof a === 'undefined'
        'no-undefined': 2,

        // 禁止變數名中使用下劃線
        // @off 暫不限制
        'no-underscore-dangle': 0,

        // 禁止出現難以理解的多行程式碼
        'no-unexpected-multiline': 2,

        // 迴圈體內必須對迴圈條件進行修改
        'no-unmodified-loop-condition': 2,

        // 禁止不必要的三元表示式
        'no-unneeded-ternary': [2, { 'defaultAssignment': false }],

        // 禁止出現不可到達的程式碼,如在 return、throw 之後的程式碼
        'no-unreachable': 2,

        // 禁止在finally塊中出現 return、throw、breakcontinue
        'no-unsafe-finally': 2,

        // 禁止出現不安全的否定,如 for (!key in obj} {},應該寫為 for (!(key in obj)} {}
        'no-unsafe-negation': 2,

        // 禁止出現無用的表示式
        'no-unused-expressions': [2,
            {
                'allowShortCircuit': true, // 允許使用 a() || b 或 a && b()
                'allowTernary': true, // 允許在表示式中使用三元運算子
                'allowTaggedTemplates': true, // 允許標記模板字串
            }
        ],

        // 禁止定義不使用的 label
        'no-unused-labels': 2,

        // 禁止定義不使用的變數
        'no-unused-vars': [2,
            {
                'vars': 'all', // 變數定義必須被使用
                'args': 'none', // 對於函式形參不檢測
                'ignoreRestSiblings': true, // 忽略剩餘子項 fn(...args),{a, b, ...coords}
                'caughtErrors': 'none', // 忽略 catch 語句的引數使用
            }
        ],

        // 禁止在變數被定義之前使用它
        'no-use-before-define': [2,
            {
                'functions': false, // 允許函式在定義之前被呼叫
                'classes': false, // 允許類在定義之前被引用
            }
        ],

        // 禁止不必要的 call 和 apply
        'no-useless-call': 2,

        // 禁止使用不必要計算的key,如 var a = { ['0']: 0 }
        'no-useless-computed-key': 2,

        // 禁止不必要的字串拼接
        'no-useless-concat': 2,

        // 禁止無用的建構函式
        'no-useless-constructor': 2,

        // 禁止無用的轉義
        'no-useless-escape': 2,

        // 禁止無效的重新命名,如 import {a as a} from xxx
        'no-useless-rename': 2,

        // 禁止沒有必要的 return
        // @off 沒有必要限制
        'no-useless-return': 0,

        // 禁止使用 var,必須用 let 或 const
        'no-var': 2,

        // 禁止使用void
        'no-void': 2,

        // 禁止註釋中出現 TODO 或 FIXME,用這個來提醒開發者,寫了 TODO 就一定要做完
        'no-warning-comments': 1,

        // 禁止屬性前出現空格,如 foo. bar()
        'no-whitespace-before-property': 2,

        // 禁止 with
        'no-with': 2,

        // 禁止 if 語句在沒有花括號的情況下換行
        'nonblock-statement-body-position': 2,

        // 定義物件的花括號前後是否要加空行
        // @off 不關心
        'object-curly-newline': 0,

        // 定義物件的花括號前後是否要加空格
        // @off 不關心
        'object-curly-spacing': 0,

        // 物件每個屬性必須獨佔一行
        // @off 不限制
        'object-property-newline': 0,

        // obj = { a: a } 必須轉換成 obj = { a }
        // @off 沒必要
        'object-shorthand': 0,

        // 每個變數宣告必須獨佔一行
        // @off 有 one-var 就不需要此規則了
        'one-var-declaration-per-line': 0,

        // 是否允許使用逗號一次宣告多個變數
        'one-var': [2, {
            'const': 'never' // 所有 const 宣告必須獨佔一行,不允許用逗號定義多個
        }],

        // 必須使用 x = x + y 而不是 x += y
        // @off 沒必要限制
        'operator-assignment': 0,

        // 斷行時操作符位於行首還是行尾
        // @off 不關心
        'operator-linebreak': 0,

        // 程式碼塊首尾必須要空行
        // @off 沒必要限制
        'padded-blocks': 0,

        // 限制語句之間的空行規則,比如變數定義完之後必須要空行
        // @off 沒必要限制
        'padding-line-between-statements': 0,

        // 必須使用箭頭函式作為回撥
        // @off 沒必要
        'prefer-arrow-callback': 0,

        // 宣告後不再修改的變數必須使用 const
        // @off 沒必要
        'prefer-const': 0,

        // 必須使用解構
        // @off 沒必要
        'prefer-destructuring': 0,

        // 必須使用 0b11111011 而不是 parseInt('111110111', 2)
        // @off 沒必要
        'prefer-numeric-literals': 0,

        // promise 的 reject 中必須傳入 Error 物件,而不允許使用字面量
        'prefer-promise-reject-errors': 2,

        // 必須使用解構 ...args 來代替 arguments
        'prefer-rest-params': 2,

        // 必須使用 func(...args) 來代替 func.apply(args)
        // @off 沒必要
        'prefer-spread': 0,

        // 必須使用模板字串來代替字串拼接
        // @off 不限制
        'prefer-template': 0,

        // 字串必須使用單引號
        'quotes': [2, 'single', {
            'avoidEscape': true, // 允許包含單引號的字串使用雙引號
            'allowTemplateLiterals': true, // 允許使用模板字串
        }],

        // 物件字面量的鍵名禁止用引號括起來
        // @off 沒必要限制
        'quote-props': 0,

        // parseInt方法必須傳進位制引數
        'radix': 2,

        // async 函式中必須存在 await 語句
        // @off async function 中沒有 await 的寫法很常見,比如 koa 的示例中就有這種用法
        'require-await': 0,

        // 必須使用 jsdoc 風格的註釋
        // @off 暫不考慮開啟
        'require-jsdoc': 0,

        // generator 函式內必須有 yield
        'require-yield': 2,

        // ...後面不允許有空格
        'rest-spread-spacing': [2, 'never'],

        // 分號前後的空格規則
        // @off 不限制
        'semi-spacing': 0,

        // 禁止行首出現分號
        'semi-style': [2, 'last'],

        // 行尾必須使用分號結束
        'semi': 2,

        // imports 必須排好序
        // @off 沒必要限制
        'sort-imports': 0,

        // 物件字面量的鍵名必須排好序
        // @off 沒必要限制
        'sort-keys': 0,

        // 變數宣告必須排好序
        // @off 沒必要限制
        'sort-vars': 0,

        // function 等的花括號之前是否使用空格
        // @off 不關心
        'space-before-blocks': 0,

        // function 的圓括號之前是否使用空格
        // @off 不關心
        'space-before-function-paren': 0,

        // 圓括號內的空格使用規則
        // @off 不關心
        'space-in-parens': 0,

        // 操作符前後要加空格
        'space-infix-ops': 2,

        // new, delete, typeof, void, yield 等表示式前後必須有空格,-, +, --, ++, !, !! 等表示式前後不許有空格
        'space-unary-ops': [2, {
            'words': true,
            'nonwords': false,
        }],

        // 註釋的斜線和星號後要加空格
        'spaced-comment': [2, 'always', {
            'block': {
                exceptions: ['*'],
                balanced: true
            }
        }],

        // 禁用嚴格模式,禁止在任何地方出現 'use strict'
        'strict': [2, 'never'],

        // switch 中冒號前後的空格規則
        // @off 不關心
        'switch-colon-spacing': 0,

        // 建立 Symbol 的時候必須傳入描述
        'symbol-description': 2,

        // 模板字串 ${} 前後的空格規則
        // @off 不限制
        'template-curly-spacing': 0,

        // 模板字串前後的空格規則
        // @off 不限制
        'template-tag-spacing': 0,

        // 所有檔案頭禁止出現 BOM
        'unicode-bom': 2,

        // 禁止直接對 NaN 進行判斷,必須使用 isNaN
        'use-isnan': 2,

        // 註釋必須符合 jsdoc 的規範
        // @off 暫不考慮開啟
        'valid-jsdoc': 0,

        // typeof 判斷條件只能是 "undefined", "object", "boolean", "number", "string", "function""symbol"
        'valid-typeof': 2,

        // var 必須在作用域的最前面
        // @off var 不在最前面也是很常見的用法
        'vars-on-top': 0,

        // 自執行函式必須使用圓括號括起來,如 (function(){do something...})()
        'wrap-iife': [2, 'inside'],

        // 正規表示式必須用圓括號括起來
        // @off 不限制
        'wrap-regex': 0,

        // yield 的 * 前後空格規則
        // @off 不限制
        'yield-star-spacing': 0,

        // 禁止Yoda格式的判斷條件,如 if (true === a),應使用 if (a === true)
        'yoda': 2,
    }
};
複製程式碼

再說點什麼

以上內容就是我在公司專案中使用到的ESLint規則,大家可以也運用到自己的專案中試試看,當然上面的規則都是可配置的,如果你有用不到的,直接把對應的規則賦為0就可以了

我們要做一個很有規範的Coder,讓別人看到我們寫的程式碼閱讀起來無障礙,上手快,這才算是高效的開發了

哈哈,就說到這裡吧,感謝大家了!

相關文章