[Frontend筆記] 前端工程化之 ESLint + Prettier

在Vue3的專案中使用Typescript和Webpack5,在路徑重命名的小issue

Posted by 李定宇 on Saturday, September 10, 2022

前端工程化之 ESLint + Prettier

前言

對於前端專案而言,如果是一人團隊、自己處理所有的code,那其實愛怎麼寫就怎麼寫、程式跑得動就好;但如果是多人協作的團隊、甚至是要跟外包的人協作,如果沒有事先訂好基本的前端規範,輕則不知道該導入的組件在哪裡、需要的函數要去哪裡找,重則難以閱讀該代碼塊、導致該代碼只能由寫出它的工程師來維護修改(俗稱Legacy Code)

而在專案一開始就建立清晰的代碼規範,不但能夠讓程式碼的可閱讀性有一定的保障、更加易於維護,更可以減少在code review時的一些爭議(團隊裡和氣最重要是吧?)

而前端規範,最基本的就是EslintPrettier的設置,一個是程式碼規範的檢查器,一個是程式碼格式化的工具。

基本Eslint和Prettier設置

依賴安裝

在同時使用EslintPrettier時,「程式碼質量」和「程式碼格式化」兩者的一些設置會造成衝突。如下圖: image (image from logrocket)

因此需要先解決這個衝突問題。所需要的npm dependency為 eslinteslint-plugin-prettiereslint-config-prettierprettier

npm i -D eslint eslint-plugin-prettier eslint-config-prettier prettier

而各自依賴的作用如下表所示:

依賴 作用
eslint Eslint核心庫
eslint-plugin-prettier 將 Prettier 的規則以plugin的形式加入到Elsint裡面
eslint-config-prettier 關掉所有和 Prettier 衝突的 ESLint 的配置
prettier Prettier核心庫

eslint和prettier設定

安裝好之後,在專案的根目錄下新增.eslintrc.js(也是可以用.eslintrc.json,但JSON檔沒辦法加註釋,所以比較偏好使用.js),再根據 eslint-plugin-prettier 官方的推薦,在.eslintrc.js中撰寫

module.exports = {
  //如果有其他extends的話,要記得把prettier放最後一個
  "extends": ["plugin:prettier/recommended"]
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}

之後,如果要新增prettier的規則(如:tab=4space),便可以改寫在"rules"下的prettier選項:

	"prettier/prettier":[
		"error",
		{
			tabWidth: 4,
		}
	]

或者直接在根目錄中新增檔案.prettierrc ,把規則寫在裡面。

補充:.eslintrc.js中的其他設定項目

module.exports = {
    env: {},
    extends: [],
    overrides: [],
    parser: '',
    parserOptions:{},
    plugins: [],
    rules: {},
    settings: {},
}
  • env:定義環境,可以讓Eslint知道有哪些可用的環境變數,完整文檔可以查看官網,常見的有
    • browser—瀏覽器全局變量,如window
    • node—NodeJS全局變量
    • es6—ECMAScript 6 功能
    • jest—Jest 全局變量
  • extends:根據指定的規範,去檢查指定類型的檔案,如根據@typescript-eslint/recommended去檢查ts程式碼。extends裡面的項目,可以看作「引入別人配置好的.eslintrc.js
    • 如果規則有衝突,後面的會覆蓋前面的。所以官方才建議把prettier放在最後一項。
  • plugins:在Eslint中使用第三方plugin,需要自己手動先npm安裝;可以理解為「加載了插件」,但要在extendsrules定義後才會生效
  • rules:套用的規則。

    • 假設npm下載了@typescript-eslint/eslint-plugin,該如何配置extend、plugin、rule?

      {
          "plugins": [
              "@typescript-eslint"  // 插件聲明    
           ],
          "extends": [
              "eslint:recommended",
              "plugin:@typescript-eslint/recommended" // 這裏是對修改插件下的某一類配置對象的引用。
          ],
          "rules": {
            "@typescript-eslint/rule-name": "error" // 對具體@typescript-eslint插件下的某個規則的使用
          }
      }
      
  • overrides:讓一組文件(通常是看檔案名稱的命名規則)不受規則檢查、或者使用另一種規則來檢查

    • 讓xxx.test.js檔案禁用某個規則

      "rules": {...},
      "overrides": [
      {
        "files": ["*-test.js","*.spec.js"],
        "rules": {
          "no-unused-expressions": "off"
        }
      }
      ]
      
  • parser:Eslint會對程式碼進行檢查,parser的作用是把程式碼轉換成ESTree,然後Eslint再對ESTree再進行檢查校驗。

  • parserOptions:對parser的補充。如預設的 ESLint 並沒有支援所有最新的 ES6 語法,因此若有需要可以加上 { "parserOptions": { "ecmaVersion": 6 } } 的設定。

    • Eslint對ts進行解析的設置:

      parser: '@typescript-eslint/parser',
      parserOptions: {
          ecmaVersion: 'latest',
          sourceType: 'module',
      },
      
  • settings:目前的使用場景,是在專案中有利用webpack.config.jstsconfig.json使用別名import(ex: import xxx from “@/compoments/xxx”),而造成Eslint報錯。在這情況下可以使用settings來解決 Unable to resolve path to module的問題

    • 利用webpack.config.js設定路徑別名時,先npm安裝eslint-import-resolver-webpack,在.eslintrc.js中修改settings:

      "settings": {
      "import/resolver": {
          "webpack":{
              "config":"webpack.config.js"
          }
      }
      }
      
      

VS-code設定

假設專案團隊裡面的成員所使用的IDE都是vscode,可以設置在每次的 on save 時,vscode自動修正 Eslint 和 Prettier 的錯誤:

  1. 在專案root目錄下新增資料夾.vscode
  2. 在該資料夾內新增 settings.json
  3. 撰寫該JSON檔:

    {
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
    },
    "eslint.alwaysShowStatus": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
    "editor.formatOnSave": true
    }
    
    

("[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },這一項,是為了eslint可以format到根目錄的一些js檔,如webpack.config.js等等)

結語

基本上,Eslint+Prettier的設置就完成、接下來就是看團隊共識了。

之後,我們會來看看在Vue/React + Typescript的專案中,還需要多些什麼設置。

ChangeLog

  • 20220911-新增結語
  • 20220901-初稿