图层

源码
Nuxt Kit 提供了用于帮助您处理图层及其目录结构的实用工具。

Nuxt 图层提供了一种在项目之间共享和扩展功能的强大方式。在模块中处理图层时,您经常需要访问每个图层的目录路径。Nuxt Kit 提供了 getLayerDirectories 实用函数,用于访问 Nuxt 应用中所有图层的解析后目录路径。

getLayerDirectories

获取 Nuxt 应用中所有图层的解析后目录路径。该函数提供了一种结构化的方法来访问图层目录,而无需直接访问私有的 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 根目录(默认是 `/`) */
  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
  /** 布局目录(默认是 `/app/layouts`) */
  readonly appLayouts: string
  /** 中间件目录(默认是 `/app/middleware`) */
  readonly appMiddleware: string
  /** 页面目录(默认是 `/app/pages`) */
  readonly appPages: string
  /** 插件目录(默认是 `/app/plugins`) */
  readonly appPlugins: string
}

参数

nuxt(可选):要从中获取图层的 Nuxt 实例。如果未提供,函数将使用当前的 Nuxt 上下文。

返回值

getLayerDirectories 函数返回一个 LayerDirectories 对象数组,每个图层对应一个对象。

图层优先级顺序:图层按优先级排序,其中:

  • 第一个图层是用户/项目图层(最高优先级)
  • 数组中较早的图层会覆盖较晚的图层
  • 基础图层出现在数组的最后(最低优先级)

此顺序与 Nuxt 的图层解析系统一致,用户定义的配置和文件优先于基础图层提供的内容。

LayerDirectories:包含图层解析后目录路径的对象。

属性类型描述
rootstring图层的根目录(等同于 rootDir
serverstring用于 Nitro 服务端代码的服务器目录
modulesstring本地模块目录
sharedstring同时被客户端和服务器使用的共享目录
appstring图层的源代码目录(等同于 srcDir
publicstring用于静态资源的 public 目录
appLayoutsstringVue 布局组件的 layouts 目录
appMiddlewarestring路由中间件的 middleware 目录
appPagesstring基于文件路由的 pages 目录
appPluginsstringNuxt 插件的 plugins 目录

示例

处理来自所有图层的文件:

// @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(`找到 ${layersWithAssets.length} 个包含 assets 目录的图层`)
  },
})
getLayerDirectories 函数通过 WeakMap 实现了缓存,以避免对相同图层重复计算目录路径,从而在多次调用时提高性能。
此函数返回的目录路径始终包含尾随斜杠以保持一致性。