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>
<BaseButton>Base Button</BaseButton>
<FancyButton>Fancy Button</FancyButton>
<UIButton>UI Button</UIButton>
<br>
{{ foo }} {{ bar }}
<br>

View File

@ -1,7 +1,10 @@
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
extends: './base',
extends: [
'./ui',
'./base'
],
publicRuntimeConfig: {
theme: {
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)
}
// Mock _extends
nuxt.options._extends = nuxt.options._extends || []
// Mock _layers
nuxt.options._layers = nuxt.options._layers || [{
config: nuxt.options,
cwd: nuxt.options.rootDir,
configFile: nuxt.options._nuxtConfigFile
}]
if (opts.nitro) {
await setupNitroBridge()

View File

@ -14,7 +14,7 @@
},
"dependencies": {
"@nuxt/schema": "^3.0.0",
"c12": "^0.1.4",
"c12": "^0.2.0",
"consola": "^2.15.3",
"defu": "^5.0.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)
}
nuxtConfig._extends = layers
nuxtConfig._layers = layers.filter(layer => layer.configFile && !layer.configFile.endsWith('.nuxtrc'))
// Resolve and apply defaults
return applyDefaults(NuxtConfigSchema, nuxtConfig) as NuxtOptions

View File

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

View File

@ -84,7 +84,7 @@ export interface NitroContext {
runtimeDir: string
hooks: Hookable<NitroHooks>
},
_extends: Array<{
_layers: Array<{
serverDir: string
}>
}
@ -158,7 +158,7 @@ export function getNitroContext (nuxtOptions: NuxtOptions, input: NitroInput): N
runtimeDir,
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')
}))
}

View File

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

View File

@ -39,26 +39,25 @@ export default defineNuxtModule<ComponentsOptions>({
}))
}
}
if (dir && typeof dir === 'object') {
return {
...dir,
path: resolve(cwd, resolveAlias(dir.path, {
...nuxt.options.alias,
'~': cwd
}))
}
if (!dir) {
return []
}
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
nuxt.hook('app:resolve', async () => {
const allDirs = [
...normalizeDirs(componentOptions.dirs, nuxt.options.srcDir),
...nuxt.options._extends
.map(layer => normalizeDirs(layer.config.components, layer.cwd))
.flat()
]
// components/ dirs from all layers
const allDirs = nuxt.options._layers
.map(layer => normalizeDirs(layer.config.components, layer.cwd))
.flat()
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')
}
// Resolve layouts
// Resolve layouts/ from all config layers
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(',')}}`)
for (const file of layoutFiles) {
const name = getNameFromPath(file)
@ -82,16 +82,19 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
}
// Resolve plugins
app.plugins = []
for (const config of [...nuxt.options._extends.map(layer => layer.config), nuxt.options]) {
app.plugins = [
...nuxt.options.plugins.map(normalizePlugin)
]
for (const config of nuxt.options._layers.map(layer => layer.config)) {
app.plugins.push(...[
...config.plugins ?? [],
...(config.plugins || []),
...await resolveFiles(config.srcDir, [
'plugins/*.{ts,js,mjs,cjs,mts,cts}',
'plugins/*/index.*{ts,js,mjs,cjs,mts,cts}'
])
].map(plugin => normalizePlugin(plugin as NuxtPlugin)))
}
app.plugins = uniqueBy(app.plugins, 'src')
// Extend app
await nuxt.callHook('app:resolve', app)
@ -100,3 +103,15 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
function getNameFromPath (path: string) {
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 () => {
const serverDirs = [
...nitroDevContext._extends.map(layer => layer.serverDir),
nitroDevContext._nuxt.serverDir
]
const serverDirs = nitroDevContext._layers.map(layer => layer.serverDir)
nitroDevContext.scannedMiddleware = (
await Promise.all(serverDirs.map(async dir => await scanMiddleware(dir)))

View File

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

View File

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

View File

@ -2914,7 +2914,7 @@ __metadata:
"@nuxt/schema": ^3.0.0
"@types/lodash.template": ^4
"@types/semver": ^7
c12: ^0.1.4
c12: ^0.2.0
consola: ^2.15.3
defu: ^5.0.1
globby: ^13.1.1
@ -3084,7 +3084,7 @@ __metadata:
dependencies:
"@types/lodash.template": ^4
"@types/semver": ^7
c12: ^0.1.4
c12: ^0.2.0
create-require: ^1.1.1
defu: ^5.0.1
jiti: ^1.13.0
@ -7061,6 +7061,21 @@ __metadata:
languageName: node
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":
version: 6.7.12
resolution: "cac@npm:6.7.12"