feat!(nuxt3): use individual config layers for extending (#3717)

This commit is contained in:
pooya parsa 2022-03-16 21:36:30 +01:00 committed by GitHub
parent 24259495b2
commit b03cdb7114
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 95 additions and 48 deletions

View File

@ -10,6 +10,7 @@ const bar = getBar()
<pre>{{ JSON.stringify(themeConfig, null, 2) }}</pre> <pre>{{ JSON.stringify(themeConfig, null, 2) }}</pre>
<BaseButton>Base Button</BaseButton> <BaseButton>Base Button</BaseButton>
<FancyButton>Fancy Button</FancyButton> <FancyButton>Fancy Button</FancyButton>
<UIButton>UI Button</UIButton>
<br> <br>
{{ foo }} {{ bar }} {{ foo }} {{ bar }}
<br> <br>

View File

@ -1,7 +1,10 @@
import { defineNuxtConfig } from 'nuxt3' import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({ export default defineNuxtConfig({
extends: './base', extends: [
'./ui',
'./base'
],
publicRuntimeConfig: { publicRuntimeConfig: {
theme: { theme: {
primaryColor: 'user_primary' primaryColor: 'user_primary'

View File

@ -0,0 +1,14 @@
<script setup>
defineProps({
color: {
type: String,
default: 'black'
}
})
</script>
<template>
<button class="ui-button" :style="{ color }">
<slot />
</button>
</template>

View File

@ -0,0 +1,7 @@
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
components: [
{ path: './components', prefix: 'UI' }
]
})

View File

@ -41,8 +41,12 @@ export default defineNuxtModule({
nuxtCtx.set(nuxt) nuxtCtx.set(nuxt)
} }
// Mock _extends // Mock _layers
nuxt.options._extends = nuxt.options._extends || [] nuxt.options._layers = nuxt.options._layers || [{
config: nuxt.options,
cwd: nuxt.options.rootDir,
configFile: nuxt.options._nuxtConfigFile
}]
if (opts.nitro) { if (opts.nitro) {
await setupNitroBridge() await setupNitroBridge()

View File

@ -14,7 +14,7 @@
}, },
"dependencies": { "dependencies": {
"@nuxt/schema": "^3.0.0", "@nuxt/schema": "^3.0.0",
"c12": "^0.1.4", "c12": "^0.2.0",
"consola": "^2.15.3", "consola": "^2.15.3",
"defu": "^5.0.1", "defu": "^5.0.1",
"globby": "^13.1.1", "globby": "^13.1.1",

View File

@ -44,7 +44,7 @@ export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<Nuxt
layer.config.srcDir = resolve(layer.config.rootDir, layer.config.srcDir) layer.config.srcDir = resolve(layer.config.rootDir, layer.config.srcDir)
} }
nuxtConfig._extends = layers nuxtConfig._layers = layers.filter(layer => layer.configFile && !layer.configFile.endsWith('.nuxtrc'))
// Resolve and apply defaults // Resolve and apply defaults
return applyDefaults(NuxtConfigSchema, nuxtConfig) as NuxtOptions return applyDefaults(NuxtConfigSchema, nuxtConfig) as NuxtOptions

View File

@ -93,10 +93,7 @@ export async function writeTypes (nitroContext: NitroContext) {
} }
async function _build (nitroContext: NitroContext) { async function _build (nitroContext: NitroContext) {
const serverDirs = [ const serverDirs = nitroContext._layers.map(layer => layer.serverDir)
...nitroContext._extends.map(layer => layer.serverDir),
nitroContext._nuxt.serverDir
]
nitroContext.scannedMiddleware = ( nitroContext.scannedMiddleware = (
await Promise.all(serverDirs.map(async dir => await scanMiddleware(dir))) await Promise.all(serverDirs.map(async dir => await scanMiddleware(dir)))
@ -181,7 +178,7 @@ async function _watch (nitroContext: NitroContext) {
let watcher = startRollupWatcher(nitroContext) let watcher = startRollupWatcher(nitroContext)
const serverDirs = [ const serverDirs = [
...nitroContext._extends.map(layer => layer.serverDir), ...nitroContext._layers.map(layer => layer.serverDir),
nitroContext._nuxt.serverDir nitroContext._nuxt.serverDir
] ]

View File

@ -84,7 +84,7 @@ export interface NitroContext {
runtimeDir: string runtimeDir: string
hooks: Hookable<NitroHooks> hooks: Hookable<NitroHooks>
}, },
_extends: Array<{ _layers: Array<{
serverDir: string serverDir: string
}> }>
} }
@ -158,7 +158,7 @@ export function getNitroContext (nuxtOptions: NuxtOptions, input: NitroInput): N
runtimeDir, runtimeDir,
hooks: createHooks<NitroHooks>() hooks: createHooks<NitroHooks>()
}, },
_extends: nuxtOptions._extends.map(layer => ({ _layers: nuxtOptions._layers.map(layer => ({
serverDir: resolve(layer.config.srcDir, (layer.config.dir as any)?.server || 'server') serverDir: resolve(layer.config.srcDir, (layer.config.dir as any)?.server || 'server')
})) }))
} }

View File

@ -40,14 +40,9 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
imports: options.imports imports: options.imports
}) })
// composables/ dirs // composables/ dirs from all layers
let composablesDirs = [ let composablesDirs = []
join(nuxt.options.srcDir, 'composables'), for (const layer of nuxt.options._layers) {
...options.dirs
]
// Extend with layers
for (const layer of nuxt.options._extends) {
composablesDirs.push(resolve(layer.config.srcDir, 'composables')) composablesDirs.push(resolve(layer.config.srcDir, 'composables'))
for (const dir of (layer.config.autoImports?.dirs ?? [])) { for (const dir of (layer.config.autoImports?.dirs ?? [])) {
composablesDirs.push(resolve(layer.config.srcDir, dir)) composablesDirs.push(resolve(layer.config.srcDir, dir))

View File

@ -39,26 +39,25 @@ export default defineNuxtModule<ComponentsOptions>({
})) }))
} }
} }
if (dir && typeof dir === 'object') { if (!dir) {
return { return []
...dir,
path: resolve(cwd, resolveAlias(dir.path, {
...nuxt.options.alias,
'~': cwd
}))
}
} }
return [] const dirs = (dir.dirs || [dir]).filter(_dir => _dir.path)
return dirs.map(_dir => ({
..._dir,
path: resolve(cwd, resolveAlias(_dir.path, {
...nuxt.options.alias,
'~': cwd
}))
}))
} }
// Resolve dirs // Resolve dirs
nuxt.hook('app:resolve', async () => { nuxt.hook('app:resolve', async () => {
const allDirs = [ // components/ dirs from all layers
...normalizeDirs(componentOptions.dirs, nuxt.options.srcDir), const allDirs = nuxt.options._layers
...nuxt.options._extends .map(layer => normalizeDirs(layer.config.components, layer.cwd))
.map(layer => normalizeDirs(layer.config.components, layer.cwd)) .flat()
.flat()
]
await nuxt.callHook('components:dirs', allDirs) await nuxt.callHook('components:dirs', allDirs)

View File

@ -71,9 +71,9 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
app.errorComponent = (await findPath(['~/error'])) || resolve(nuxt.options.appDir, 'components/nuxt-error-page.vue') app.errorComponent = (await findPath(['~/error'])) || resolve(nuxt.options.appDir, 'components/nuxt-error-page.vue')
} }
// Resolve layouts // Resolve layouts/ from all config layers
app.layouts = {} app.layouts = {}
for (const config of [nuxt.options, ...nuxt.options._extends.map(layer => layer.config)]) { for (const config of nuxt.options._layers.map(layer => layer.config)) {
const layoutFiles = await resolveFiles(config.srcDir, `${config.dir?.layouts || 'layouts'}/*{${nuxt.options.extensions.join(',')}}`) const layoutFiles = await resolveFiles(config.srcDir, `${config.dir?.layouts || 'layouts'}/*{${nuxt.options.extensions.join(',')}}`)
for (const file of layoutFiles) { for (const file of layoutFiles) {
const name = getNameFromPath(file) const name = getNameFromPath(file)
@ -82,16 +82,19 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
} }
// Resolve plugins // Resolve plugins
app.plugins = [] app.plugins = [
for (const config of [...nuxt.options._extends.map(layer => layer.config), nuxt.options]) { ...nuxt.options.plugins.map(normalizePlugin)
]
for (const config of nuxt.options._layers.map(layer => layer.config)) {
app.plugins.push(...[ app.plugins.push(...[
...config.plugins ?? [], ...(config.plugins || []),
...await resolveFiles(config.srcDir, [ ...await resolveFiles(config.srcDir, [
'plugins/*.{ts,js,mjs,cjs,mts,cts}', 'plugins/*.{ts,js,mjs,cjs,mts,cts}',
'plugins/*/index.*{ts,js,mjs,cjs,mts,cts}' 'plugins/*/index.*{ts,js,mjs,cjs,mts,cts}'
]) ])
].map(plugin => normalizePlugin(plugin as NuxtPlugin))) ].map(plugin => normalizePlugin(plugin as NuxtPlugin)))
} }
app.plugins = uniqueBy(app.plugins, 'src')
// Extend app // Extend app
await nuxt.callHook('app:resolve', app) await nuxt.callHook('app:resolve', app)
@ -100,3 +103,15 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
function getNameFromPath (path: string) { function getNameFromPath (path: string) {
return kebabCase(basename(path).replace(extname(path), '')).replace(/["']/g, '') return kebabCase(basename(path).replace(extname(path), '')).replace(/["']/g, '')
} }
function uniqueBy (arr: any[], uniqueKey: string) {
const seen = new Set<string>()
const res = []
for (const i of arr) {
const key = i[uniqueKey]
if (seen.has(key)) { continue }
res.push(i)
seen.add(key)
}
return res
}

View File

@ -77,10 +77,7 @@ export function initNitro (nuxt: Nuxt) {
}) })
nuxt.hook('build:before', async () => { nuxt.hook('build:before', async () => {
const serverDirs = [ const serverDirs = nitroDevContext._layers.map(layer => layer.serverDir)
...nitroDevContext._extends.map(layer => layer.serverDir),
nitroDevContext._nuxt.serverDir
]
nitroDevContext.scannedMiddleware = ( nitroDevContext.scannedMiddleware = (
await Promise.all(serverDirs.map(async dir => await scanMiddleware(dir))) await Promise.all(serverDirs.map(async dir => await scanMiddleware(dir)))

View File

@ -19,7 +19,7 @@
"unbuild": "latest" "unbuild": "latest"
}, },
"dependencies": { "dependencies": {
"c12": "^0.1.4", "c12": "^0.2.0",
"create-require": "^1.1.1", "create-require": "^1.1.1",
"defu": "^5.0.1", "defu": "^5.0.1",
"jiti": "^1.13.0", "jiti": "^1.13.0",

View File

@ -10,7 +10,7 @@ export interface NuxtConfig extends DeepPartial<ConfigSchema> {
/** Normalized Nuxt options available as `nuxt.options.*` */ /** Normalized Nuxt options available as `nuxt.options.*` */
export interface NuxtOptions extends ConfigSchema { export interface NuxtOptions extends ConfigSchema {
_extends: ResolvedConfig<NuxtConfig>[] _layers: ResolvedConfig<NuxtConfig>[]
} }
export interface PublicRuntimeConfig extends Record<string, any> { } export interface PublicRuntimeConfig extends Record<string, any> { }

View File

@ -2914,7 +2914,7 @@ __metadata:
"@nuxt/schema": ^3.0.0 "@nuxt/schema": ^3.0.0
"@types/lodash.template": ^4 "@types/lodash.template": ^4
"@types/semver": ^7 "@types/semver": ^7
c12: ^0.1.4 c12: ^0.2.0
consola: ^2.15.3 consola: ^2.15.3
defu: ^5.0.1 defu: ^5.0.1
globby: ^13.1.1 globby: ^13.1.1
@ -3084,7 +3084,7 @@ __metadata:
dependencies: dependencies:
"@types/lodash.template": ^4 "@types/lodash.template": ^4
"@types/semver": ^7 "@types/semver": ^7
c12: ^0.1.4 c12: ^0.2.0
create-require: ^1.1.1 create-require: ^1.1.1
defu: ^5.0.1 defu: ^5.0.1
jiti: ^1.13.0 jiti: ^1.13.0
@ -7061,6 +7061,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"c12@npm:^0.2.0":
version: 0.2.0
resolution: "c12@npm:0.2.0"
dependencies:
defu: ^5.0.1
dotenv: ^14.3.2
gittar: ^0.1.1
jiti: ^1.12.14
mlly: ^0.4.1
pathe: ^0.2.0
rc9: ^1.2.0
checksum: 1f69ed861368c8dc057f235a4925c4863b0423683a98578d3fa3c208dbcb43aadb907a5c855bf95969157210f632bfeb2bdf539f15a6c2d731d68f20273c00df
languageName: node
linkType: hard
"cac@npm:^6.7.12": "cac@npm:^6.7.12":
version: 6.7.12 version: 6.7.12
resolution: "cac@npm:6.7.12" resolution: "cac@npm:6.7.12"