<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          [譯] 以和為貴!讓 ESlint、Prettier 和 EditorConfig 互不沖突

          共 9748字,需瀏覽 20分鐘

           ·

          2021-06-10 12:10

          原文鏈接:https://blog.theodo.com/2019/08/empower-your-dev-environment-with-eslint-prettier-and-editorconfig-with-no-conflicts/

          ESLint, Prettier and EditorConfig

          來由

          如果你已經(jīng)在搭配使用 Prettier 和 ESLint, 可能已經(jīng)遇到過 代碼格式化沖突 的問題了吧。

          ESLint - Prettier conflict

          我曾在一次把 TypeScript 項目從 TSLint 遷移到 ESLint 的工作中遇到過這些問題。我們打算用 ESLint 和 Prettier 接管語法檢查,在添加了一條 ESLint 規(guī)則強(qiáng)制規(guī)定 2 個空格縮進(jìn)以解決上圖中的問題后,其他問題又像按下葫蘆浮起瓢一樣紛紛出現(xiàn)了,很明顯沒法子通過一條條增加規(guī)則解決每一個沖突。

          網(wǎng)上關(guān)于這個話題的確有很多說法,但大部分都是針對某個特定項目給出一個配置,而非深入闡釋為什么 ESLint、Prettier 或 EditorConfig 會八字不合。本文的目的就是對這些潛在的問題解惑,以免相關(guān)的 bug 再干擾調(diào)試。

          策略

          我們先來明確一下 各司其職 的原則:

          • EditorConfig 將負(fù)責(zé)統(tǒng)一各種編輯器的配置,所有和編輯器相關(guān)的配置 (行尾、縮進(jìn)樣式、縮進(jìn)距離...) 都交給它
          • Prettier 作為 代碼格式化 工具
          • 其余的,也就是 代碼質(zhì)量 方面的語法檢查,用 ESLint 來做

          ESLint 和 Prettier

          假設(shè)我們有這么一個 main.js,并同時配置了 ESLint 和 Prettier。

          main.js

          function printUser(firstName, lastName, number, street, code, city, country{
              console.log(`${firstName} ${lastName} lives at ${number}${street}${code} in ${city}${country}`);
          }
          printUser('John''Doe'48'998 Primrose Lane'53718'Madison''United States of America');

          eslintrc.json

          {
            "extends": ["eslint:recommended"],
            "env": {
              "es6"true,
              "node"true
            }
          }

          讓 Prettier 做它自己的工作

          為了能 配合使用 ESLint 和 Prettier,應(yīng)該 關(guān)閉所有可能和 Prettier 沖突的 ESLint 規(guī)則 (也就是 代碼格式化 那些)。好消息是,eslint-config-prettier 包已經(jīng)解決了這個問題。

          npm install eslint-config-prettier --save-dev

          先在 .eslintrc.json 中,將 prettier 加到 extends 數(shù)組的最后,并移除任何 代碼格式化 相關(guān)的規(guī)則:

          {
            "extends": ["eslint:recommended""prettier"],
            "env": {
              "es6"true,
              "node"true
            }
          }

          如此一來, Prettier 的配置將覆蓋 extends 數(shù)組中先前任何 代碼格式化 相關(guān)的 ESLint 配置,二者就能并行不悖地工作了。

          將 Prettier 整合進(jìn) ESLint

          分別運行兩條命令以檢查語法和格式化代碼可不太方便,我們可以通過安裝 eslint-plugin-prettier 包來解決這個問題。

          npm install eslint-plugin-prettier --save-dev

          .eslintrc.jsonplugins 數(shù)組中加入 prettier 插件,并建立一條指定為  error  的 Prettier 新規(guī)則,這樣任何格式化錯誤就也被認(rèn)為是 ESLint 錯誤了。

          {
            "extends": ["eslint:recommended""prettier"],
            "env": {
              "es6"true,
              "node"true
            },
            "rules": {
              "prettier/prettier""error"
            },
            "plugins": [
              "prettier"
            ]
          }

          main.js 運行 ESLint 試一下:

          npx eslint main.js
          ESLint no fix

          可以看到,那些字符過多或縮進(jìn)錯誤的行,都被標(biāo)以了 prettier/prettier 并作為 ESLint 錯誤被打印出來。

          修復(fù)之:

          npx eslint --fix main.js

          文件將按 Prettier 的方式被正確格式化。

          Prettier 和 ESLint 配合中的常見問題

          添加 ESLint 插件

          以上的配置應(yīng)付小項目綽綽有余;但當(dāng)你使用 Vue、React 或其他框架時,還是 很容易讓 ESLint 和 Prettier 的配置打架。我遇到的一個常見問題是當(dāng)開發(fā)者增加一個 ESLint 插件后,如何在不同時改動 Prettier 的情況下,也能讓后者正常工作。

          以 TypeScript 為例

          出于某些考慮,我們決定在項目中使用 TypeScript。鑒于 TSLint 將被廢棄,自然要用 ESLint 取而代之。這里就使用 TypeScript 作為一個例子,來展示 對于有一個適用的 ESLint 插件的框架,該如何處理

          這是進(jìn)行了 TypeScript 改造后的 main.ts 文件:

          function printUser(firstName: string, lastName: stringnumbernumber, street: string, code: number, city: string, country: string): void {
           console.log(`${firstName} ${lastName} lives at ${number}${street}${code} in ${city}${country}`);
          }
          printUser('John''Doe'48'998 Primrose Lane'53718'Madison''United States of America');

          要想讓 ESLint 兼容 TypeScript 或是其他什么特殊語法的框架,需要增加一個 parser 以使 ESLint 可以讀取新的代碼和相關(guān)的一系列規(guī)則。

          npm install typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev

          然后修改 .eslintrc.json,分別向 parser 選項和 extends 數(shù)組中包含 TypeScript 插件:

          {
            "parser""@typescript-eslint/parser",
            "extends": ["plugin:@typescript-eslint/recommended""eslint:recommended""prettier"],
            "env": {
              "es6"true,
              "node"true
            },
            "rules": {
              "prettier/prettier""error"
            },
            "plugins": [
              "prettier"
            ]
          }

          帶上 --fix 選項,再來試試 ESLint:

          eslint-fix-option

          這時如果我們多次執(zhí)行這條命令,每次都將得到同樣的報錯 -- 盡管控制臺里面說錯誤是可以被修復(fù)的。此時文件被修改為了這樣:

          function printUser(
            firstName: string,
            lastName: string,
            numbernumber,
            street: string,
            code: number,
            city: string,
            country: string
          ): void 
          {
            console.log(
              `${firstName} ${lastName} lives at ${number}${street}${code} in ${city}${country}`
            );
          }

          printUser(
            'John',
            'Doe',
            48,
            '998 Primrose Lane',
            53718,
            'Madison',
            'United States of America'
          );

          所以 Prettier 的確格式化了我們的代碼,但 ESLint 期望的 4 個空格沒有被滿足。錯誤看起來和 @typescript-eslint 規(guī)則有關(guān)。

          如果你像我一樣在使用 VSCode 并開啟了保存時自動執(zhí)行 ESLint 修復(fù),可能會看到這種情況:

          Conflict between typescript eslint and prettier

          通過禁用新增插件的所有 ESLint 格式化規(guī)則解決沖突

          很多人的一個常見錯誤就是頭疼醫(yī)頭、腳疼醫(yī)腳。比如對于這個 @typescript-eslint 插件里面的縮進(jìn)規(guī)則,他們會往 rules 數(shù)組中添加一條這樣的規(guī)則:

          "@typescript-eslint/indent": ["error"2]

          這當(dāng)然解決了具體沖突,但有兩個問題出現(xiàn)了:

          • 無法保證 typescript-eslint 插件中的其他規(guī)則今后不和 Prettier 沖突
          • ESLint 和 Prettier 又開始同時負(fù)責(zé)代碼格式化了,這違背了我們的分工策略

          按照之前的整合方法,通過在 extends 數(shù)組中增加 prettier/@typescript-eslint 來禁用相關(guān)插件中所有關(guān)乎 代碼格式化 的規(guī)則。

          {
            "parser""@typescript-eslint/parser",
            "extends": ["plugin:@typescript-eslint/recommended""eslint:recommended""prettier""prettier/@typescript-eslint"],
            "env": {
              "es6"true,
              "node"true
            },
            "rules": {
              "prettier/prettier""error"
            },
            "plugins": [
              "prettier"
            ]
          }

          謹(jǐn)記 .eslintrc.jsonextends 數(shù)組的順序非常重要。基本上每次向數(shù)組添加新配置時,都將覆蓋之前的配置。因此 prettierprettier/@typescript-eslint 待在數(shù)組末尾至關(guān)重要。

          這樣配置后就沒問題了,ESLint 將不會再越俎代庖。

          總結(jié)一下這種常見問題:

          • 每當(dāng)你添加一個 ESLint 插件,針對 它引入的 代碼格式化 規(guī)則 添加一個 prettier 配置 (如果有的話) 。在我們的例子中,使用了 prettier/@typescript-eslint,但其實我們也可以用 prettier/reactprettier/vue。檢查 eslint\-config\-prettier 文檔(https://github.com/prettier/eslint-config-prettier) 獲取可用的 ESLint 插件。
          • 不要嘗試自己覆蓋 eslintrc 中的格式化規(guī)則
          • 每當(dāng)你見到這種 Prettier 和 ESLint 對同一種格式化的沖突,就以為著你有一條無用的 ESLint 格式化規(guī)則,也意味著你沒有遵守以上兩條

          添加一條自定義規(guī)則

          項目團(tuán)隊中的 TypeScript 開發(fā)者對 2 個空格縮進(jìn)渾身不舒服,非要改成 4 個。一個常見的錯誤是把我們的 ESLint-Prettier 整合策略拋之腦后,并在 .eslintrc.json 中直接添加規(guī)則,就像這樣:

          {
            "parser""@typescript-eslint/parser",
            "extends": ["plugin:@typescript-eslint/recommended""eslint:recommended""prettier""prettier/@typescript-eslint"],
            "env": {
              "es6"true,
              "node"true
            },
            "rules": {
              "prettier/prettier""error",
              "@typescript-eslint/indent": ["error"4]
            },
            "plugins": [
              "prettier"
            ]
          }

          熟悉的錯誤毫無意外地又出現(xiàn)了,和我們之前解決 Prettier 協(xié)同 ESLint 時遇到的一摸一樣:

          Conflict with custom rule

          rules 數(shù)組中自定義的規(guī)則會覆蓋 prettier/@typescript-eslint 配置。

          按照正確的策略,代碼格式化 規(guī)則應(yīng)該在 .prettierrc 中配置。對于例子來說,應(yīng)該是:

          .prettierrc

          {
            "tabWidth"4
          }

          這樣 Prettier 將以 4 個空格格式化代碼,而 .eslintrc.json 應(yīng)該不關(guān)心任何縮進(jìn)規(guī)則。

          總結(jié)一下這種常見問題:

          • 當(dāng)你想添加一條規(guī)則時,分清其屬于 代碼質(zhì)量 還是 代碼格式化 類別。簡單地做法是,檢查這條規(guī)則在 Prettier 中是不是可行的
          • 不要在 .eslintrc.json 中添加格式化規(guī)則,這樣做將不可避免的和 Prettier 沖突

          Prettier 和 EditorConfig

          設(shè)置編輯器配置

          EditorConfig 使不同編輯器可以保持同樣的配置。因此,我們得以無需在每次編寫新代碼時,再依靠 Prettier 來按照團(tuán)隊約定格式化一遍(譯注:出現(xiàn)保存時格式化突然改變的情況)。當(dāng)然這需要在你的 IDE 上安裝了必要的 EditorConfig 插件或擴(kuò)展。

          本文以 VSCode 為例,但 EditorConfig 支持很多編輯器。

          在項目中增加自定義的編輯器配置:

          .editorconfig

          [*]
          end_of_line = lf
          charset = utf-8
          indent_style = space

          如果安裝了 the EditorConfig VSCode extension,編輯器將自動獲知該如何格式化你的文件。你也能在編輯器右下角看到相應(yīng)的信息:

          vscode

          避免 EditorConfig 和 Prettier 的重復(fù)配置

          但是,這意味著 Prettier 和 EditorConfig 共享了相同的配置選項,而我們不希望同步維護(hù)兩份重復(fù)的配置 (比如關(guān)于行尾的配置)。Prettier 的最新版本通過處理 .editorconfig 文件來決定使用的配置。

          限于以下幾種選項:

          end_of_line
          indent_style
          indent_size/tab_width
          max_line_length

          這些選項會被映射為 Prettier 的相關(guān)選項 (如果沒有在 .prettierrc 再被定義的話):

          "endOfLine"
          "useTabs"
          "tabWidth"
          "printWidth"

          就像 ESLint 配合 Prettier 時的策略那樣,在你改變 EditorConfig 或 Prettier 配置時,根據(jù)這些限定選項來決定在哪邊改。上面例子中的選項就應(yīng)該只在 .editorconfig 中存在。

          據(jù)此再檢查我們上面做過的所有配置,還能發(fā)現(xiàn)一個配置錯誤。我們在 Prettier 配置中指定了縮進(jìn)距離。因為這也是一個瀏覽器相關(guān)的配置,所以應(yīng)該將其移至 .editorconfig

          .editorConfig

          tab_width 4

          現(xiàn)在我們刪除了已經(jīng)空白的 .prettierrc.json,并對未格式化的代碼運行 ESLint:

          function printUser(
              firstName: string,
              lastName: string,
              numbernumber,
              street: string,
              code: number,
              city: string,
              country: string
          ): void 
          {
              console.log(
                  `${firstName} ${lastName} lives at ${number}${street}${code} in ${city}${country}`
              );
          }

          printUser(
              "John",
              "Doe",
              48,
              "998 Primrose Lane",
              53718,
              "Madison",
              "United States of America"
          );

          代碼縮進(jìn)變成了 4 個空格。現(xiàn)在,無論你在何時用編輯器打開一個新文件,都會應(yīng)用這個配置,Prettier 同樣也會遵循。




          --End--

          查看更多前端好文
          請搜索 云前端 或 fewelife 關(guān)注公眾號

          轉(zhuǎn)載請注明出處


          瀏覽 142
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区二 三区免费 | 在线高清免费无码 | 欧美男女操逼视频 | 无码操人| 三级久久网 |