Nuxt Layers: переиспользование конфигурации и кода между проектами
Nuxt Layers — механизм для переиспользования компонентов, composables, middleware, серверных роутов и конфигурации между проектами. В отличие от модулей, layers имеют структуру, идентичную обычному Nuxt-приложению, что делает их простыми в создании и сопровождении. Этот механизм особенно полезен для монорепозиториев, тем, библиотек компонентов и шаблонов проектов.
В этой статье разберём, как устроены layers, как наследуется приоритет, как подключать их из разных источников и какие паттерны использовать.
Содержание
- Что такое Nuxt Layers
- Структура layer
- Подключение layers
- Наследование и приоритеты
- Именованные алиасы layers
- Переопределение конфигурации
- Паттерны использования
- Layers vs Modules
- Лучшие практики и антипаттерны
- Ключевые тезисы для интервью
- Заключение
- Полезные ссылки
Что такое Nuxt Layers
Nuxt Layers — это способ организации переиспользуемого кода в виде мини-приложений, которые подключаются к основному проекту через extends в nuxt.config.ts. Каждый layer имеет структуру, аналогичную обычному Nuxt-приложению: свои компоненты, composables, middleware, плагины, серверные роуты и конфигурацию.
Основные сценарии использования:
- Переиспользование конфигурации (
nuxt.config,app.config) между проектами. - Создание библиотек компонентов через директорию
components/. - Построение утилит и composables через
composables/иutils/. - Формирование шаблонов проектов и тем.
- Организация кода в монорепозиториях.
Структура layer
Минимальный layer — это директория с файлом nuxt.config.ts. Nuxt автоматически сканирует определённые директории и файлы, если они присутствуют в layer:
my-layer/
├── nuxt.config.ts # Обязательный файл
├── components/ # Компоненты
├── composables/ # Composables
├── utils/ # Утилиты
├── layouts/ # Layouts
├── middleware/ # Middleware
├── pages/ # Страницы
├── plugins/ # Плагины
├── server/ # Серверные роуты и middleware
├── public/ # Статические файлы
└── app.config.ts # Конфигурация приложения
Пример базового layer
// my-layer/nuxt.config.ts
export default defineNuxtConfig({})
<!-- my-layer/components/Button.vue -->
<template>
<button class="layer-button">
<slot />
</button>
</template>
<style scoped>
.layer-button {
padding: 8px 16px;
border-radius: 4px;
background: #3b82f6;
color: white;
border: none;
cursor: pointer;
}
</style>
// my-layer/composables/useTheme.ts
export const useTheme = () => {
const color = useState('theme-color', () => '#3b82f6');
return { color };
};
Подключение layers
Локальные layers
Layers в директории ~/layers/ автоматически регистрируются начиная с Nuxt 3.12.0:
project/
├── layers/
│ ├── base/
│ │ └── nuxt.config.ts
│ └── theme/
│ └── nuxt.config.ts
├── nuxt.config.ts
└── pages/
Для подключения layer из другой директории используйте extends:
// nuxt.config.ts
export default defineNuxtConfig({
extends: [
'./layers/base',
'../shared-theme',
],
});
npm-пакеты
export default defineNuxtConfig({
extends: [
'@my-org/nuxt-layer',
'@my-org/nuxt-admin-theme',
],
});
Git-репозитории
export default defineNuxtConfig({
extends: [
'github:my-org/my-theme',
'github:my-org/my-theme#v1.0.0',
],
});
Для приватных репозиториев с токеном:
export default defineNuxtConfig({
extends: [
['github:my-org/private-theme', { auth: process.env.GITHUB_TOKEN }],
],
});
Наследование и приоритеты
При подключении нескольких layers Nuxt объединяет их файлы с учётом приоритетов. Приоритет от наибольшего к наименьшему:
- Файлы проекта (наивысший приоритет)
- Layers в
~/layers/(в алфавитном порядке) - Layers из
extends(в порядке объявления)
Пример конфликта компонентов
layers/
├── 1.base/
│ └── components/
│ └── Button.vue # Базовый стиль
├── 2.theme/
│ └── components/
│ └── Button.vue # Стиль темы (переопределяет base)
app/
└── components/
└── Button.vue # Проектный компонент (переопределяет всё)
- Если есть только layers, используется
2.theme/Button.vue(выше по алфавиту). - Если
Button.vueесть в проекте, он переопределяет все layers.
Именованные алиасы layers
Начиная с Nuxt 3.16.0, каждый layer в ~/layers/ получает именованный алиас через #layers/имя:
// Доступ к composables из слоя theme
import { useTheme } from '#layers/theme/composables/useTheme';
<script setup>
// Доступ к компонентам из слоя base
import BaseButton from '#layers/base/components/Button.vue';
</script>
Алиасы упрощают обращение к конкретным слоям, особенно когда в проекте подключено несколько layers с похожими файлами.
Переопределение конфигурации
Layers могут расширять и переопределять конфигурацию проекта.
Расширение nuxt.config
Layer может добавить свой заголовок, мета-теги или настройки:
// my-theme/nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
title: 'My Theme',
meta: [
{ name: 'description', content: 'Nuxt theme with custom styling' },
],
},
},
css: ['~/assets/css/theme.css'],
});
Расширение app.config
// my-theme/app.config.ts
export default defineAppConfig({
ui: {
primary: '#3b82f6',
borderRadius: '8px',
},
});
// nuxt.config.ts — переопределение значений из layer
export default defineNuxtConfig({
extends: ['./my-theme'],
appConfig: {
ui: {
primary: '#10b981', // Переопределяет цвет из layer
},
},
});
Отключение модулей из layer
export default defineNuxtConfig({
extends: ['./my-theme'],
// Отключаем модуль, который подключил layer
modules: [],
// Или переопределяем конфиг модуля
image: {
quality: 80,
},
});
Паттерны использования
Библиотека компонентов
Создайте layer с готовыми компонентами и используйте его в нескольких проектах:
ui-lib/
├── nuxt.config.ts
├── components/
│ ├── Button.vue
│ ├── Modal.vue
│ └── Card.vue
└── composables/
└── useModal.ts
Тема для приложения
Layer может содержать layouts, стили и компоненты для оформления:
admin-theme/
├── nuxt.config.ts
├── layouts/
│ └── default.vue
├── components/
│ ├── Sidebar.vue
│ └── Header.vue
├── assets/
│ └── css/
│ └── admin.css
└── middleware/
└── auth.ts
Монорепозиторий с общим кодом
monorepo/
├── packages/
│ ├── shared-nuxt-layer/
│ │ ├── nuxt.config.ts
│ │ ├── composables/
│ │ └── components/
│ ├── app-1/
│ │ ├── nuxt.config.ts # extends: ['../packages/shared-nuxt-layer']
│ │ └── pages/
│ └── app-2/
│ ├── nuxt.config.ts # extends: ['../packages/shared-nuxt-layer']
│ └── pages/
└── package.json
Layers vs Modules
| Критерий | Layers | Modules |
|---|---|---|
| Структура | Идентична Nuxt-приложению | Программатический API |
| Подключение | extends в nuxt.config | modules в nuxt.config |
| Скоуп | Файлы и директории | Хуки и API модулей |
| Переопределение | Автоматическое через приоритет | Ручное через API |
| Использование | Библиотеки, темы, шаблоны | Расширение функционала Nuxt |
| Сложность | Низкая | Средняя–высокая |
Layers подходят для переиспользования файлов (компоненты, страницы, стили). Modules — для программного расширения возможностей Nuxt (добавление хуков, генерация файлов, интеграция с сервисами).
Лучшие практики и антипаттерны
✅ Делайте
- Храните переиспользуемые компоненты и composables в отдельных layers.
- Используйте
app.configдля конфигурации тем и стилей, чтобы проекты могли переопределять значения. - Задавайте имена слоям через
meta.nameдля удобства в логах и отладке. - Используйте
#layers/имядля явного обращения к конкретному layer. - Тестируйте layer изолированно перед подключением к проекту.
- В документации layer указывайте, какие файлы и конфигурации он предоставляет.
❌ Не делайте
- Не размещайте бизнес-логику проекта в layer — layer должен быть переиспользуемым.
- Не полагайтесь на алиасы
~/и@/внутри layer — они резолвятся относительно проекта, а не layer. Используйте относительные импорты или#layers/имя. - Не создавайте глубокую вложенность layers — это затрудняет понимание приоритетов.
- Не подключайте один и тот же layer несколько раз — это приведёт к дублированию кода.
- Не переопределяйте файлы layer напрямую — вместо этого создайте файл с тем же именем в проекте.
Ключевые тезисы для интервью
- Nuxt Layers — механизм переиспользования компонентов, composables, middleware и конфигурации между проектами.
- Структура layer идентична Nuxt-приложению:
components/,composables/,pages/,server/,layouts/,middleware/,plugins/,app.config.ts. - Подключение через
extendsвnuxt.config.tsили автоматически из~/layers/. - Приоритет: проект >
~/layers/(алфавитно) >extends(по порядку объявления). - Именованные алиасы
#layers/имя(с Nuxt 3.16.0) позволяют явно обращаться к конкретному layer. - Layers могут подключаться из локальных директорий, npm-пакетов и git-репозиториев.
- app.config в layer расширяется проектом, что удобно для тем и конфигурации стилей.
- Layers vs Modules: layers — для файлов и структуры, modules — для программного расширения Nuxt.
- Слой должен быть самодостаточным и переиспользуемым — без привязки к конкретному проекту.
- Алиасы
~/и@/внутри layer резолвятся относительно проекта, а не source-директории layer.
Заключение
Nuxt Layers — это элегантное решение для переиспользования кода между проектами. Они позволяют создавать библиотеки компонентов, темы и шаблоны с минимальным количеством boilerplate. Понимание приоритетов наследования, правильное использование алиасов и разделение ответственности между layers и modules — ключ к масштабируемой архитектуре Nuxt-приложений.
Начните с выделения общих компонентов и composables в отдельный layer, подключите его к нескольким проектам и убедитесь, что переопределение конфигурации работает через app.config. Это первый шаг к единообразию и поддерживаемости кодовой базы.
Полезные ссылки
- Nuxt Layers — официальная документация по layers
- Authoring Nuxt Layers — руководство по созданию layers
- Layers Directory — структура директории layers
- Nuxt Kit: Layers API — программный API для работы с layers
- Nuxt Modules — каталог официальных модулей