Пишем свой модуль в Nuxt
Сегодня поговорим о модулях в Nuxt, разберемся из чего они состоят, зачем они нужны и разберемся с самым
главным вопросом "Как написать свой модуль?".
Начинаем работу с модулями
Для того чтобы инициализировать новый модуль в Nuxt достаточно просто ввести следуюущую команду:
npx nuxi init -t module nuxt-module-guideline
Данная команда создаст директорию с именем "nuxt-module-guideline", перейдем в нее и увидим следующее:
.
├── package.json
├── playground
│ ├── app.vue
│ ├── nuxt.config.ts
│ ├── package.json
│ ├── server
│ │ └── tsconfig.json
│ └── tsconfig.json
├── pnpm-lock.yaml
├── README.md
├── src
│ ├── module.ts
│ └── runtime
│ └── plugin.ts
├── test
│ ├── basic.test.ts
│ └── fixtures
│ └── basic
│ ├── app.vue
│ ├── nuxt.config.ts
│ └── package.json
└── tsconfig.json
Нас мало интересуют директории
playground
и test
, ибо у них предназначение тестировать
наш модуль, а не разрабатывать его. Самое интересное, естественно, находится в директории src
.Рассматриваем то, что создано темплейтом
Внутри директории
src
есть первый файл который нам нужно рассмотреть - module.ts
:module.ts
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
// Опции плагина
export interface ModuleOptions {}
export default defineNuxtModule<ModuleOptions>({
// Мета-информация модуля
meta: {
name: 'my-module', // Название модуля
configKey: 'myModule' // Название поля для конфигурации модуля в nuxt.config.ts
},
// Значения конфигурации модуля по умолчанию
defaults: {},
// Функция, которая будет выполняться при подключении модуля
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
// Добавляем плагин
addPlugin(resolver.resolve('./runtime/plugin'))
}
});
Как мы можем увидеть функция
setup
определяет что будет подключено к нашему модулю, она может добавлять:- Компоненты;
- Плагины;
- Автоимпорты (services, composables и многое другое);
- Цепляться к хукам в Nuxt;
У функции
setup
также есть два параметра:options
- Конфигурация модуля, которая была задана вnuxt.config.ts
;nuxtApp
- Контекст приложения Nuxt, в котором данный модуль будет использоваться;
Сама функция
defineNuxtModule
имеет дженерик, который принимает интерфейс. Данный интерфейс будет описывать
конфигурацию модуля, которую мы можем задать в nuxt.config.ts
.module.ts
// ...
// Опции плагина
export interface ModuleOptions {
foo: string;
}
export default defineNuxtModule<ModuleOptions>({
// Мета-информация модуля
meta: {
name: 'foo-module', // Название модуля
configKey: 'fooModule' // Название поля для конфигурации модуля в nuxt.config.ts
},
// ...
});
nuxt.config.ts
export default defineNuxtConfig({
// ...
fooModule: {
foo: '123',
},
// ...
})
Расширяем наш модуль
В данном разделе мы будем расширять наш модуль посредством добавления в него разных сущностей.
Начнем с самого простого, и зачастую самого нужного: composable.
Добавление composables в модуль
Тут все достаточно тривиально, для начала нам нужно написать сам composable:
src/composables/hello.ts
export default function () {
console.log('Hello, world!');
}
Данный композабл будет просто выводить "Hello, World!" в консоль. Для того чтобы мы могли подключить его
к модулю достаточно произвести следующие действия в функции
setup
внутри src/module.ts
:src/module.ts
import { defineNuxtModule, addImports, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
// ...
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addImports({
name: 'useHello', // Имя composable
as: 'useHello', // Имя, которое composable будет иметь после импорта модуля
from: resolver.resolve('./composables/hello.ts')
})
}
})
resolver
- это обычный объект, который содержит функцию resolve
.
При передаче в вышеупомянутую функцию относительного пути (напр. ./composable/hello.ts
) - она
отдаст абсолютный путь относительно модуля Nuxt.addImports
в свою очередь служит для того чтобы добавить автоимпорт для всего, чего нам только захочется.Если нам нужно добаить целую директорию - это тоже не составит труда:
src/module.ts
import { defineNuxtModule, addImportsDir, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
// ...
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addImportsDir(resolver.resolve('./composables'))
}
})
Добавление components в модуль
Мы также можем добавить компонент к нашему модулю:
components/hello-world.vue
<template>
<div class="hello">Hello, world!</div>
</template>
После того как мы написали наш компонент мы можем добавить его в модуль:
src/module.ts
import { defineNuxtModule, addComponent, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
// ...
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addComponent(resolver.resolve('./components/hello-world.vue'))
}
})
Мы также можем добавить целую директорию с компонентами:
src/module.ts
import { defineNuxtModule, addComponentsDir, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
// ...
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addComponentsDir(resolver.resolve('./components'))
}
})
Добавление plugins в модуль
Добавление плагина осуществляется ровно тем же способом, что и добавление других сущностей:
src/module.ts
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const { resolve } = createResolver(import.meta.url)
addPlugin(resolve('./plugins/plugin'))
}
})
Помимо того, что мы можем добавить плагины для Nuxt, мы также можем добавить плагины
для Vite и Webpack:
src/module.ts
import { defineNuxtModule, addVitePlugin, addWebpackPlugin, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const { resolve } = createResolver(import.meta.url)
// Добавляем плагин для Vite
addVitePlugin(resolve('./vite/plugin'));
// Добавляем плагин для Webpack
addWebpackPlugin(resolve('./webpack/plugin'));
}
})
Добавление api в модуль
Мы также можем добавить серверную часть в наш модуль:
src/module.ts
import { defineNuxtModule, addServerHandler, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addServerHandler({
route: '/api/hello',
handler: resolver.resolve('./server/api/hello.get.ts')
})
}
})
Добавление types в модуль
Добавление типизации также не составит никакого труда:
src/module.ts
import { defineNuxtModule, createResolver, addTypeTemplate } from '@nuxt/kit';
export default defineNuxtModule({
// ...
setup (moduleOptions, nuxt) {
const { resolve } = createResolver(import.meta.url);
addTypeTemplate({
filename: 'types/module.d.ts',
src: resolve('./types/types.ts')
});
}
});
Добавление других файлов в модуль
Как уже было сказано ранее, мы можем запихнуть все, что только захотим в наш модуль.
Если у вас есть файл, который должен быть доступен для импорта, то мы можем использовать
addTemplate
:src/module.ts
import { defineNuxtModule, createResolver, addTemplate } from '@nuxt/kit';
export default defineNuxtModule({
// ...
setup (moduleOptions, nuxt) {
const { resolve } = createResolver(import.meta.url);
addTemplate({
filename: 'types/module.d.ts',
src: resolve('./otherFile.mjs')
});
}
});