透過 100 多個技巧的集合學習 Nuxt!
文章·  

Nuxt ESLint 整合更新

我們改造了 ESLint 整合,以支援使用扁平配置的 ESLint v9,以及一個具有更多功能的新模組。

重點整理

我們改造了 ESLint 整合,以支援使用新的扁平配置的 ESLint v9。在此過程中,我們探索了許多新的可能性,使其更加個人化、強大,並具有更好的開發人員體驗。

您可以執行以下命令來安裝新的 @nuxt/eslint 模組

終端機
npx nuxi module add eslint

繼續閱讀故事或透過文件了解更多資訊。

背景

ESLint 已成為當今 Web 開發的必備工具。它可以幫助您捕捉錯誤並在您的專案中強制執行一致的程式碼風格。在 Nuxt,我們盡力為 ESLint 提供開箱即用的體驗,使其易於使用、配置並遵循我們推薦的最佳實踐。

由於 Nuxt 和 ESLint 都經歷了許多演變。從歷史上看,我們最終在 Nuxt 中為 ESLint 提供了一些不同的套件和整合,而且哪個套件用於什麼目的並不總是顯而易見的。我們收到了來自社群的許多回饋。

為了改善這種情況並使其具有前瞻性,我們最近更新了 ESLint 整合,以支援使用扁平配置ESLint v9。這為客製化您的 ESLint 設定開啟了更多功能,提供更直接和統一的體驗。

Nuxt ESLint Monorepo

我們將分散在不同儲存庫中的 ESLint 相關套件移至單一 monorepo:nuxt/eslint,並設有專用的新文件網站:eslint.nuxt.com

為了幫助理解每個套件之間的差異以及使用哪個套件,我們還提供了一個常見問題頁面來比較它們並解釋它們的範圍。

這個 monorepo 現在包含

  • @nuxt/eslint - 用於 Nuxt 3 的全新、多合一 ESLint 模組,支援專案感知 ESLint 扁平配置和更多功能。
  • @nuxt/eslint-config - 用於 Nuxt 3 的不帶主觀意見但可客製化的共用 ESLint 配置。同時支援扁平配置格式舊版格式
  • @nuxt/eslint-plugin - 用於 Nuxt 3 的 ESLint 外掛程式,提供 Nuxt 特有的規則和配置。
  • 兩個用於維護模式中 Nuxt 2 的套件。

ESLint 扁平配置

在深入研究新的 Nuxt 整合之前,讓我向您介紹ESLint 扁平配置的概念。

扁平配置是 ESLint v8.21.0 中引入的實驗性配置格式,並成為ESLint v9 中的預設格式。

快速參考以區分

  • 扁平配置: eslint.config.js eslint.config.mjs 等。
  • 舊版配置: .eslintrc .eslintrc.json .eslintrc.js 等。

為什麼要使用扁平配置?

ESLint 的這篇部落格文章詳細解釋了扁平配置系統背後的動機。簡而言之,舊版的 eslintrc 格式是在 JavaScript 的早期設計的,當時 ES 模組和現代 JavaScript 功能尚未標準化。其中涉及許多隱含的約定,並且 extends 功能使得最終的配置結果難以理解和預測。這也使得共用配置難以維護和除錯。

.eslintrc
{
  "extends": [
    // Solve from `import("@nuxtjs/eslint-config").then(mod => mod.default)`
    "@nuxtjs",
    // Solve from `import("eslint-config-vue").then(mod => mod.default.configs["vue3-recommended"])`
    "plugin:vue/vue3-recommended",
  ],
  "rules": {
    // ...
  }
}

新的扁平配置將外掛程式和配置解析從 ESLint 的內部約定移至原生 ES 模組解析。這反過來使其更加明確和透明,允許您甚至從其他模組匯入它。由於扁平配置只是一個 JavaScript 模組,它也為更多客製化開啟了大門。

用於扁平配置的 Nuxt 預設

在最新的 @nuxt/eslint-config 套件中,我們利用了靈活性,提供了一個工廠函式,讓您可以更輕鬆地以更高層次的方式客製化配置預設。以下是如何使用它的範例

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt()

@nuxt/eslint-config 從一個不帶主觀意見的基本配置開始,這意味著我們只包含 TypeScript、Vue 和 Nuxt 的最佳實踐規則,並將程式碼風格、格式設定等其餘部分留給您決定。您也可以同時執行 Prettier,以使用預設值進行格式設定。

此配置也允許您根據需要選擇加入更多帶有主觀意見的功能。例如,如果您也希望 ESLint 處理格式設定,您可以透過將 features.stylistic 傳遞給工廠函式來啟用它(由 ESLint Stylistic 提供支援)

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: true
  }
})

或使用選項物件調整您的偏好(在此處了解更多選項

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: {
      semi: false,
      indent: 2, // 4 or 'tab'
      quotes: 'single',
      // ... and more
    }
  }
})

如果您是撰寫 Nuxt 模組,您可以啟用 features.tooling 來啟用 Nuxt 模組開發的規則

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    tooling: true
  }
})

等等。扁平配置中的工廠函式允許預設涵蓋底層 ESLint 配置的複雜性,並為最終使用者提供高階且使用者友善的抽象化以進行客製化。所有這些都不需要使用者擔心內部細節。

雖然此方法為您提供了類似 Prettier 的體驗,並具有最少的配置(因為它由 ESLint 提供支援),但您仍然可以完全靈活地根據需要客製化和覆寫細微的規則和外掛程式。

我們也製作了來自 eslint-flat-config-utilsFlatConfigComposer 工具,讓覆寫和擴充扁平配置變得更加容易。@nuxt/eslint-config/flat 中的工廠函式會傳回 FlatConfigComposer 實例

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  // ...options for Nuxt integration
})
  .append(
    // ...append other flat config items
  )
  .prepend(
    // ...prepend other flat config items before the base config
  )
  // override a specific config item based on their name
  .override(
    'nuxt/typescript', // specify the name of the target config, or index
    {
      rules: {
        // ...override the rules
        '@typescript-eslint/no-unsafe-assignment': 'off'
      }
    }
  )
  // an so on, operations are chainable

使用此方法,我們可以兩全其美:簡單和高階抽象化使其易於使用,以及客製化和微調的功能。

Nuxt ESLint 模組

更進一步,我們為 Nuxt 3 製作了新的多合一 @nuxt/eslint 模組。它利用 Nuxt 的上下文為您的專案產生專案感知和型別安全的 ESLint 配置。

專案感知規則

我們知道 Vue 的樣式指南建議使用多字名稱的元件,以避免與現有和未來的 HTML 元素發生衝突。因此,在 eslint-plugin-vue 中,我們預設啟用了規則 vue/multi-word-component-names。這是一個很好的實踐,但我們知道在 Nuxt 專案中,並非所有 .vue 檔案都註冊為元件。諸如 app.vuepages/index.vuelayouts/default.vue 等檔案在其他 Vue 檔案中不可用作元件,而且該規則與它們無關。

通常,我們可以關閉這些檔案的規則,例如

eslint.config.js
export default [
  {
    files: ['*.vue'],
    rules: {
      'vue/multi-word-component-names': 'error'
    }
  },
  {
    files: ['app.vue', 'error.vue', 'pages/**/*.vue', 'layouts/**/*.vue'],
    rules: {
      // disable the rule for these files
      'vue/multi-word-component-names': 'off'
    }
  }
]

它應該適用於大多數情況。但是,我們知道在 Nuxt 中,您可以自訂每個目錄的路徑,並且圖層允許您為每個目錄擁有多個來源。這表示 Linter 規則的準確性會降低,並且可能會導致使用者付出額外的努力來使它們保持手動對齊。

同樣地,我們希望只對 pageslayouts 等啟用 vue/no-multiple-template-root。隨著案例增加,要求使用者手動維護規則變得不切實際。

這就是 @nuxt/eslint 的魔力所在!它利用 Nuxt 的上下文來產生特定於您的專案結構的配置和規則。非常類似於 Nuxt 提供的 .nuxt/tsconfig.json,您現在也有專案感知的 .nuxt/eslint.config.mjs 可以從中擴充。

若要使用它,您可以將模組新增至您的 Nuxt 專案

終端機
npx nuxi module add eslint

Config Inspector 開發人員工具整合

在新的扁平配置的移轉和研究期間,我想到為扁平配置製作一個互動式 UI 檢查器,並使配置更加透明且易於理解。當您安裝 @nuxt/eslint 模組時,我們已將其整合到 Nuxt 開發人員工具中,因此您可以隨時輕鬆存取它。

Screenshot of ESLint Config Inspector running as a tab in Nuxt DevTools

此檢查器可讓您查看已啟用的最終解析配置、規則和外掛程式,並進行快速比對,以查看規則和配置如何應用於特定檔案。它對於除錯和了解 ESLint 在您的專案中如何運作非常有用。

我們很高興 ESLint 團隊也覺得它很有用,並有興趣將其用於更廣泛的 ESLint 社群。我們隨後加入了這項工作,並使其成為官方 ESLint Config Inspector(順便說一句,它是使用 Nuxt 建置的)。您可以閱讀這篇公告文章,以了解更多詳細資訊。

規則的型別產生

配置 ESLint 的主要痛點之一是規則和配置的型別資訊洩漏。很難知道特定規則有哪些選項可用,而且您需要跳到每個規則的文件中才能找出答案。

再次感謝新的扁平配置具有如此多的可能性的動態性。我們找到了一個新工具,eslint-typegen,我們可以根據您正在使用的實際外掛程式,從每個規則的規則配置架構產生相應的型別。這表示這是一個適用於任何 ESLint 外掛程式的通用解決方案,而且這些型別始終準確且保持最新。

@nuxt/eslint 模組中,此功能已內建整合,讓您能立即享有絕佳體驗

Screenshot of VS Code that showcases the type check and autocomplete with ESLint rules config

開發伺服器檢查器

透過新的模組,我們藉此機會將 @nuxtjs/eslint-module 以及 ESLint 的開發伺服器檢查器合併到新的 @nuxt/eslint 模組中,作為可選功能。

您可能在大多數時候不需要此功能,因為您的編輯器整合應該已經在編輯器中提供 ESLint 診斷。然而,對於一些使用不同編輯器的團隊,並且希望確保 ESLint 始終運行,在某些情況下,能夠在開發伺服器中執行 ESLint 可能會有所幫助。

若要啟用它,您可以在模組選項中將 checker 選項設定為 true

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/eslint'
  ],
  eslint: {
    checker: true // <---
  }
})

每當您遇到一些 ESLint 錯誤時,您會在主控台和瀏覽器中看到警告。若要了解有關此功能的更多資訊,您可以查閱文件

模組 Hook

既然我們現在位於具有程式碼生成功能和專案感知配置的 Nuxt 模組中,實際上我們可以做更多有趣的事情。其中一項是我們可以允許模組也為 ESLint 配置做出貢獻。想像一下,未來當您安裝像是 @nuxtjs/i18n 的 Nuxt 模組時,它可以自動啟用與 i18n 相關檔案的特定 ESLint 規則,或者當您安裝像是 @pinia/nuxt 的模組時,它可以安裝 Pinia ESLint 外掛程式,以強制執行 Pinia 的最佳實踐等。

作為一個實驗,我們製作了一個名為 nuxt-eslint-auto-explicit-import 的模組,可以使用預先配置的 ESLint 預設值,為您 Nuxt 專案中註冊的自動導入執行自動插入。這樣您在使用 API 進行自動導入時,可以獲得相同的良好開發體驗,但仍然可以在程式碼庫中擁有自動插入的明確導入。

這仍然處於早期階段,我們仍在探索可能性和最佳實踐。但是,我們對其潛力和它所開啟的機會感到非常興奮。我們將與社群合作,看看如何充分利用它。如果您有任何想法或回饋,請隨時與我們分享!

生態系統

在 Nuxt,我們始終非常關心生態系統和社群。在我們探索採用新的扁平化配置並改善開發人員體驗的過程中,我們製作了一些工具來實現這個目標。它們都是通用工具,可以在 Nuxt 之外使用

我們致力於支持更廣泛的社群,並與開發人員合作,以改進這些工具並擴展其可能性。我們很高興看到這些工具如何使 ESLint 生態系統受益,並為整體開發人員體驗做出貢獻。

未來

扁平化配置格式仍然相當新,而 ESLint v9 幾週前才剛發布。外掛程式和社群正在逐步趕上新的格式。它仍處於探索和實驗的階段。

展望未來,我們很期待看到 ESLint 生態系統將如何繼續發展,以及我們如何利用新的功能和可能性來進一步增強 Nuxt 的開發人員體驗。我們致力於為 Nuxt 用戶提供無縫且強大的開發環境,我們將繼續探索新想法並與社群合作以實現此目標。