feat(nuxt,schema): allow setting serialisable vue app config (#28873)

This commit is contained in:
Damian Głowala 2024-09-19 15:59:50 +02:00 committed by GitHub
parent c5cfe106cc
commit 58ae53b402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 4 deletions

View File

@ -4,7 +4,7 @@ import { join, normalize, relative, resolve } from 'pathe'
import { createDebugger, createHooks } from 'hookable' import { createDebugger, createHooks } from 'hookable'
import ignore from 'ignore' import ignore from 'ignore'
import type { LoadNuxtOptions } from '@nuxt/kit' import type { LoadNuxtOptions } from '@nuxt/kit'
import { addBuildPlugin, addComponent, addPlugin, addRouteMiddleware, addServerPlugin, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, logger, nuxtCtx, resolveAlias, resolveFiles, resolveIgnorePatterns, resolvePath, tryResolveModule, useNitro } from '@nuxt/kit' import { addBuildPlugin, addComponent, addPlugin, addPluginTemplate, addRouteMiddleware, addServerPlugin, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, logger, nuxtCtx, resolveAlias, resolveFiles, resolveIgnorePatterns, resolvePath, tryResolveModule, useNitro } from '@nuxt/kit'
import { resolvePath as _resolvePath } from 'mlly' import { resolvePath as _resolvePath } from 'mlly'
import type { Nuxt, NuxtHooks, NuxtModule, NuxtOptions } from 'nuxt/schema' import type { Nuxt, NuxtHooks, NuxtModule, NuxtOptions } from 'nuxt/schema'
import type { PackageJson } from 'pkg-types' import type { PackageJson } from 'pkg-types'
@ -606,6 +606,21 @@ async function initNuxt (nuxt: Nuxt) {
}) })
} }
if (nuxt.options.vue.config && Object.values(nuxt.options.vue.config).some(v => v !== null && v !== undefined)) {
addPluginTemplate({
filename: 'vue-app-config.mjs',
getContents: () => `
import { defineNuxtPlugin } from '#app/nuxt'
export default defineNuxtPlugin({
name: 'nuxt:vue-app-config',
enforce: 'pre',
setup (nuxtApp) {
${Object.keys(nuxt.options.vue.config!).map(k => ` nuxtApp.vueApp.config[${JSON.stringify(k)}] = ${JSON.stringify(nuxt.options.vue.config![k as 'idPrefix'])}`).join('\n')}
}
})`,
})
}
nuxt.hooks.hook('builder:watch', (event, relativePath) => { nuxt.hooks.hook('builder:watch', (event, relativePath) => {
const path = resolve(nuxt.options.srcDir, relativePath) const path = resolve(nuxt.options.srcDir, relativePath)
// Local module patterns // Local module patterns

View File

@ -35,6 +35,13 @@ export default defineUntypedSchema({
* @type {boolean} * @type {boolean}
*/ */
propsDestructure: true, propsDestructure: true,
/**
* It is possible to pass configure the Vue app globally. Only serializable options
* may be set in your `nuxt.config`. All other options should be set at runtime in a Nuxt plugin..
* @see [Vue app config documentation](https://vuejs.org/api/application.html#app-config)
*/
config: undefined,
}, },
/** /**

View File

@ -1,4 +1,4 @@
import type { KeepAliveProps, TransitionProps } from 'vue' import type { KeepAliveProps, TransitionProps, AppConfig as VueAppConfig } from 'vue'
import type { ServerOptions as ViteServerOptions, UserConfig as ViteUserConfig } from 'vite' import type { ServerOptions as ViteServerOptions, UserConfig as ViteUserConfig } from 'vite'
import type { Options as VuePluginOptions } from '@vitejs/plugin-vue' import type { Options as VuePluginOptions } from '@vitejs/plugin-vue'
import type { Options as VueJsxPluginOptions } from '@vitejs/plugin-vue-jsx' import type { Options as VueJsxPluginOptions } from '@vitejs/plugin-vue-jsx'
@ -45,7 +45,8 @@ export interface RuntimeConfig extends RuntimeConfigNamespace {
} }
// User configuration in `nuxt.config` file // User configuration in `nuxt.config` file
export interface NuxtConfig extends DeepPartial<Omit<ConfigSchema, 'vite' | 'runtimeConfig'>> { export interface NuxtConfig extends DeepPartial<Omit<ConfigSchema, 'vue' | 'vite' | 'runtimeConfig' | 'webpack'>> {
vue?: Omit<DeepPartial<ConfigSchema['vue']>, 'config'> & { config?: Partial<Filter<VueAppConfig, string | boolean>> }
// Avoid DeepPartial for vite config interface (#4772) // Avoid DeepPartial for vite config interface (#4772)
vite?: ConfigSchema['vite'] vite?: ConfigSchema['vite']
runtimeConfig?: Overrideable<RuntimeConfig> runtimeConfig?: Overrideable<RuntimeConfig>
@ -77,7 +78,8 @@ export interface NuxtBuilder {
} }
// Normalized Nuxt options available as `nuxt.options.*` // Normalized Nuxt options available as `nuxt.options.*`
export interface NuxtOptions extends Omit<ConfigSchema, 'builder' | 'webpack' | 'postcss'> { export interface NuxtOptions extends Omit<ConfigSchema, 'vue' | 'sourcemap' | 'builder' | 'postcss' | 'webpack'> {
vue: Omit<ConfigSchema['vue'], 'config'> & { config?: Partial<Filter<VueAppConfig, string | boolean>> }
sourcemap: Required<Exclude<ConfigSchema['sourcemap'], boolean>> sourcemap: Required<Exclude<ConfigSchema['sourcemap'], boolean>>
builder: '@nuxt/vite-builder' | '@nuxt/webpack-builder' | NuxtBuilder builder: '@nuxt/vite-builder' | '@nuxt/webpack-builder' | NuxtBuilder
postcss: Omit<ConfigSchema['postcss'], 'order'> & { order: Exclude<ConfigSchema['postcss']['order'], string> } postcss: Omit<ConfigSchema['postcss'], 'order'> & { order: Exclude<ConfigSchema['postcss']['order'], string> }
@ -141,6 +143,9 @@ export interface AppConfigInput extends CustomAppConfig {
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
type Serializable<T> = T extends Function ? never : T extends Promise<infer U> ? Serializable<U> : T extends string & {} ? T : T extends Record<string, any> ? { [K in keyof T]: Serializable<T[K]> } : T type Serializable<T> = T extends Function ? never : T extends Promise<infer U> ? Serializable<U> : T extends string & {} ? T : T extends Record<string, any> ? { [K in keyof T]: Serializable<T[K]> } : T
type ValueOf<T> = T[keyof T]
type Filter<T extends Record<string, any>, V> = Pick<T, ValueOf<{ [K in keyof T]: NonNullable<T[K]> extends V ? K : never }>>
export interface NuxtAppConfig { export interface NuxtAppConfig {
head: Serializable<AppHeadMetaObject> head: Serializable<AppHeadMetaObject>
layoutTransition: boolean | Serializable<TransitionProps> layoutTransition: boolean | Serializable<TransitionProps>