模块

源码
Nuxt Kit 提供了一套工具,帮助您创建和使用模块。您可以使用这些工具来创建自己的模块或重用现有模块。

模块是 Nuxt 的构建块。Kit 提供了一套工具,以帮助您创建和使用模块。您可以使用这些工具来创建自己的模块或重用现有模块。例如,您可以使用 defineNuxtModule 函数来定义一个模块,并使用 installModule 函数以编程方式安装模块。

defineNuxtModule

定义一个 Nuxt 模块,自动将默认值与用户提供的选项合并,安装提供的任何钩子,并调用可选的设置函数以获得完全控制。

用法

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: 模块定义对象或模块函数。模块定义对象应包含以下属性:

属性类型是否必需描述
metaModuleMetafalse模块的元数据。定义模块名称、版本、配置键和兼容性。
defaultsT | ((nuxt: Nuxt) => T)false模块的默认选项。如果提供了函数,将会以 Nuxt 实例作为第一个参数调用。
schemaTfalse模块选项的模式。如果提供,选项将应用到模式。
hooksPartial<NuxtHooks>false将为模块安装的钩子。如果提供,模块将安装这些钩子。
setup(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupInstallResult>false模块的设置函数。如果提供,模块将调用设置函数。

示例

使用 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'
    },
  },
  async setup() {
    const resolver = createResolver(import.meta.url)
    // 实现
  },
})

如果用户尝试在不兼容的 Nuxt 版本中使用您的模块,他们将收到控制台中的警告。

 WARN  模块 @nuxt/icon 由于兼容性问题被禁用:
 - [nuxt] 需要 Nuxt 版本 ^3.1.0,但当前使用的是 3.0.0

Type Safety for Resolved Options with .with()

When you need type safety for your resolved/merged module options, you can use the .with() method. This enables TypeScript to properly infer the relationship between your module's defaults and the final resolved options that your setup function receives.

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
  }
})

Without using .with(), the resolvedOptions parameter would be typed as the raw ModuleOptions interface, where timeout and retries could be undefined even when defaults are provided. The .with() method enables TypeScript to understand that default values make those properties non-optional in the resolved options.

installModule

以编程方式安装指定的 Nuxt 模块。这在您的模块依赖其他模块时非常有用。您可以将模块选项作为对象传递给 inlineOptions,并将它们传递给模块的 setup 函数。

用法

import { defineNuxtModule, installModule } from '@nuxt/kit'

export default defineNuxtModule({  
  async setup () {
    // 将安装 @nuxtjs/fontaine,并使用 Roboto 字体和 Impact 后备
    await installModule('@nuxtjs/fontaine', {
      // 模块配置
      fonts: [
        {
          family: 'Roboto',
          fallbacks: ['Impact'],
          fallbackName: 'fallback-a',
        }
      ]
    })
  }
})

类型

async function installModule (moduleToInstall: string | NuxtModule, inlineOptions?: any, nuxt?: Nuxt)

参数

属性类型是否必需描述
moduleToInstallstring | NuxtModuletrue要安装的模块。可以是模块名称的字符串或模块对象本身。
inlineOptionsanyfalse一个对象,包含要传递给模块的 setup 函数的模块选项。
nuxtNuxtfalseNuxt 实例。如果未提供,它将通过 useNuxt() 调用从上下文中检索。

示例

import { defineNuxtModule, installModule } from '@nuxt/kit'

export default defineNuxtModule({  
  async setup (options, nuxt) {
    // 将安装 @nuxtjs/fontaine,并使用 Roboto 字体和 Impact 后备
    await installModule('@nuxtjs/fontaine', {
      // 模块配置
      fonts: [
        {
          family: 'Roboto',
          fallbacks: ['Impact'],
          fallbackName: 'fallback-a',
        }
      ]
    })
  }
})