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 { loadConfig } from 'c12'
import type { NuxtConfig, NuxtOptions } from '@nuxt/schema' import type { NuxtConfig, NuxtOptions } from '@nuxt/schema'
import { NuxtConfigSchema } from '@nuxt/schema' import { NuxtConfigSchema } from '@nuxt/schema'
import { globby } from 'globby'
import defu from 'defu'
export interface LoadNuxtConfigOptions extends LoadConfigOptions<NuxtConfig> {} 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))) const layerSchema = Object.fromEntries(Object.entries(NuxtConfigSchema).filter(([key]) => layerSchemaKeys.includes(key)))
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> { 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 (globalThis as any).defineNuxtConfig = (c: any) => c
const result = await loadConfig<NuxtConfig>({ const result = await loadConfig<NuxtConfig>({
name: 'nuxt', name: 'nuxt',
configFile: 'nuxt.config', configFile: 'nuxt.config',
rcFile: '.nuxtrc', rcFile: '.nuxtrc',
extend: { extendKey: ['theme', 'extends'] }, extend: { extendKey: ['theme', 'extends', '_extends'] },
dotenv: true, dotenv: true,
globalRc: true, globalRc: true,
...opts, ...opts,

View File

@ -10,7 +10,7 @@ import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
import escapeRE from 'escape-string-regexp' import escapeRE from 'escape-string-regexp'
import fse from 'fs-extra' import fse from 'fs-extra'
import { withoutLeadingSlash } from 'ufo' import { withTrailingSlash, withoutLeadingSlash } from 'ufo'
import defu from 'defu' import defu from 'defu'
import pagesModule from '../pages/module' 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 // Set nuxt instance for useNuxt
nuxtCtx.set(nuxt) nuxtCtx.set(nuxt)
nuxt.hook('close', () => nuxtCtx.unset()) 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: [ 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/subpath',
'./modules/test', './modules/test',
'~/modules/example', '~/modules/example',