變成rule的形狀(3) - Prettier + ESLint


Posted by TempuraEngineer on 2022-06-11

Prettier

Prettier是一個formatter,會根據rule去修改coding style,以維持一致性。支援HTML、CSS、SCSS、JS、TS、Vue...等

這篇會介紹Prettier,和如何整合ESLint和Prettier


linter 與 formatter的差異

  1. linters for catching errors, formatters to fix style

    • linters for catching errors
      linter擅長改善語法、抓出潛在的語法錯誤。例如,它會叫你用let/const取代var、===取代==

    Linters can be used as formatters, but they are not the best fit for that.

    The reason for that is that linters have a problem with their initial design.

    Code linters can only deal with imperfections that have only one way of fixing them. For instance, it is considered to be a good practice to use the type-safe equality operators === and !== instead of their regular counterparts == and !=.

    以下是上文翻譯

    linter可以被當作formatter用(使用指令 npx eslint --fix "src/*/.{js,vue}"),但它並不是最佳選擇。

    因為linter的設計上有些問題。

    linter只能處理那些只有一個方式(意指有最佳解)修理的瑕疵。例如,linter認為最好使用===和!==,而不是==和!==

    • formatters to fix style
      formatter擅長修改coding style,根據rules把code變成它的形狀。例如,它不在乎你用var還是let/const,但會禁止你使用""(semi: true)

    Prettier is a code formatter. It parses your code and re-prints it according to a set of opinionated formatting rules.

    Prettier doesn't care about the meaning of the code, only about how it looks.

    以下是上文翻譯

    Prettier是一種formatter,它會根據rules重新編排你的code,而且它很鴨霸(會跟ESLint起衝突)

    Prettier不在乎code的意義(意指語法),只在乎code長怎樣(coding style有沒有遵守規則)

  2. 抽象語法樹(Abstract Syntax Tree)的使用

    linter和formatter都會使用AST,但linter多了一步靜態分析,因此才能改善語法,比formatter慢也是這個原因

    linter uses AST to analyze the code, find out violation, then fix the code just in that place.

    formatter also uses AST but regenerates the code directly from the AST, so code formatter can promise 100% code consistency in the whole codebase,
    and code formatter always fixes code much faster than code linter.


解 ESLint 和 Prettier 衝突的工具

  • eslint-config-prettier
    關掉所有會和Prettier產生衝突的ESLint rule,也會關掉一些已經被廢棄的rule

    另外其中也有一些rule預設被關掉,但可以依自己的需求去打開

    There a few rules that eslint-config-prettier disables that actually can be enabled in some cases.

    例如lines-around-comment,ESLint會要求這樣寫

      if (result) {
    
        /* comment */
        return result;
      }
    

    Prettier則認為註解上面的空行是多餘的

      if (result) {
        /* comment */
        return result;
      }
    

    習慣註解的下一行不要空行的話這樣設定,詳細可以看這篇

      // .eslintrc
    
      rules: {
        'lines-around-comment': [
              'error',
              {
                  afterBlockComment: false, /* 區塊註解的下一行,不強迫空白 */
                  afterLineComment: false, // 單行註解的下一行,不強迫空行
            },
        ],
      }
    
  • eslint-plugin-prettier
    關掉ESLint有關formatting的rule,只留下偵測bug的rule。

    prettier/prettier設為error,可打開eslint-plugin-prettier提供的rule,讓Prettier被當作ESLint的rule來運作

      // .eslintrc
    
      {
          "extends": ["prettier"],
          "plugins": ["prettier"],
          "rules": {
            "prettier/prettier": "error",
          }
      }
    

    另外雖然可以透過.eslintrc.設定Prettier,但不推薦,因為有些Vs Code extensions(ex: prettier-vscode)只讀.prettierrc

      // .eslintrc.js 
      // 透過設定prettier/prettier的secondary option可以傳遞強制用單引號的設定到.prettierrc
    
      "rules": {
          "prettier/prettier": ["error", {"singleQuote": true}],
      }
    


.prettierrc.js的屬性們

```
module.exports = {
    // 縮排,預設2
    indent: 4,

    // 行縮排使用Tab,預設false
    useTabs: true,

    // tab鍵縮排相當於2個空格
    tabWidth: 4,

    // 單行程式碼字元數限制(只要佔位就算長度,例如:let num = 1 + 2;佔16,加上縮排2個則為24),預設80(官方建議)
    printWidth: 100,

    // 語句的末尾加分號
    semi: true,

    // 使用單引號
    singleQuote: true,

    // 只在物件屬性需要引號的時候才加上(例如:{name:'Tempura', 'awesome-skill':'writing kanji'})
    quoteProps: 'as-needed',

    // 物件屬性值尾逗號
    trailingComma: 'all',

    // 在括號和物件的key、value之間加上一個空格
    bracketSpacing: true,

    // vue template 中的起始標籤斷行,預設false(見圖)
    bracketSameLine: true,

    // vue template 中的結束標籤斷行,預設'css'(見圖)
    htmlWhitespaceSensitivity: 'ignore',

    // .vue 檔,<script>、<style>不縮排
    vueIndentScriptAndStyle: false,
};
```


自動排版(auto fix)

修改不符合extends、rules的語法

  • 儲存時自動修改
    本篇整合了Prettier和ESLint,所以使用ESLint。也可以使用Prettier ESLint

    Prettier也有vs code的extension可以用(ex:Prettier - Code formatter),只是在和ESLint整合的情況下還是建議不要,因為會打架。

      "editor.codeActionsOnSave": {
          "source.fixAll.eslint": true,
      }
    


📖

Prettier
prettier/eslint-config-prettier

difference between code linters and formatters
format code vs and lint code

淺談 AST 及 ESlint Rule:AST 是殺毀?(上)


#Prettier #formatter







Related Posts

系統架構 & 資料庫結構 筆記

系統架構 & 資料庫結構 筆記

[FE302] React 基礎 ( hooks 版 ):React 基礎

[FE302] React 基礎 ( hooks 版 ):React 基礎

Higher Order Functions

Higher Order Functions


Comments