模块是 Nuxt 的构建基石。Kit 提供了一组实用工具,帮助你创建和使用模块。你可以使用这些工具创建自己的模块,或者复用现有模块。例如,你可以使用 defineNuxtModule 函数定义一个模块,并通过 moduleDependencies 选项指定依赖关系。
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>
}
definition:模块定义对象或模块函数。模块定义对象应包含以下属性:
| 属性 | 类型 | 必须 | 说明 |
|---|---|---|---|
meta | ModuleMeta | 否 | 模块的元数据。定义模块名称、版本、配置键及兼容性。 |
defaults | T | ((nuxt: Nuxt) => T) | 否 | 模块的默认选项。如果为函数,将传入 Nuxt 实例作为第一个参数。 |
schema | T | 否 | 模块选项的 Schema。如果提供,选项将应用于该 Schema。 |
hooks | Partial<NuxtHooks> | 否 | 要安装的模块钩子。如果提供,模块将安装这些钩子。 |
moduleDependencies | Record<string, ModuleDependency> | ((nuxt: Nuxt) => Record<string, ModuleDependency>) | 否 | 对其他模块的依赖,含版本约束和配置。可为对象或接收 Nuxt 实例的函数。详见 示例。 |
onInstall | (nuxt: Nuxt) => Awaitable<void> | 否 | 模块首次安装时调用的生命周期钩子。需定义 meta.name 和 meta.version。 |
onUpgrade | (options: T, nuxt: Nuxt, previousVersion: string) => Awaitable<void> | 否 | 模块升级到新版本时调用的生命周期钩子。需定义 meta.name 和 meta.version。 |
setup | (this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupInstallResult> | 否 | 模块的 setup 函数。如果提供,模块将在初始化时调用该函数。 |
configKey 使模块可配置定义 Nuxt 模块时,可以设置 configKey,指定用户如何在 nuxt.config 中配置该模块。
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!')
}
},
})
用户可以在 nuxt.config 中通过对应键名为该模块传入选项:
export default defineNuxtConfig({
myModule: {
enabled: false,
},
})
如果你开发的 Nuxt 模块使用了仅在特定 Nuxt 版本支持的 API,强烈建议包含 compatibility.nuxt。
export default defineNuxtModule({
meta: {
name: '@nuxt/icon',
configKey: 'icon',
compatibility: {
// 必需的 Nuxt 版本(semver 格式)
nuxt: '>=3.0.0', // 或使用 '^3.0.0'
},
},
setup () {
const resolver = createResolver(import.meta.url)
// 实现逻辑
},
})
如果用户尝试在不兼容的 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'
// 定义模块选项接口
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 的类型准确为:
// {
// apiKey: string // 必填,无默认值
// baseURL: string // 必填,有默认值
// timeout: number // 可选,有默认值
// retries: number // 可选,有默认值
// }
console.log(resolvedOptions.baseURL) // ✅ TypeScript 知道此属性总是存在
console.log(resolvedOptions.timeout) // ✅ TypeScript 知道此属性总是存在
console.log(resolvedOptions.retries) // ✅ TypeScript 知道此属性总是存在
},
})
如果不使用 .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', // 生命周期钩子必需
configKey: 'myAwesomeModule',
},
defaults: {
apiKey: '',
enabled: true,
},
onInstall (nuxt) {
// 仅在模块首次安装时运行
console.log('首次设置 my-awesome-module!')
// 你可能想:
// - 创建初始配置文件
// - 设置数据库架构
// - 显示欢迎信息
// - 执行补充数据迁移
},
onUpgrade (options, nuxt, previousVersion) {
// 模块升级到新版本时运行
console.log(`将 my-awesome-module 从 ${previousVersion} 升级至 1.2.0`)
// 你可能想:
// - 迁移配置文件
// - 更新数据库架构
// - 清理废弃文件
// - 显示升级说明
if (semver.lt(previousVersion, '1.1.0')) {
console.log('⚠️ 1.1.0 版本含破坏性变更 - 请查看迁移指南')
}
},
setup (options, nuxt) {
// 常规 setup 逻辑,每次构建时运行
if (options.enabled) {
// 配置模块
}
},
})
你可以使用 moduleDependencies 选项声明对其他模块的依赖。这是确保正确初始化顺序、版本兼容和配置管理的可靠方式。
moduleDependencies 可以是对象,也可以是接收 Nuxt 实例的函数:
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
},
moduleDependencies: {
'@nuxtjs/tailwindcss': {
// 指定版本约束(semver 格式)
version: '>=6.0.0',
// 覆盖用户配置
overrides: {
exposeConfig: true,
},
// 设置默认配置但尊重用户设定
defaults: {
config: {
darkMode: 'class',
},
},
},
'@nuxtjs/fontaine': {
// 可选依赖不会自动安装,但若安装允许设置选项
optional: true,
defaults: {
fonts: [
{
family: 'Roboto',
fallbacks: ['Impact'],
},
],
},
},
},
setup (options, nuxt) {
},
})
你也可以使用函数,基于 Nuxt 配置动态确定依赖:
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
},
moduleDependencies (nuxt) {
const dependencies: Record<string, any> = {
'@nuxtjs/tailwindcss': {
version: '>=6.0.0',
},
}
// 根据 Nuxt 配置条件性添加依赖
if (nuxt.options.experimental?.someFeature) {
dependencies['@nuxtjs/fontaine'] = {
optional: true,
}
}
return dependencies
},
setup (options, nuxt) {
// 所有依赖初始化后执行 setup 逻辑
},
})
installModule以编程方式安装指定 Nuxt 模块。当你的模块依赖其他模块时,这非常有用。你可以将模块选项作为对象通过 inlineOptions 传入,这些选项会传递给模块的 setup 函数。
import { defineNuxtModule, installModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup () {
// 会安装带有 Roboto 字体和 Impact 备选字体的 @nuxtjs/fontaine
await installModule('@nuxtjs/fontaine', {
// 模块配置
fonts: [
{
family: 'Roboto',
fallbacks: ['Impact'],
fallbackName: 'fallback-a',
},
],
})
},
})
async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt)
| 属性 | 类型 | 必须 | 说明 |
|---|---|---|---|
moduleToInstall | string | NuxtModule | 是 | 要安装的模块。可以是模块名称字符串或者模块对象。 |
inlineOptions | any | 否 | 传递给模块 setup 函数的模块选项对象。 |
nuxt | Nuxt | 否 | Nuxt 实例。如果未提供,将通过调用 useNuxt() 从上下文获取。 |
import { defineNuxtModule, installModule } from '@nuxt/kit'
export default defineNuxtModule({
async setup (options, nuxt) {
// 会安装带有 Roboto 字体和 Impact 备选字体的 @nuxtjs/fontaine
await installModule('@nuxtjs/fontaine', {
// 模块配置
fonts: [
{
family: 'Roboto',
fallbacks: ['Impact'],
fallbackName: 'fallback-a',
},
],
})
},
})