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

Commit

Permalink
feat(nuxt): app.config improvements (#6905)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tahul authored Aug 24, 2022
1 parent a4dfe23 commit 1700bf8
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 20 deletions.
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',
'defineAppConfig',
'preloadComponents',
'prefetchComponents'
Expand Down

0 comments on commit 1700bf8

Please sign in to comment.