模組

原始檔
Nuxt Kit 提供了一套實用工具,幫助您建立和使用模組。您可以使用這些工具來建立自己的模組或重用現有模組。

模組是 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>
}

引數

定義:一個模組定義物件或一個模組函式。模組定義物件應包含以下屬性:

屬性型別必需描述
metaModuleMetafalse模組的元資料。它定義了模組名稱、版本、配置鍵和相容性。
defaultsT | ((nuxt: Nuxt) => T)false模組的預設選項。如果提供了函式,它將以 Nuxt 例項作為第一個引數呼叫。
schemaTfalse模組選項的 Schema。如果提供,選項將應用於 Schema。
hooksPartial<NuxtHooks>false要為模組安裝的鉤子。如果提供,模組將安裝這些鉤子。
onInstall(nuxt: Nuxt) => Awaitable<void>false模組首次安裝時呼叫的生命週期鉤子。需要定義 meta.namemeta.version
onUpgrade(options: T, nuxt: Nuxt, previousVersion: string) => Awaitable<void>false模組升級到新版本時呼叫的生命週期鉤子。需要定義 meta.namemeta.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 介面,其中 timeoutretries 即使提供了預設值也可能是 undefined.with() 方法使 TypeScript 能夠理解預設值使這些屬性在解析選項中變為非可選。

使用生命週期鉤子進行模組安裝和升級

您可以定義生命週期鉤子,這些鉤子在模組首次安裝或升級到新版本時執行。這些鉤子對於執行一次性設定任務、資料庫遷移或清理操作非常有用。

要使生命週期鉤子正常工作,您必須在模組定義中同時提供 meta.namemeta.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)

引數

屬性型別必需描述
moduleToInstallstring | NuxtModuletrue要安裝的模組。可以是帶有模組名稱的字串,也可以是模組物件本身。
inlineOptionsanyfalse一個包含要傳遞給模組 setup 函式的模組選項的物件。
nuxtNuxtfalseNuxt 例項。如果未提供,將透過 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',
        },
      ],
    })
  },
})