레이어

Source
Nuxt Kit은 레이어와 그 디렉터리 구조를 다루는 데 도움이 되는 유틸리티를 제공합니다.

Nuxt 레이어는 프로젝트 간에 기능을 공유하고 확장할 수 있는 강력한 방법을 제공합니다. 모듈에서 레이어를 사용할 때는 각 레이어의 디렉터리 경로에 접근해야 하는 경우가 자주 있습니다. Nuxt Kit은 Nuxt 애플리케이션의 모든 레이어에 대해 해석된 디렉터리 경로에 접근할 수 있는 getLayerDirectories 유틸리티를 제공합니다.

getLayerDirectories

Nuxt 애플리케이션의 모든 레이어에 대해 해석된 디렉터리 경로를 가져옵니다. 이 함수는 비공개 속성인 nuxt.options._layers에 직접 접근하지 않고 레이어 디렉터리에 구조적으로 접근할 수 있는 방법을 제공합니다.

Usage

import { defineNuxtModule, getLayerDirectories } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    const layerDirs = getLayerDirectories()

    // 모든 레이어의 디렉터리에 접근
    for (const [index, layer] of layerDirs.entries()) {
      console.log(`Layer ${index}:`)
      console.log(`  Root: ${layer.root}`)
      console.log(`  App: ${layer.app}`)
      console.log(`  Server: ${layer.server}`)
      console.log(`  Pages: ${layer.appPages}`)
      // ... 기타 디렉터리
    }
  },
})

Type

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
  /** 레이아웃 디렉터리 (기본값은 `/app/layouts`) */
  readonly appLayouts: string
  /** 미들웨어 디렉터리 (기본값은 `/app/middleware`) */
  readonly appMiddleware: string
  /** 페이지 디렉터리 (기본값은 `/app/pages`) */
  readonly appPages: string
  /** 플러그인 디렉터리 (기본값은 `/app/plugins`) */
  readonly appPlugins: string
}

Parameters

nuxt (선택 사항): 레이어를 가져올 Nuxt 인스턴스입니다. 제공되지 않으면 현재 Nuxt 컨텍스트를 사용합니다.

Return Value

getLayerDirectories 함수는 애플리케이션의 각 레이어마다 하나씩, LayerDirectories 객체의 배열을 반환합니다.

레이어 우선순위 정렬: 레이어는 다음과 같은 우선순위로 정렬됩니다:

  • 첫 번째 레이어는 사용자/프로젝트 레이어입니다 (가장 높은 우선순위)
  • 배열에서 앞쪽 레이어가 뒤쪽 레이어를 오버라이드합니다
  • 베이스 레이어는 배열의 마지막에 위치합니다 (가장 낮은 우선순위)

이 정렬 방식은 Nuxt의 레이어 해석 시스템과 일치하며, 사용자 정의 설정과 파일이 베이스 레이어의 것보다 우선합니다.

LayerDirectories: 레이어에 대한 해석된 디렉터리 경로를 포함하는 객체입니다.

PropertyTypeDescription
rootstring레이어의 루트 디렉터리 (rootDir와 동일)
serverstringNitro 서버 사이드 코드를 위한 서버 디렉터리
modulesstring로컬 모듈 디렉터리
sharedstring클라이언트와 서버 모두에서 사용하는 코드를 위한 공유 디렉터리
appstring레이어의 소스 디렉터리 (srcDir와 동일)
publicstring정적 에셋을 위한 퍼블릭 디렉터리
appLayoutsstringVue 레이아웃 컴포넌트를 위한 레이아웃 디렉터리
appMiddlewarestring라우트 미들웨어를 위한 미들웨어 디렉터리
appPagesstring파일 기반 라우팅을 위한 페이지 디렉터리
appPluginsstringNuxt 플러그인을 위한 플러그인 디렉터리

Examples

모든 레이어에서 파일 처리:

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(`Layer ${index} (${index === 0 ? 'user' : 'base'}):`, files.length, 'components')
      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(`Using config from layer: ${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(`Found ${layersWithAssets.length} layers with assets directory`)
  },
})
getLayerDirectories 함수는 동일한 레이어에 대해 디렉터리 경로를 반복해서 다시 계산하지 않도록 WeakMap을 통한 캐싱을 포함하고 있어, 여러 번 호출될 때 성능을 향상시킵니다.
이 함수가 반환하는 디렉터리 경로는 일관성을 위해 항상 끝에 슬래시가 포함됩니다.