透過 100+ 個訣竅學習 Nuxt!
文章·  

Nuxt ESLint 整合功能煥然一新

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

TL;DR(重點摘要)

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

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

終端機
npx nuxi module add eslint

繼續閱讀完整內容,或透過文件深入了解。

背景

ESLint 已成為現今網頁開發不可或缺的工具。它能協助您捕捉錯誤,並在專案中強制執行一致的程式碼風格。在 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-utils 製作了 FlatConfigComposer 公用程式,使覆寫和擴充扁平配置變得更加容易。@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

配置檢查器開發人員工具整合

在遷移和研究新的扁平配置期間,我產生了一個想法,即為扁平配置製作互動式 UI 檢查器,使配置更加透明且易於理解。當您安裝 @nuxt/eslint 模組時,我們已將其整合到 Nuxt DevTools 中,以便您隨時可以輕鬆存取它。

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

檢查器允許您查看已啟用的最終解析配置、規則和外掛程式,並執行快速比對以查看規則和配置如何應用於特定檔案。它非常適合偵錯和學習 ESLint 在您的專案中如何運作。

我們很高興 ESLint 團隊也發現它很有用,並且有興趣將其用於更廣泛的 ESLint 社群。我們稍後加入了這項工作,並使其成為官方 ESLint 配置檢查器(順帶一提,它是使用 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 錯誤時,您都會在主控台和瀏覽器中看到警告。若要深入了解此功能,您可以查看文件

模組鉤子

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

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

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

生態系統

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

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

未來展望

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

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