From 58ae53b40271645838f60f3d46aa2398139b99b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20G=C5=82owala?= Date: Thu, 19 Sep 2024 15:59:50 +0200 Subject: [PATCH] feat(nuxt,schema): allow setting serialisable vue app config (#28873) --- packages/nuxt/src/core/nuxt.ts | 17 ++++++++++++++++- packages/schema/src/config/app.ts | 7 +++++++ packages/schema/src/types/config.ts | 11 ++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 18479a6fa7..9caa634fdf 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -4,7 +4,7 @@ import { join, normalize, relative, resolve } from 'pathe' import { createDebugger, createHooks } from 'hookable' import ignore from 'ignore' 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 type { Nuxt, NuxtHooks, NuxtModule, NuxtOptions } from 'nuxt/schema' 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) => { const path = resolve(nuxt.options.srcDir, relativePath) // Local module patterns diff --git a/packages/schema/src/config/app.ts b/packages/schema/src/config/app.ts index 5b890528b4..9f5d8aa0b5 100644 --- a/packages/schema/src/config/app.ts +++ b/packages/schema/src/config/app.ts @@ -35,6 +35,13 @@ export default defineUntypedSchema({ * @type {boolean} */ 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, }, /** diff --git a/packages/schema/src/types/config.ts b/packages/schema/src/types/config.ts index 2e95263395..3de59b8493 100644 --- a/packages/schema/src/types/config.ts +++ b/packages/schema/src/types/config.ts @@ -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 { Options as VuePluginOptions } from '@vitejs/plugin-vue' 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 -export interface NuxtConfig extends DeepPartial> { +export interface NuxtConfig extends DeepPartial> { + vue?: Omit, 'config'> & { config?: Partial> } // Avoid DeepPartial for vite config interface (#4772) vite?: ConfigSchema['vite'] runtimeConfig?: Overrideable @@ -77,7 +78,8 @@ export interface NuxtBuilder { } // Normalized Nuxt options available as `nuxt.options.*` -export interface NuxtOptions extends Omit { +export interface NuxtOptions extends Omit { + vue: Omit & { config?: Partial> } sourcemap: Required> builder: '@nuxt/vite-builder' | '@nuxt/webpack-builder' | NuxtBuilder postcss: Omit & { order: Exclude } @@ -141,6 +143,9 @@ export interface AppConfigInput extends CustomAppConfig { // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type type Serializable = T extends Function ? never : T extends Promise ? Serializable : T extends string & {} ? T : T extends Record ? { [K in keyof T]: Serializable } : T +type ValueOf = T[keyof T] +type Filter, V> = Pick extends V ? K : never }>> + export interface NuxtAppConfig { head: Serializable layoutTransition: boolean | Serializable