Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt): app.config improvements #6905

Merged
merged 9 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/content/3.api/1.composables/update-app-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `updateAppConfig`

::StabilityEdge
::

Updates [app config](/guide/features/app-config):

**Usage:**

```js
const appConfig = useAppConfig() // { foo: 'bar'Β }

const newAppConfig = { foo: 'baz' }

updateAppConfig(newAppConfig)

console.log(appConfig) // { foo: 'baz' }
```

::ReadMore{link="/guide/features/app-config"}
7 changes: 6 additions & 1 deletion examples/advanced/config-extends/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export default defineAppConfig({
foo: 'user',
bar: 'user',
baz: 'base'
baz: 'base',
array: [
'user',
'user',
'user'
]
})
16 changes: 15 additions & 1 deletion examples/advanced/config-extends/base/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
export default defineAppConfig({
bar: 'base',
baz: 'base'
baz: 'base',
array: () => [
'base',
'base',
'base'
],
arrayNested: {
nested: {
array: [
'base',
'base',
'base'
]
}
}
})
53 changes: 37 additions & 16 deletions packages/nuxt/src/app/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,35 @@ import { useNuxtApp } from './nuxt'
// @ts-ignore
import __appConfig from '#build/app.config.mjs'

type DeepPartial<T> = T extends Function ? T : T extends Record<string, any> ? { [P in keyof T]?: DeepPartial<T[P]> } : T

// Workaround for vite HMR with virtual modules
export const _getAppConfig = () => __appConfig as AppConfig

function deepDelete (obj: any, newObj: any) {
for (const key in obj) {
const val = newObj[key]
if (!(key in newObj)) {
delete (obj as any)[key]
}

if (val !== null && typeof val === 'object') {
deepDelete(obj[key], newObj[key])
}
}
}

function deepAssign (obj: any, newObj: any) {
for (const key in newObj) {
const val = newObj[key]
if (val !== null && typeof val === 'object') {
deepAssign(obj[key], val)
} else {
obj[key] = val
}
}
}

export function useAppConfig (): AppConfig {
const nuxtApp = useNuxtApp()
if (!nuxtApp._appConfig) {
Expand All @@ -15,28 +41,23 @@ export function useAppConfig (): AppConfig {
return nuxtApp._appConfig
}

/**
* Deep assign the current appConfig with the new one.
*
* Will preserve existing properties.
*/
export function updateAppConfig (appConfig: DeepPartial<AppConfig>) {
const _appConfig = useAppConfig()
deepAssign(_appConfig, appConfig)
}

// HMR Support
if (process.dev) {
function applyHMR (newConfig: AppConfig) {
const appConfig = useAppConfig()
if (newConfig && appConfig) {
deepAssign(appConfig, newConfig)
for (const key in appConfig) {
if (!(key in newConfig)) {
delete (appConfig as any)[key]
}
}
}
}

function deepAssign (obj: any, newObj: any) {
for (const key in newObj) {
const val = newObj[key]
if (val !== null && typeof val === 'object') {
deepAssign(obj[key], val)
} else {
obj[key] = val
}
deepDelete(appConfig, newConfig)
}
}

Expand Down
5 changes: 3 additions & 2 deletions packages/nuxt/src/core/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,13 @@ export const appConfigTemplate: NuxtTemplate = {
write: true,
getContents: ({ app, nuxt }) => {
return `
import defu from 'defu'
import { defuFn } from 'defu'

const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)}

${app.configs.map((id: string, index: number) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join('\n')}
export default defu(${app.configs.map((_id: string, index: number) => `cfg${index}`).concat(['inlineConfig']).join(', ')})

export default defuFn(${app.configs.map((_id: string, index: number) => `cfg${index}`).concat(['inlineConfig']).join(', ')})
`
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/nuxt/src/imports/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const appPreset = defineUnimportPreset({
'createError',
'defineNuxtLink',
'useAppConfig',
'updateAppConfig',
'defineAppConfig',
'preloadComponents',
'prefetchComponents'
Expand Down