模块
模块是 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',
},
],
})
},
})