feat(nuxt): auto-register layers in layers/ directory (#27221)

This commit is contained in:
Daniel Roe 2024-05-15 05:51:14 -05:00 committed by GitHub
parent b96b62ecd2
commit 06be4cc025
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 2 deletions

View File

@ -4,6 +4,8 @@ import type { ConfigLayer, ConfigLayerMeta, LoadConfigOptions } from 'c12'
import { loadConfig } from 'c12'
import type { NuxtConfig, NuxtOptions } from '@nuxt/schema'
import { NuxtConfigSchema } from '@nuxt/schema'
import { globby } from 'globby'
import defu from 'defu'
export interface LoadNuxtConfigOptions extends LoadConfigOptions<NuxtConfig> {}
@ -11,12 +13,19 @@ const layerSchemaKeys = ['future', 'srcDir', 'rootDir', 'dir']
const layerSchema = Object.fromEntries(Object.entries(NuxtConfigSchema).filter(([key]) => layerSchemaKeys.includes(key)))
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
// Automatically detect and import layers from `~~/layers/` directory
opts.overrides = defu(opts.overrides, {
_extends: await globby('layers/*', {
onlyDirectories: true,
cwd: opts.cwd || process.cwd(),
}),
});
(globalThis as any).defineNuxtConfig = (c: any) => c
const result = await loadConfig<NuxtConfig>({
name: 'nuxt',
configFile: 'nuxt.config',
rcFile: '.nuxtrc',
extend: { extendKey: ['theme', 'extends'] },
extend: { extendKey: ['theme', 'extends', '_extends'] },
dotenv: true,
globalRc: true,
...opts,

View File

@ -10,7 +10,7 @@ import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
import escapeRE from 'escape-string-regexp'
import fse from 'fs-extra'
import { withoutLeadingSlash } from 'ufo'
import { withTrailingSlash, withoutLeadingSlash } from 'ufo'
import defu from 'defu'
import pagesModule from '../pages/module'
@ -71,6 +71,17 @@ async function initNuxt (nuxt: Nuxt) {
}
}
// Restart Nuxt when layer directories are added or removed
const layersDir = withTrailingSlash(resolve(nuxt.options.rootDir, 'layers'))
nuxt.hook('builder:watch', (event, relativePath) => {
const path = resolve(nuxt.options.srcDir, relativePath)
if (event === 'addDir' || event === 'unlinkDir') {
if (path.startsWith(layersDir)) {
return nuxt.callHook('restart', { hard: true })
}
}
})
// Set nuxt instance for useNuxt
nuxtCtx.set(nuxt)
nuxt.hook('close', () => nuxtCtx.unset())

View File

@ -0,0 +1,8 @@
export default defineNuxtConfig({
modules: [
function (_options, nuxt) {
// @ts-expect-error not valid nuxt option
nuxt.options.__installed_layer = true
},
],
})

View File

@ -92,6 +92,14 @@ export default defineNuxtConfig({
},
},
modules: [
function (_options, nuxt) {
nuxt.hook('modules:done', () => {
// @ts-expect-error not valid nuxt option
if (!nuxt.options.__installed_layer) {
throw new Error('layer in layers/ directory was not auto-registered')
}
})
},
'~/modules/subpath',
'./modules/test',
'~/modules/example',