Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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) using deep assignment. Existing (nested) properties will be preserved.

**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',
Comment thread
Tahul marked this conversation as resolved.
'defineAppConfig',
'preloadComponents',
'prefetchComponents'
Expand Down