Модули

Исходный код
Утилиты Nuxt Kit для создания и подключения модулей — собственных и сторонних.

Модули — базовые кирпичики Nuxt. Kit даёт утилиты, чтобы описывать модули и подключать их из кода: defineNuxtModule задаёт модуль, installModule — ставит другой модуль программно.

defineNuxtModule

Описывает модуль Nuxt: сливает пользовательские опции с defaults, вешает переданные хуки и при необходимости вызывает 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('Мой модуль Nuxt включён!')
    }
  },
})

Тип

// @errors: 2391
import type { ModuleDefinition, ModuleOptions, NuxtModule } from '@nuxt/schema'
// ---cut---
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Хуки, которые установит модуль.
moduleDependenciesRecord<string, ModuleDependency> | ((nuxt: Nuxt) => Record<string, ModuleDependency>)falseЗависимости от других модулей с ограничениями версий и конфигурацией. См. пример.
onInstall(nuxt: Nuxt) => Awaitable<void>falseВызывается при первой установке модуля. Нужны meta.name и meta.version.
onUpgrade(nuxt: Nuxt, options: T, previousVersion: string) => Awaitable<void>falseВызывается при обновлении версии модуля. Нужны meta.name и meta.version.
setup(this: void, resolvedOptions: T, nuxt: Nuxt) => Awaitable<void | false | ModuleSetupInstallResult>falseФункция настройки модуля.

Примеры

configKey: настраиваемый модуль

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('Мой модуль Nuxt включён!')
    }
  },
})

В nuxt.config опции передаются под этим ключом.

export default defineNuxtConfig({
  myModule: {
    enabled: false,
  },
})

Полностью отключить модуль можно, задав для ключа в nuxt.config значение false: setup не выполнится, но типы для опций модуля по-прежнему генерируются.

export default defineNuxtConfig({
  myModule: false,
})
Особенно полезно отключать модули, унаследованные из слоёв Nuxt.

Требования к совместимости

Если модуль зависит от API определённых версий Nuxt, задайте 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  Модуль @nuxt/icon отключён из‑за проблем совместимости:
 - [nuxt] Требуется Nuxt ^3.1.0, сейчас используется 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 могут оставаться опциональными в типах даже при наличии дефолтов. С .with() типы показывают, что после слияния с дефолтами эти поля заполнены.

Хуки жизненного цикла установки и обновления

Можно задать хуки при первой установке модуля в проект и при обновлении его версии — для разовой настройки, миграций и очистки.

Для хуков нужны оба поля: 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 (nuxt, options, 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) {
    if (options.enabled) {
      // обычная настройка при каждой сборке
    }
  },
})

Указание зависимостей модуля {#specifying-module-dependencies}

Опция moduleDependencies объявляет зависимости от других модулей: порядок инициализации, совместимость версий и конфигурация. Значение — объект или функция (nuxt) => ....

Пример
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    name: 'my-module',
  },
  moduleDependencies: {
    '@nuxtjs/tailwindcss': {
      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',
      },
    }

    if (nuxt.options.experimental?.someFeature) {
      dependencies['@nuxtjs/fontaine'] = {
        optional: true,
      }
    }

    return dependencies
  },
  setup (options, nuxt) {
    // логика после инициализации всех зависимостей
  },
})

installModule

Устарело: используйте moduleDependencies в defineNuxtModule. Функция 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 устанавливаемого модуля.
nuxtNuxtfalseЭкземпляр Nuxt; если не задан — берётся из контекста через 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',
        },
      ],
    })
  },
})