# Структура модуля

> Как устроены модули Nuxt и как их описывать.

Есть два вида модулей:

- **опубликованные** — в npm; примеры сообщества — [на сайте Nuxt](/modules);
- **локальные** — внутри проекта: [в `nuxt.config`](/docs/3.x/api/nuxt-config#modules) или в [каталоге `modules`](/docs/3.x/directory-structure/modules).

Принцип работы одинаковый.

## Определение модуля

<note>

В стартере точка входа — `src/module.ts`.

</note>

Определение модуля — то, что Nuxt загружает, когда модуль указан в конфигурации.

На низком уровне это простая (возможно асинхронная) функция с пользовательскими опциями и объектом `nuxt`:

```ts
export default function (inlineOptions, nuxt) {
  // Здесь можно делать что угодно..
  console.log(inlineOptions.token) // `123`
  console.log(nuxt.options.dev) // `true` или `false`
  nuxt.hook('ready', (nuxt) => {
    console.log('Nuxt готов')
  })
}
```

Типы удобнее брать через `defineNuxtModule` из [Nuxt Kit](/docs/3.x/guide/going-further/kit):

```ts
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule((options, nuxt) => {
  nuxt.hook('pages:extend', (pages) => {
    console.log(`Найдено страниц: ${pages.length}`)
  })
})
```

**Такой низкоуровневый вид не рекомендуем.** Для публикации в npm лучше **объектный синтаксис** с `meta`.

`defineNuxtModule` закрывает типовые задачи модулей, упрощает совместимость и жизнь авторам и пользователям.

```ts
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    // Обычно имя npm-пакета модуля
    name: '@nuxtjs/example',
    // Ключ в `nuxt.config`, где хранятся опции модуля
    configKey: 'sample',
    // Ограничения совместимости
    compatibility: {
      // Semver-диапазон поддерживаемых версий Nuxt
      nuxt: '>=3.0.0',
    },
  },
  // Дефолтные опции модуля; можно задать функцией, возвращающей объект
  defaults: {},
  // Краткая запись для регистрации хуков Nuxt
  hooks: {},
  // Настройка других модулей: не гарантирует, что они выполнятся до вашего,
  // но позволяет изменить их конфигурацию до их запуска
  moduleDependencies: {
    'some-module': {
      // Semver-диапазон для пакета `some-module`; несовпадение с установленной версией — ошибка при старте Nuxt
      version: '>=2',
      // По умолчанию записи `moduleDependencies` попадают в список модулей к установке Nuxt,
      // если не указано `optional`
      optional: true,
      // Конфигурация, полностью перебивающая `nuxt.options`
      overrides: {},
      // Значения по умолчанию: перебивают дефолты модуля, но не заданное пользователем в `nuxt.options`
      defaults: {},
    },
  },
  // Логика модуля; может быть асинхронной
  setup (moduleOptions, nuxt) {
    // ...
  },
})
```

`defineNuxtModule` возвращает обёртку с сигнатурой `(inlineOptions, nuxt)`. Перед `setup` она:

- подмешивает `defaults` и опции по `meta.configKey`
- даёт типы и вывод типов
- гарантирует однократную установку модуля (ключ из `meta.name` / `meta.configKey`)
- регистрирует хуки из `hooks`
- проверяет совместимость по `meta`
- отдаёт `getOptions` / `getMeta` для внутреннего использования Nuxt
- сохраняет совместимость при обновлении `@nuxt/kit`
- стыкуется со сборкой модуля

## Код рантайма

<note>

В стартере каталог рантайма — `src/runtime/`.

</note>

Сама конфигурация модуля в рантайм приложения не попадает. Чтобы добавить код в приложение пользователя, используйте каталог **runtime** (код времени выполнения).

Туда можно положить всё, что относится к Nuxt-приложению:

- Vue-компоненты
- Композаблы
- [плагины Nuxt](/docs/3.x/directory-structure/plugins)

Для [серверного движка](/docs/3.x/guide/concepts/server-engine) Nitro:

- API-маршруты
- промежуточное ПО сервера (server middleware)
- плагины Nitro

И любые другие артефакты (стили, медиа и т.д.), которые модуль «впрыскивает» в проект.

Подключение — из [определения модуля](#%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F).

<tip>

Про внедрение ресурсов — в [рецептах](/docs/3.x/guide/modules/recipes-basics).

</tip>

<warning>

В **опубликованных** модулях автоимпорты из каталога рантайма **не работают** — импортируйте явно из `#imports` и т.п.
<br />

 <br />


Автоимпорт для файлов в `node_modules` отключён из соображений производительности.

</warning>
