模組
模組是 Nuxt 的基石。Kit 提供了一套實用工具,幫助您建立和使用模組。您可以使用這些工具來建立自己的模組或重用現有模組。例如,您可以使用 defineNuxtModule
函式來定義模組,並使用 installModule
函式以程式設計方式安裝模組。
defineNuxtModule
定義一個 Nuxt 模組,自動將預設值與使用者提供的選項合併,安裝所有提供的鉤子,並呼叫一個可選的 setup 函式以實現完全控制。
使用
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
defaults: {
enabled: true,
},
setup (options) {
if (options.enabled) {
console.log('My Nuxt module is enabled!')
}
},
})
型別
export function defineNuxtModule<TOptions extends ModuleOptions> (
definition?: ModuleDefinition<TOptions, Partial<TOptions>, false> | NuxtModule<TOptions, Partial<TOptions>, false>,
): NuxtModule<TOptions, TOptions, false>
export function defineNuxtModule<TOptions extends ModuleOptions> (): {
with: <TOptionsDefaults extends Partial<TOptions>> (
definition: ModuleDefinition<TOptions, TOptionsDefaults, true> | NuxtModule<TOptions, TOptionsDefaults, true>
) => NuxtModule<TOptions, TOptionsDefaults, true>
}
引數
定義:一個模組定義物件或一個模組函式。模組定義物件應包含以下屬性:
屬性 | 型別 | 必需 | 描述 |
---|---|---|---|
meta | ModuleMeta | false | 模組的元資料。它定義了模組名稱、版本、配置鍵和相容性。 |
defaults | T | ((nuxt: Nuxt) => T) | false | 模組的預設選項。如果提供了函式,它將以 Nuxt 例項作為第一個引數呼叫。 |
schema | T | false | 模組選項的 Schema。如果提供,選項將應用於 Schema。 |
hooks | Partial<NuxtHooks> | false | 要為模組安裝的鉤子。如果提供,模組將安裝這些鉤子。 |
onInstall | (nuxt: Nuxt) => Awaitable<void> | false | 模組首次安裝時呼叫的生命週期鉤子。需要定義 meta.name 和 meta.version 。 |
onUpgrade | (options: T, nuxt: Nuxt, previousVersion: string) => Awaitable<void> | false | 模組升級到新版本時呼叫的生命週期鉤子。需要定義 meta.name 和 meta.version 。 |
setup | (this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupInstallResult> | false | 模組的 setup 函式。如果提供,模組將呼叫 setup 函式。 |
示例
使用 configKey
使您的模組可配置
在定義 Nuxt 模組時,您可以設定 configKey
來指定使用者應如何在他們的 nuxt.config
中配置該模組。
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule',
},
defaults: {
// Module options
enabled: true,
},
setup (options) {
if (options.enabled) {
console.log('My Nuxt module is enabled!')
}
},
})
使用者可以在 nuxt.config
中對應鍵下為該模組提供選項。
export default defineNuxtConfig({
myModule: {
enabled: false,
},
})
定義模組相容性要求
如果您正在開發 Nuxt 模組並使用僅在特定 Nuxt 版本中支援的 API,強烈建議包含 compatibility.nuxt
。
export default defineNuxtModule({
meta: {
name: '@nuxt/icon',
configKey: 'icon',
compatibility: {
// Required nuxt version in semver format.
nuxt: '>=3.0.0', // or use '^3.0.0'
},
},
setup () {
const resolver = createResolver(import.meta.url)
// Implement
},
})
如果使用者嘗試使用與您的模組不相容的 Nuxt 版本,他們將在控制檯中收到警告。
WARN Module @nuxt/icon is disabled due to incompatibility issues:
- [nuxt] Nuxt version ^3.1.0 is required but currently using 3.0.0
使用 .with()
實現解析選項的型別安全
當您需要解析/合併模組選項的型別安全時,可以使用 .with()
方法。這使得 TypeScript 能夠正確推斷模組預設值與 setup 函式接收的最終解析選項之間的關係。
import { defineNuxtModule } from '@nuxt/kit'
// Define your module options interface
interface ModuleOptions {
apiKey: string
baseURL: string
timeout?: number
retries?: number
}
export default defineNuxtModule<ModuleOptions>().with({
meta: {
name: '@nuxtjs/my-api',
configKey: 'myApi',
},
defaults: {
baseURL: 'https://api.example.com',
timeout: 5000,
retries: 3,
},
setup (resolvedOptions, nuxt) {
// resolvedOptions is properly typed as:
// {
// apiKey: string // Required, no default provided
// baseURL: string // Required, has default value
// timeout: number // Optional, has default value
// retries: number // Optional, has default value
// }
console.log(resolvedOptions.baseURL) // ✅ TypeScript knows this is always defined
console.log(resolvedOptions.timeout) // ✅ TypeScript knows this is always defined
console.log(resolvedOptions.retries) // ✅ TypeScript knows this is always defined
},
})
不使用 .with()
時,resolvedOptions
引數的型別將是原始的 ModuleOptions
介面,其中 timeout
和 retries
即使提供了預設值也可能是 undefined
。.with()
方法使 TypeScript 能夠理解預設值使這些屬性在解析選項中變為非可選。
使用生命週期鉤子進行模組安裝和升級
您可以定義生命週期鉤子,這些鉤子在模組首次安裝或升級到新版本時執行。這些鉤子對於執行一次性設定任務、資料庫遷移或清理操作非常有用。
meta.name
和 meta.version
。鉤子使用這些值來跟蹤專案 .nuxtrc
檔案中的模組安裝狀態。生命週期鉤子在主 setup
函式之前執行,如果鉤子丟擲錯誤,它會被記錄但不會停止構建過程。
onInstall
僅在模組首次新增到專案時執行一次。
onUpgrade
在模組版本增加時(使用 semver 比較)每次執行一次 — 但每個版本只執行一次。
示例
import { defineNuxtModule } from '@nuxt/kit'
import semver from 'semver'
export default defineNuxtModule({
meta: {
name: 'my-awesome-module',
version: '1.2.0', // Required for lifecycle hooks
configKey: 'myAwesomeModule',
},
defaults: {
apiKey: '',
enabled: true,
},
onInstall (nuxt) {
// This runs only when the module is first installed
console.log('Setting up my-awesome-module for the first time!')
// You might want to:
// - Create initial configuration files
// - Set up database schemas
// - Display welcome messages
// - Perform initial data migration
},
onUpgrade (options, nuxt, previousVersion) {
// This runs when the module is upgraded to a newer version
console.log(`Upgrading my-awesome-module from ${previousVersion} to 1.2.0`)
// You might want to:
// - Migrate configuration files
// - Update database schemas
// - Clean up deprecated files
// - Display upgrade notes
if (semver.lt(previousVersion, '1.1.0')) {
console.log('⚠️ Breaking changes in 1.1.0 - please check the migration guide')
}
},
setup (options, nuxt) {
// Regular setup logic runs on every build
if (options.enabled) {
// Configure the module
}
},
})
installModule
以程式設計方式安裝指定的 Nuxt 模組。當您的模組依賴於其他模組時,這很有幫助。您可以將模組選項作為物件傳遞給 inlineOptions
,它們將傳遞給模組的 setup
函式。
使用
import { defineNuxtModule, installModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup () {
// will install @nuxtjs/fontaine with Roboto font and Impact fallback
await installModule('@nuxtjs/fontaine', {
// module configuration
fonts: [
{
family: 'Roboto',
fallbacks: ['Impact'],
fallbackName: 'fallback-a',
},
],
})
},
})
型別
async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt)
引數
屬性 | 型別 | 必需 | 描述 |
---|---|---|---|
moduleToInstall | string | NuxtModule | true | 要安裝的模組。可以是帶有模組名稱的字串,也可以是模組物件本身。 |
inlineOptions | any | false | 一個包含要傳遞給模組 setup 函式的模組選項的物件。 |
nuxt | Nuxt | false | Nuxt 例項。如果未提供,將透過 useNuxt() 呼叫從上下文中檢索。 |
示例
import { defineNuxtModule, installModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup (options, nuxt) {
// will install @nuxtjs/fontaine with Roboto font and Impact fallback
await installModule('@nuxtjs/fontaine', {
// module configuration
fonts: [
{
family: 'Roboto',
fallbacks: ['Impact'],
fallbackName: 'fallback-a',
},
],
})
},
})