1. 程式人生 > 其它 >專案組 eslint 統一配置及疑難解決

專案組 eslint 統一配置及疑難解決

技術標籤:前端技術eslint

背景

專案組前端程式碼eslint久失維護,大家有的人有程式碼規範,有的人沒有。新來的程式碼規範也是從老的手裡copy一份。每個人eslint外掛的版本、配置、程式碼項均不同。導致改程式碼的時候,為了避免自動fix帶來的大量程式碼改動,不得不暫時關閉eslint,改完後,無規則校驗上庫。程式碼規範缺乏校驗,上庫程式碼質量日益下降。

第一步

按照可信認證規則(標準程式碼規範)配置eslintrc檔案,外掛的配置自不必說。為了支援js/ts/jsx/tsx ,需要安裝eslint的4個外掛,配置在plugin中。注意為了支援tsparser需要指定為@typescript-eslint/parser

。否則無法校驗ts規則。

編寫eslint fix指令碼,全域性fix專案中的程式碼。共計上庫改動600餘個檔案。

eslintrc.js

module.exports = {
    'root':true,
    'env': {
        'browser': true,
        'es6': true,
        'node': true
    },
    'globals': {
        'Atomics': 'readonly'
, 'SharedArrayBuffer': 'readonly' }, "parser": "@typescript-eslint/parser", 'parserOptions': { 'ecmaFeatures': { 'jsx': true }, 'ecmaVersion': 6, 'sourceType': 'module' }, 'plugins': [ 'react', "react-hooks"
, "typescript", "@typescript-eslint" ], 'settings':{ "react": { "version": "16.13.0", }, }, "overrides": [ { "files":["*.tsx","*.jsx"], "rules": { "react/jsx-indent-props": 0, //禁用驗證JSX中的props縮排 } } ], //覆蓋規則 'rules': { 'indent': [//縮排 'error', 4 ], 'semi': [//語句強制分號結尾 'error', 'always' ], //引數一:0或‘off’ 關閉規則,1或‘warn’ 規則等級警告,2或者‘error’ 規則等級錯誤 //引數二:可以使用預設,也可以根據文件自定義 'no-unused-vars': 0,//禁止出現未使用過的變數 'no-console': 1,//建議不使用console 'no-var': 1,//建議使用let或const替代var 'object-shorthand': 2,//物件屬性、方法簡寫語法 'prefer-spread':1,//建議使用擴充套件運算子...複製陣列 'comma-dangle': ['error', { 'arrays': 'only-multiline', 'objects': 'only-multiline', 'imports': 'never', 'exports': 'never', 'functions': 'ignore' }],//要求使用尾逗號 'func-style':['error','declaration',{"allowArrowFunctions": true}],//要求函式使用宣告式取代表達式 'prefer-rest-params':2,//要求使用rest語法...替代arguments 'no-param-reassign':1,//函式引數禁止再賦值 "curly": ["error", "all"],//控制語句使用大括號 "prefer-destructuring": ["warn", { "array": true, "object": true }, { "enforceForRenamedProperties": false//解構是否應用於重構 }],//陣列解構和物件解構 "max-len": ["warn", 120, 4],//行的最大長度120 縮排4 'no-eval':2,//禁止使用eval 'no-with':2,//禁止使用with 'brace-style':[2,'1tbs',{"allowSingleLine": true}],//花括號風格:左開與語句在同一行,允許花括號左右在同一行 'no-const-assign':2,//禁止修改const宣告變數 'no-empty':[1,{"allowEmptyCatch": true }],//建議不要存在空語句塊,允許catch塊為空 'no-cond-assign':[2,"always"],//禁止在 if、for、while 和 do...while 語句中出現模稜兩可的賦值操作符 'no-unreachable':2,//禁止在 return、throw、continue 和 break 語句後出現不可達程式碼 "jsx-quotes": [2, "prefer-double"], //強制在JSX屬性(jsx-quotes)中一致使用雙引號 "react/jsx-closing-bracket-location": 0, //在JSX中驗證右括號位置 "react/jsx-curly-spacing": [2, {"when": "never", "children": true}], //在JSX屬性和表示式中加強或禁止大括號內的空格。 "react/jsx-indent-props": [2, 4], //驗證JSX中的props縮排 "react/jsx-key": 2, //在陣列或迭代器中驗證JSX具有key屬性 "react/jsx-no-bind": 0, //JSX中不允許使用箭頭函式和bind "react/jsx-no-duplicate-props": 2, //防止在JSX中重複的props "react/jsx-no-undef": 1, //在JSX中禁止未宣告的變數 "react/jsx-pascal-case": 1, //為使用者定義的JSX元件強制使用PascalCase "react/jsx-uses-vars": 1, //防止在JSX中使用的變數被錯誤地標記為未使用 "react/no-danger": 1, //防止使用危險的JSX屬性 "react/no-did-mount-set-state": 0, //防止在componentDidMount中使用setState "react/no-did-update-set-state": 1, //防止在componentDidUpdate中使用setState "react/no-direct-mutation-state": 2, //防止this.state的直接變異 "react/no-multi-comp": 1, //防止每個檔案有多個元件定義 "react/no-set-state": 0, //防止使用setState "react/no-unknown-property": 2, //防止使用未知的DOM屬性 "react/prefer-es6-class": 2, //為React元件強制執行ES5或ES6類 "react/prop-types": 0, //防止在React元件定義中丟失props驗證 "react/react-in-jsx-scope": 2, //使用JSX時防止丟失React "react/self-closing-comp": 0, //防止沒有children的元件的額外結束標籤 "react/sort-comp": 1, //強制元件方法順序 "no-extra-boolean-cast": 0, //禁止不必要的bool轉換 "react/no-array-index-key": 0, //防止在陣列中遍歷中使用陣列key做索引 "react/no-deprecated": 1, //不使用棄用的方法 "react/jsx-equals-spacing": 2, //在JSX屬性中強制或禁止等號周圍的空格 "comma-dangle": 2, // 陣列和物件鍵值對最後一個逗號, never引數:不能帶末尾的逗號, always引數:必須帶末尾的逗號 "comma-spacing": [2, {'before': false, 'after': true}], // 控制逗號前後的空格 "no-mixed-spaces-and-tabs": 0, //禁止混用tab和空格 "prefer-arrow-callback": 0, //比較喜歡箭頭回調 //空格 建議 "space-before-blocks": [1, "always"],//程式碼塊花括號左{空格 "space-before-function-paren": [1, "never"],//函式定義時括號前面要有空格 "space-in-parens": [1, "never"],//小括號裡面要有空格 "space-infix-ops":[1,{"int32Hint": true}],//操作符空格 true允許B|0 //--FIX dyj react-hooks相關 "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks //--FIX dyj 補充可信認證中的規範 "arrow-body-style":1, //--規則31 箭頭函式的簡寫 "eqeqeq":1, //--建議47 判斷相等時使用 === 和 !== ,而不是 == 和 != "no-else-return":1, //--規則32 要求使用一致的 return 語句 "no-useless-return":1,//--規則 66 禁止多餘的 return 語句 "consistent-return":1, "prefer-template":1,//--規則36 使用模板字串(`)實現字串拼接 "no-prototype-builtins":1, //--規則 43 禁止在物件例項上直接使用 Object.prototypes 的內建屬性 "dot-notation":1, //--規則 41 使用點號來訪問物件的屬性,只有屬性是動態的時候使用 [] "guard-for-in":1, //規則 44 需要約束 for-in "no-nested-ternary":1, //規則 46 禁止使用巢狀的三元表示式 "default-case":1, // 規則 47 每個 switch 語句都包含一個 default 語句,即使它不包含任何程式碼 "no-case-declarations":1, //--規則 49 case 語句中需要宣告詞法時, 花括號 {} 不能省略 "no-duplicate-imports":1, //--規則 52 不要多次 import 同一個模組 "no-useless-rename":1, //--規則 55 不要從 import 中直接 export "no-floating-decimal":1,//--規則 57 禁止省略小數點前後的 0 "use-isnan":1,//--規則 58 要求呼叫 isNaN() 檢查 NaN "no-unsafe-finally":1,//--規則 59 禁止在 finally 語句塊中出現控制流語句 "no-return-await":1,//--規則 60 禁用不必要的 return await "no-implicit-coercion":1, //--規則 65 禁止使用較短的符號實現型別轉換 "new-cap":1, //--構造器函式、類採用首字母大寫的駝峰命名方法 "no-shadow":1,//--規則67 塊內變數不能與函式內的其他變數同名,塊內函式應該使用函式表示式宣告 } }
 "scripts": {
	"eslint": "eslint src scripts config   --ext .jsx --ext .tsx --ext .js --ext ts -o eslint-report.txt -c .eslintrc.js",
    "eslint-fix": "eslint --fix src scripts config  --ext .jsx --ext .tsx --ext .js --ext ts -c .eslintrc.js",
  },

第二步

通過npm run eslint 生成報告,手動修改無法fix的問題,例如重複props、繞過setState直接修改state、或者引數重賦值等問題累計60餘處。
![(https://img-blog.csdnimg.cn/20210201211610271.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5NzIyMjgx,size_16,color_FFFFFF,t_70)

第三步

配置 eslint-vscode外掛。統一使用2.1.14版本,使用通用的工作區設定:

{
	"eslint.run": "onType",
	"eslint.format.enable":true,
	 "eslint.options": {
	     "extensions": [
	         "web.js",
	         "js",
	         "web.ts",
	         "ts",
	         "web.tsx",
	         "tsx",
	         "json",
	         "web.jsx",
	         "jsx",
	         "node"
	     ]
	 },
	 "editor.codeActionsOnSave": {
	     "source.fixAll.eslint": true
	 },
	 "editor.suggestSelection": "first"
 }

在這裡插入圖片描述

第四步

設定webpack編譯時校驗(僅限開發模式)

rules: [
 // Disable require.ensure as it's not a standard language feature.
        { parser: { requireEnsure: false } },

        // First, run the linter.
        // It's important to do this before Babel processes the JS.
        isEnvDevelopment ? {
            test: /\.(js|mjs|jsx|ts|tsx)$/,
            enforce: 'pre',
            use: [
                {
                    options: {
                        formatter: require.resolve('react-dev-utils/eslintFormatter'),
                        eslintPath: require.resolve('eslint')
        
                    },
                    loader: require.resolve('eslint-loader')
                }
            ],
            include: paths.appSrc
        } : {},
  ]

問題

1、eslint規則衝突 導致無限fix

解決eslint規則衝突的問題。eslint規則衝突會導致不論是eslint-vscode外掛還是npm eslint,無限fix程式碼的過程。例如最常見的,eslint 原始規則 indent,設定程式碼應該的間隔,極容易與react外掛配置的一些規則衝突。這時候,就需要我們對react字尾(jsx、tsx)檔案做覆蓋規則處理:

//--eslintrc.js
 "overrides": [
        {
            "files":["*.tsx","*.jsx"],
            "rules": {
                "react/jsx-indent-props": 0, //禁用驗證JSX中的props縮排
            }
        }
    ]

2、專案成員明明eslint配置全部一致,實際規則卻不一致

這是由於eslint在查詢配置檔案時,會不斷的冒泡向上查詢規則直到系統根路徑。如果eslintrc.js沒有配置root:true。參加這裡,則eslint會不斷的在電腦中尋找配置檔案。部分成員根目錄中配置了額外規則,導致覆寫的時候出現問題。在eslintrc.js中新增即可

'root':true

五、成效

專案成員使用統一的eslint規範,再也不用害怕ctrl+s改壞原來的程式碼。且存在程式碼壞味道的程式碼會在開發階段的門禁就被攔截掉,避免引入更大的問題。

專案Value
自動修復檔案數583
自動修復程式碼行數15000
手動修復程式碼問題(風險問題)56