Слои (layers)
Слои Nuxt переиспользуют и наращивают код между проектами. В модулях часто нужны абсолютные пути каталогов каждого слоя — для этого служит getLayerDirectories.
getLayerDirectories
Возвращает массив структур с абсолютными путями каталогов для каждого слоя приложения — стабильный API вместо nuxt.options._layers.
Использование
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
export default defineNuxtModule({
setup () {
const layerDirs = getLayerDirectories()
// Каталоги всех слоёв
for (const [index, layer] of layerDirs.entries()) {
console.log(`Слой ${index}:`)
console.log(` Корень: ${layer.root}`)
console.log(` Приложение: ${layer.app}`)
console.log(` Сервер: ${layer.server}`)
console.log(` Страницы: ${layer.appPages}`)
// ... другие каталоги
}
},
})
Тип
// @errors: 2391
import type { Nuxt } from '@nuxt/schema'
// ---cut---
function getLayerDirectories (nuxt?: Nuxt): LayerDirectories[]
interface LayerDirectories {
/** Корень Nuxt, `rootDir` (по умолчанию `/`) */
readonly root: string
/** Исходный каталог Nitro (по умолчанию `/server`) */
readonly server: string
/** Локальный каталог модулей (по умолчанию `/modules`) */
readonly modules: string
/** Общий каталог (по умолчанию `/shared`) */
readonly shared: string
/** Публичный каталог (по умолчанию `/public`) */
readonly public: string
/** Исходный каталог Nuxt, `srcDir` (по умолчанию `/app/`) */
readonly app: string
/** Каталог лейаутов (по умолчанию `/layouts`) */
readonly appLayouts: string
/** Каталог прослоек маршрутов (по умолчанию `/middleware`) */
readonly appMiddleware: string
/** Каталог страниц (по умолчанию `/pages`) */
readonly appPages: string
/** Каталог плагинов (по умолчанию `/plugins`) */
readonly appPlugins: string
}
Параметры
nuxt (необязательно): экземпляр Nuxt. Если не передан, используется текущий контекст Nuxt.
Возвращаемое значение
Функция возвращает массив объектов LayerDirectories — по одному на каждый слой.
Порядок приоритета слоёв:
- Первый слой — слой пользователя/проекта (наивысший приоритет)
- Более ранние элементы массива перекрывают более поздние
- Базовые слои идут в конце массива (низший приоритет)
Это совпадает с тем, как Nuxt накладывает слои: файлы и настройки проекта имеют приоритет над базовыми слоями.
LayerDirectories: разрешённые пути каталогов для слоя.
| Свойство | Тип | Описание |
|---|---|---|
root | string | Корень слоя (аналог rootDir) |
server | string | Каталог сервера Nitro |
modules | string | Локальный каталог модулей |
shared | string | Общий каталог для клиента и сервера |
app | string | Исходный каталог слоя (аналог srcDir) |
public | string | Публичный каталог статики |
appLayouts | string | Каталог лейаутов Vue |
appMiddleware | string | Каталог route middleware |
appPages | string | Каталог страниц (маршрутизация по файлам) |
appPlugins | string | Каталог плагинов Nuxt |
Примеры
Обработка файлов из всех слоёв:
// @errors: 2307
// ---cut---
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
import { resolve } from 'pathe'
import { globby } from 'globby'
export default defineNuxtModule({
async setup () {
const layerDirs = getLayerDirectories()
// Все компоненты по слоям
// layerDirs[0] — слой пользователя (наивысший приоритет)
// Дальше по массиву — меньший приоритет
const componentFiles = []
for (const [index, layer] of layerDirs.entries()) {
const files = await globby('**/*.vue', {
cwd: resolve(layer.app, 'components'),
absolute: true,
})
console.log(`Слой ${index} (${index === 0 ? 'пользователь' : 'базовый'}):`, files.length, 'компонентов')
componentFiles.push(...files)
}
},
})
Шаблоны из нескольких слоёв:
import { addTemplate, defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
import { basename, resolve } from 'pathe'
import { existsSync } from 'node:fs'
export default defineNuxtModule({
setup () {
const layerDirs = getLayerDirectories()
// Конфиг из каждого слоя, где он есть
for (const dirs of layerDirs) {
const configPath = resolve(dirs.app, 'my-module.config.ts')
if (existsSync(configPath)) {
addTemplate({
filename: `my-module-${basename(dirs.root)}.config.ts`,
src: configPath,
})
}
}
},
})
С учётом приоритета слоёв:
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
import { resolve } from 'pathe'
import { existsSync, readFileSync } from 'node:fs'
export default defineNuxtModule({
setup () {
const layerDirs = getLayerDirectories()
// Первый (самый приоритетный) слой с нужным конфигом
let configContent = null
for (const dirs of layerDirs) {
const configPath = resolve(dirs.app, 'my-config.json')
if (existsSync(configPath)) {
configContent = readFileSync(configPath, 'utf-8')
console.log(`Конфигурация из слоя: ${dirs.root}`)
break
}
}
// Вариант: собрать конфиги со всех слоёв, слой пользователя побеждает
const allConfigs = {}
for (const dirs of layerDirs.reverse()) {
const configPath = resolve(dirs.app, 'my-config.json')
if (existsSync(configPath)) {
const config = JSON.parse(readFileSync(configPath, 'utf-8'))
Object.assign(allConfigs, config)
}
}
},
})
Проверка каталогов в слоях:
import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
import { existsSync } from 'node:fs'
import { resolve } from 'pathe'
export default defineNuxtModule({
setup () {
const layerDirs = getLayerDirectories()
const layersWithAssets = layerDirs.filter((layer) => {
return existsSync(resolve(layer.app, 'assets'))
})
console.log(`Слоёв с каталогом assets: ${layersWithAssets.length}`)
},
})
getLayerDirectories кэширует результат в WeakMap, повторные вызовы с тем же nuxt не пересчитывают пути.