# [VSCode] 如何設定 eslint 與 prettier 安定地共同協作

我曾經寫過一篇 eslint 與 prettier 協作的文章 (reference: https://z20240.github.io/Tech/Frontend/vue/2022-07-04-vue-nuxt-eslint-prettier-vscode-%E8%A8%AD%E5%AE%9A-%E8%AE%93-eslint-%E8%87%AA%E5%8B%95%E6%8E%92%E7%89%88-nuxt-%E5%B0%88%E6%A1%88/)。當時使用的是 prettier-eslint 這個 extension。

然而隨著專案越寫越多,發現這個 plugin 有許多的限制。

vscode 時常會噴出如下的 error

prettier-eslint [ERROR]: prettier formatting failed due to a prettier error
prettier-eslint-cli [ERROR]: There was an error formatting "/Users/colhoop/Sources/UGP/tms/tms-frontend/custom.d.ts":
    TypeError: Expected `input` to be a `string`, got `object`
        at module.exports (/Users/colhoop/Sources/UGP/tms/tms-frontend/node_modules/indent-string/index.js:11:9)
        at prettify (/Users/colhoop/Sources/UGP/tms/tms-frontend/node_modules/@prettier/eslint/dist/index.js:133:37)
        at format (/Users/colhoop/Sources/UGP/tms/tms-frontend/node_modules/@prettier/eslint/dist/index.js:113:20)
        at async /Users/colhoop/Sources/UGP/tms/tms-frontend/node_modules/prettier-eslint-cli/dist/format-files.js:255:26

而這樣的 error 時常出現在各種不同場合的 TS 專案,又偏偏難以解決。因此我決定重新尋找更加通用的解決方案。

在幾經詢問 ChatGPT 之後,她介紹了我 eslint-plugin-prettier + eslint-config-prettier 的解決方案。

因此我將詢問 chatGPT 的經過整理在這邊,作為一個記錄。

  1. 使用 eslint-plugin-prettier
    這個插件將 Prettier 作為 ESLint 規則運行,所以您只需要修復 ESLint 的問題。它將使用 Prettier 的設定進行格式化,這可以解決 ESLint 和 Prettier 之間的衝突。

  2. 更新你的 .eslintrc.js (或其他相應的 ESLint 配置文件)

module.exports = {
  // ... other ESLint configuration ...
  extends: [
    // ... other extends
    // 注意 plugin:prettier/recommended 必須是最後一個 extends 這樣它可以禁用所有與 Prettier 衝突的 ESLint 規則。
    "plugin:prettier/recommended"
  ],
  plugins: [
    // ... other plugins
    "prettier"
  ],
  rules: {
    // ... other rules
    // 啟用此規則來得知 prettier 的格式錯誤
    "prettier/prettier": "error",
  },
};

這樣,ESLint 和 Prettier 的設定就會同步,不再產生任何衝突。如果您使用的是其他特定的 ESLint 配置或插件(如 eslint-config-airbnb),那麼 eslint-config-prettier 可以幫助您關閉可能與 Prettier 衝突的任何規則。

  1. 確保 vscode 的 default formatter 是 dbaeumer.vscode-eslint , 且僅配置使用 ESLint 進行格式化。
{
  "[typescript]": {
    // 儘讓 eslint 來格式化,不要讓 prettier 格式化
    // "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.defaultFormatter": "dbaeumer.vscode-eslint",
    "editor.formatOnSave": true
  },
  "[javascript]": {
    // 儘讓 eslint 來格式化,不要讓 prettier 格式化
    // "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.defaultFormatter": "dbaeumer.vscode-eslint",
    "editor.formatOnSave": true
  },
  // 關閉 prettier 的格式化功能。
  "prettier.enable": false
}
  1. 設定你自己習慣的 prettier formatter (prettierrc.js)
module.exports = {
  semi: true,
  singleQuote: true,
  trailingComma: "all",
  printWidth: 120,
};
  1. 重啟 vscode: 有時更改設定後,為確保所有配置都正確加載,需要重啟 vscode.

這樣,當你執行 ESLint 時,它會使用 Prettier 的規則進行格式化,並且不會有衝突的問題。

未來所有 rule 不增加在 eslintrc 的 rule 中,而是使用 prettier 來設定規則。

Like z20240z's work