Создание авторских слоёв Nuxt
Слои Nuxt — это мощная возможность, которую вы можете использовать для совместного использования и переиспользования частичных приложений Nuxt в монорепозитории или из git-репозитория или пакета npm. Структура слоёв практически идентична стандартному приложению Nuxt, что упрощает их создание и поддержку.
Базовая директория слоя Nuxt должна содержать файл nuxt.config.ts, указывающий на то, что это слой.
export default defineNuxtConfig({})
Кроме того, некоторые другие файлы в директории слоя будут автоматически сканироваться и использоваться Nuxt для проекта, расширяющего этот слой.
components/*— расширение компонентов по умолчаниюcomposables/*— расширение композаблов по умолчаниюlayouts/*— расширение лейаутов по умолчаниюmiddleware/*— расширение middleware по умолчаниюpages/*— расширение страниц по умолчаниюplugins/*— расширение плагинов по умолчаниюutils/*— расширение утилит по умолчаниюapp.config.ts— расширение конфигурации приложения по умолчаниюserver/*— расширение серверных эндпоинтов и middleware по умолчаниюnuxt.config.ts— расширение конфигурации Nuxt по умолчанию
Базовый пример
export default defineNuxtConfig({
extends: [
'./base',
],
})
Приоритет слоёв
При расширении из нескольких слоёв важно понимать порядок переопределения. Слои с более высоким приоритетом переопределяют слои с более низким приоритетом, если они задают одни и те же файлы или компоненты.
Порядок приоритета от большего к меньшему:
- Файлы вашего проекта — всегда самый высокий приоритет
- Автосканируемые слои из каталога
~~/layers— сортировка по алфавиту (Z выше, чем A) - Слои в конфиге
extends— первый элемент важнее второго
Когда что использовать
extends— для внешних зависимостей (npm-пакеты, удалённые репозитории) или слоёв вне каталога проекта- каталог
~~/layers— для локальных слоёв, которые являются частью проекта
~/layers/1.z-layer, ~/layers/2.a-layer. Тогда 2.a-layer будет иметь приоритет выше, чем 1.z-layer.Пример
export default defineNuxtConfig({
extends: [
// Локальный слой вне проекта
'../base',
// NPM-пакет
'@my-themes/awesome',
// Удалённый репозиторий
'github:my-themes/awesome#v1',
],
})
Если у вас также есть ~~/layers/custom, порядок приоритета такой:
- файлы проекта (наивысший)
~~/layers/custom../base@my-themes/awesomegithub:my-themes/awesome#v1(наинизший)
То есть файлы проекта переопределяют любой слой, а ~~/layers/custom переопределяет всё, что указано в extends.
Начальный шаблон
Для начала вы можете инициализировать слой с помощью шаблона nuxt/starter/layer. Это создаст базовую структуру, на которую вы сможете опираться. Выполните в терминале:
npm create nuxt -- --template layer nuxt-layer
Следуйте инструкциям в README для следующих шагов.
Публикация слоёв
Вы можете публиковать и делиться слоями, используя либо удалённый источник, либо npm-пакет.
Git-репозиторий
Вы можете использовать git-репозиторий, чтобы поделиться своим слоем Nuxt. Некоторые примеры:
export default defineNuxtConfig({
extends: [
// Удалённый источник GitHub
'github:username/repoName',
// Удалённый источник GitHub в каталоге /base
'github:username/repoName/base',
// Удалённый источник GitHub из ветки dev
'github:username/repoName#dev',
// Удалённый источник GitHub с тегом v1.0.0
'github:username/repoName#v1.0.0',
// Пример удалённого источника GitLab
'gitlab:username/repoName',
// Пример удалённого источника Bitbucket
'bitbucket:username/repoName',
],
})
GIGET_AUTH=<token> с токеном доступа.GIGET_GITHUB_URL=<url> или GIGET_GITLAB_URL=<url> — или настройте напрямую опцию auth в nuxt.config.node_modules/.c12/layer_name/node_modules/), куда ваш менеджер пакетов не смотрит.install: true в опциях слоя.export default defineNuxtConfig({
extends: [
['github:username/repoName', { install: true }],
],
})
Пакет npm
Вы можете опубликовать слои Nuxt в виде npm-пакета с файлами и зависимостями, которые хотите расширить. Это позволит поделиться конфигурацией, использовать её в нескольких проектах или приватно.
Для расширения из npm-пакета убедитесь, что модуль опубликован в npm и установлен в проекте пользователя как devDependency. Затем используйте имя модуля в extends:
export default defineNuxtConfig({
extends: [
// scoped-пакет npm
'@scope/moduleName',
// или просто имя модуля
'moduleName',
],
})
Чтобы опубликовать каталог слоя как npm-пакет, заполните в package.json нужные поля — так файлы попадут в публикацию.
{
"name": "my-theme",
"version": "1.0.0",
"type": "module",
"main": "./nuxt.config.ts",
"dependencies": {},
"devDependencies": {
"nuxt": "^3.0.0"
}
}
dependencies. Зависимость nuxt и всё, что нужно только для тестирования слоя до публикации, оставьте в devDependencies.Далее опубликуйте модуль в npm — публично или приватно.
Советы
Именованные алиасы слоёв
Автосканируемые слои (из ~~/layers) получают алиасы автоматически. Например, слой ~~/layers/test доступен как #layers/test.
Для остальных слоёв можно задать имя в конфигурации самого слоя:
export default defineNuxtConfig({
$meta: {
name: 'example',
},
})
Появится алиас #layers/example, указывающий на этот слой.
Относительные пути и алиасы
При импорте через глобальные алиасы (~/, @/ и т.п.) в компонентах и композаблах слоя помните: они разрешаются относительно проекта пользователя, а не слоя. Обходной путь — относительные пути или именованные алиасы слоёв.
Также относительные пути в nuxt.config слоя (кроме вложенных extends) разрешаются относительно проекта пользователя, а не слоя. Используйте полностью разрешённые пути в nuxt.config:
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'
const currentDir = dirname(fileURLToPath(import.meta.url))
export default defineNuxtConfig({
css: [
join(currentDir, './assets/main.css'),
],
})
Отключение модулей из слоёв
Расширяя слой, вы можете отключить входящие в него модули: задайте для ключа конфигурации модуля значение false в своём nuxt.config.
export default defineNuxtConfig({
extends: ['./base-layer'],
// Отключение модулей слоя через ключ конфигурации false
image: false, // отключает @nuxt/image
pinia: false, // отключает @pinia/nuxt
})
image для @nuxt/image, pinia для @pinia/nuxt, content для @nuxt/content. Смотрите документацию модуля.Полезно, когда:
- в слое есть модули, которые вам не нужны
- вы хотите другую реализацию, чем в слое
- нужно отключить аналитику или другие модули в отдельных окружениях
false останавливает выполнение setup модуля, но типы для модуля по-прежнему генерируются.Многослойная поддержка модулей Nuxt
Используйте утилиту getLayerDirectories из Nuxt Kit для своей логики работы со слоями.
import { defineNuxtModule, getLayerDirectories } from 'nuxt/kit'
export default defineNuxtModule({
setup (_options, nuxt) {
const layerDirs = getLayerDirectories()
for (const [index, layer] of layerDirs.entries()) {
console.log(`Слой ${index}:`)
console.log(` Корень: ${layer.root}`)
console.log(` App: ${layer.app}`)
console.log(` Server: ${layer.server}`)
console.log(` Pages: ${layer.appPages}`)
// ... другие каталоги
}
},
})
Примечания:
- более ранние элементы массива имеют более высокий приоритет и переопределяют более поздние
- проект пользователя — первый элемент массива
Углубляясь в тему
Загрузка конфигурации и extends обеспечиваются unjs/c12, слияние — unjs/defu, удалённые git-источники — unjs/giget. Подробнее — в документации и исходниках пакетов.