超詳細一次搞定Eslint + Prettier + husky + lint-staged前端程式碼工作流

Kev1n 發表於 2022-07-18
前端

我們使用熱門構建工具vite建立專案,並選擇react + ts模板。關於Eslint + Prettier + husky + lint-staged配置同樣適用於webpack、Vue建立的專案,稍有不同的地方下文會提到,請放心食用。

1、使用vite建立專案

yarn create vite

輸入專案名並選擇 react + ts

success Installed "[email protected]" with binaries:
  - create-vite
  - cva
✔ Project name: … my-app
✔ Select a framework: › react
✔ Select a variant: › react-ts
Done. Now run:

  cd my-app
  yarn
  yarn dev

2、安裝Eslint

yarn add -D eslint

3、初始化配置Eslint

npm init @eslint/config

或者

npx exlint --init

3.1、選擇模式:

選檢查語法並發現問題

? How would you like to use ESLint? …
  To check syntax only
❯ To check syntax and find problems
  To check syntax, find problems, and enforce code style

3.2、選擇模組化語法:

選JavaScript modules

✔ How would you like to use ESLint? · problems
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

3.3、選擇js框架:

選React

? Which framework does your project use? …
❯ React
  Vue.js
  None of these

3.4、是否使用ts

我選擇是

? Does your project use TypeScript? › No / Yes

3.5、選擇程式碼執行環境

用空格選中browser + node

? Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
✔ Node

3.6、 選擇配置檔案格式

選JavaScript

? What format do you want your config file to be in? …
❯ JavaScript
  YAML
  JSON

3.7、安裝三個依賴

選擇是 (eslint解析react和ts的依賴)

The config that you've selected requires the following dependencies:
[email protected] 
@typescript-eslint/[email protected] 
@typescript-eslint/[email protected]
? Would you like to install them now? › No / Yes

3.8、選擇包管理器

選擇yarn

? Which package manager do you want to use? …
  npm
❯ yarn
  pnpm

4、安裝完成

在專案根目錄生成.eslintrc.cjs檔案
這裡就是上面3步驟初始化的檔案,後面的配置都寫這裡

// .eslintrc.cjs
module.exports = {
    env: {
        browser: true,
        es2021: true,
        node: true
      },

    extends: "eslint:recommended", //eslint推薦的規則(過於嚴格)

    parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module'
  },
  rules: {

  }
}

5、繼續安裝依賴

使用vite的同學安裝 vite-plugin-eslint

yarn add -D vite-plugin-eslint

使用webpack的同學安裝 eslint-webpack-plugin

yarn add -D eslint-webpack-plugin

以上兩個依賴的作用都是在yarn dev時自動檢查eslint規範

安裝eslint解析器 @babel/core @babel/eslint-parser

yarn add -D @babel/core             
yarn add -D @babel/eslint-parser

6、配置vite.config.js 或 webpack.config.js

// vite.config.js
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import eslintPlugin from 'vite-plugin-eslint';
export default defineConfig({
  plugins: [
    react(),
    eslintPlugin({
      include: ['src/**/*.tsx', 'src/**/*.ts', 'src/*.ts', 'src/*.tsx'], // eslint校驗的檔案型別
    }),
  ],
});
// webpack.config.js
const ESLintPlugin = require('eslint-webpack-plugin');

module.exports = {
  // ...
  plugins: [new ESLintPlugin(options)],
  // ...
};

7、配置eslintrc.cjs

此處我們使用騰訊的 AlloyTeam Eslint
它會覆蓋eslint推薦的規則,並且相容prettier

yarn add -D eslint-config-alloy
// eslintrc.cjs
module.exports = {
  extends: [
    'alloy',
    'alloy/react',
    'alloy/typescript',
  ],
  env: {
    // 你的環境變數(包含多個預定義的全域性變數)
    //
    // browser: true,
    // node: true,
    // mocha: true,
    // jest: true,
    // jquery: true
  },
  globals: {
    // 你的全域性變數(設定為 false 表示它不允許被重新賦值)
    //
    // myGlobal: false
  },
  rules: {
    // 自定義你的規則
  },
};

8、安裝prettier規範程式碼格式

yarn add -D prettier

安裝後在專案根目錄建立.prettierrc.cjs檔案
AlloyTeam 提供了一套 Prettier 配置,此配置直接繼承。

// .prettierrc.cjs
module.exports = {
  // 一行最多 120 字元
  printWidth: 120,
  // 使用 2 個空格縮排
  tabWidth: 2,
  // 不使用縮排符,而使用空格
  useTabs: false,
  // 行尾需要有分號
  semi: true,
  // 使用單引號
  singleQuote: true,
  // 物件的 key 僅在必要時用引號
  quoteProps: 'as-needed',
  // jsx 不使用單引號,而使用雙引號
  jsxSingleQuote: false,
  // 末尾需要有逗號
  trailingComma: 'all',
  // 大括號內的首尾需要空格
  bracketSpacing: true,
  // jsx 標籤的反尖括號需要換行
  bracketSameLine: false,
  // 箭頭函式,只有一個引數的時候,也需要括號
  arrowParens: 'always',
  // 每個檔案格式化的範圍是檔案的全部內容
  rangeStart: 0,
  rangeEnd: Infinity,
  // 不需要寫檔案開頭的 @prettier
  requirePragma: false,
  // 不需要自動在檔案開頭插入 @prettier
  insertPragma: false,
  // 使用預設的折行標準
  proseWrap: 'preserve',
  // 根據顯示樣式決定 html 要不要折行
  htmlWhitespaceSensitivity: 'css',
  // vue 檔案中的 script 和 style 內不用縮排
  vueIndentScriptAndStyle: false,
  // 換行符使用 lf
  endOfLine: 'lf',
  // 格式化嵌入的內容
  embeddedLanguageFormatting: 'auto',
};

9、配置VScode

安裝Eslint外掛、Prettier外掛

// 配置vscode
// 開啟:設定 -> 文字編輯器 -> 字型 -> 在 settings.json 中編輯
// settings.json檔案
{
  "files.eol": "\n",
  "editor.tabSize": 2,
 // 儲存時將程式碼按照eslint規則修復
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },
 // 預設格式化外掛
  "editor.defaultFormatter": "esbenp.prettier-vscode",
 // 新增eslint支援
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ] 
}

10、安裝並配置husky + lint-staged

安裝依賴

yarn add -D husky
yarn add -D lint-staged

husky

一個為 git 客戶端增加 hook 的工具。安裝後,它會自動在倉庫中的 .husky/ 目錄下增加相應的鉤子;比如 pre-commit 鉤子就會在你執行 git commit 的觸發。我們可以在 pre-commit 中實現一些比如 lint 檢查、單元測試、程式碼美化等操作。

package.json 需要新增 prepare 指令碼

{
  "scripts": {
    "prepare": "husky install"
  }
}

做完以上工作,就可以使用 husky 建立一個 hook 了

npx husky add .husky/pre-commit "npx lint-staged"

lint-staged

一個僅僅過濾出 Git 程式碼暫存區檔案(被 git add 的檔案)的工具;這個很實用,因為我們如果對整個專案的程式碼做一個檢查,可能耗時很長,如果是老專案,要對之前的程式碼做一個程式碼規範檢查並修改的話,這可能就麻煩了,可能導致專案改動很大。所以這個 lint-staged,對團隊專案和開源專案來說,是一個很好的工具,它是對個人要提交的程式碼的一個規範和約束。

此時我們已經實現了監聽 Git hooks,接下來我們需要在 pre-commit 這個 hook 使用 Lint-staged 對程式碼進行 prettier 的自動化修復和 ESLint 的檢查,如果發現不符合程式碼規範的檔案則直接退出 commit。

並且 Lint-staged 只會對 Git 暫存區(git add 的程式碼)內的程式碼進行檢查而不是全量程式碼,且會自動將 prettier 格式化後的程式碼新增到此次 commit 中。

在 package.json 中配置

{
 "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{ts,tsx,js}": [
      "eslint --fix",
      "prettier --write",
      "git add"
    ]
  },
}

對於commit-msg的約束,因為不同公司有各自的規範,本文暫不配置。
綜上,一套完整的Eslint + Prettier + husky + lint-staged前端程式碼工作流就搞定了。