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
功能使得最終配置結果難以理解和預測。這也使得共用配置難以維護和偵錯。
{
"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
套件中,我們利用靈活性提供了一個工廠函數,讓您能夠以更進階的方式輕鬆自訂配置預設。以下是如何使用它的範例
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt()
@nuxt/eslint-config
從不帶預設立場的基本配置開始,這表示我們僅包含 TypeScript、Vue 和 Nuxt 最佳實務的規則,並將程式碼風格、格式設定等其餘部分留給您決定。您也可以同時執行 Prettier 以使用預設值進行格式設定。
該配置也允許您根據需要選擇加入更多帶有預設立場的功能。例如,如果您希望 ESLint 也負責處理格式設定,您可以透過將 features.stylistic
傳遞給工廠函數來開啟它(由 ESLint Stylistic 支援)
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
export default createConfigForNuxt({
features: {
stylistic: true
}
})
或使用選項物件調整您的偏好設定(在此處深入了解選項)
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 模組開發的規則
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
執行個體
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.vue
、pages/index.vue
、layouts/default.vue
等檔案在其他 Vue 檔案中不可用作元件,並且該規則與它們無關。
通常,我們可以針對這些檔案關閉該規則,例如
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 規則的準確性會降低,並可能導致使用者需要付出額外的努力來手動保持它們一致。
同樣地,我們希望僅針對 pages
和 layouts
等啟用 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 中,以便您隨時可以輕鬆存取它。
檢查器允許您查看已啟用的最終解析配置、規則和外掛程式,並執行快速比對以查看規則和配置如何應用於特定檔案。它非常適合偵錯和學習 ESLint 在您的專案中如何運作。
我們很高興 ESLint 團隊也發現它很有用,並且有興趣將其用於更廣泛的 ESLint 社群。我們稍後加入了這項工作,並使其成為官方 ESLint 配置檢查器(順帶一提,它是使用 Nuxt 建構的)。您可以閱讀這篇公告文章以了解更多詳細資訊。
規則的型別產生
設定 ESLint 的主要痛點之一是規則和配置的型別資訊洩漏。很難知道特定規則有哪些選項可用,而且您需要跳到每個規則的文件中才能弄清楚。
再次感謝新的扁平配置具有如此多的可能性。我們找到了一個新工具 eslint-typegen
,我們可以根據您正在使用的實際外掛程式,從每個規則的規則配置架構產生對應的型別。這表示它是一個適用於任何 ESLint 外掛程式的通用解決方案,而且型別始終準確且保持最新。
在 @nuxt/eslint
模組中,此功能已開箱即用,因此您將立即獲得這種絕佳體驗
開發伺服器檢查器
透過新模組,我們藉此機會將 @nuxtjs/eslint-module
和 ESLint 的開發伺服器檢查器合併到新的 @nuxt/eslint
模組中,作為可選功能。
若要啟用它,您可以將 checker
選項在模組選項中設定為 true
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/config-inspector
- 官方 ESLint 配置檢查器,為您的配置提供互動式 UI。eslint-typegen
- 根據您正在使用的實際外掛程式,為 ESLint 規則產生 TypeScript 型別。eslint-flat-config-utils
- 用於管理和撰寫 ESLint 扁平配置的公用程式。
我們致力於支援更廣泛的社群,並與開發人員合作,以改進這些工具並擴展其可能性。我們很高興看到這些工具如何使 ESLint 生態系統受益,並為整體開發人員體驗做出貢獻。
未來展望
展望未來,我們渴望看到 ESLint 生態系統將如何持續發展,以及我們如何利用新的功能和可能性來進一步增強 Nuxt 的開發人員體驗。我們致力於為 Nuxt 使用者提供無縫且強大的開發環境,我們將繼續探索新的想法並與社群合作以實現此目標。