fix(vite): allow extending vue config per-environment (#19968)

This commit is contained in:
Daniel Roe 2023-03-29 11:59:57 +01:00 committed by GitHub
parent cb154c9f95
commit ae82d70895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 42 deletions

View File

@ -8,13 +8,13 @@ export interface ExtendConfigOptions {
* *
* @default true * @default true
*/ */
dev?: boolean dev?: boolean
/** /**
* Install plugin on build * Install plugin on build
* *
* @default true * @default true
*/ */
build?: boolean build?: boolean
/** /**
* Install plugin on server side * Install plugin on server side
* *
@ -41,7 +41,7 @@ export interface ExtendViteConfigOptions extends ExtendConfigOptions {}
* when applying to both client and server builds. * when applying to both client and server builds.
*/ */
export function extendWebpackConfig ( export function extendWebpackConfig (
fn: ((config: WebpackConfig)=> void), fn: ((config: WebpackConfig) => void),
options: ExtendWebpackConfigOptions = {} options: ExtendWebpackConfigOptions = {}
) { ) {
const nuxt = useNuxt() const nuxt = useNuxt()

View File

@ -94,14 +94,16 @@ export interface NuxtOptions extends Omit<ConfigSchema, 'builder'> {
} }
export interface ViteConfig extends ViteUserConfig { export interface ViteConfig extends ViteUserConfig {
/** The path to the entrypoint for the Vite build. */
entry?: string
/** /**
* Options passed to @vitejs/plugin-vue * Options passed to @vitejs/plugin-vue.
* @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue * @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue
*/ */
vue?: VuePluginOptions vue?: VuePluginOptions
/** /**
* Options passed to @vitejs/plugin-vue-jsx * Options passed to @vitejs/plugin-vue-jsx.
* @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx * @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx
*/ */
vueJsx?: VueJsxPluginOptions vueJsx?: VueJsxPluginOptions

View File

@ -1,7 +1,7 @@
import type { TSConfig } from 'pkg-types' import type { TSConfig } from 'pkg-types'
import type { Server as HttpServer } from 'node:http' import type { Server as HttpServer } from 'node:http'
import type { Server as HttpsServer } from 'node:https' import type { Server as HttpsServer } from 'node:https'
import type { InlineConfig as ViteInlineConfig, ViteDevServer } from 'vite' import type { ViteDevServer } from 'vite'
import type { Manifest } from 'vue-bundle-renderer' import type { Manifest } from 'vue-bundle-renderer'
import type { EventHandler } from 'h3' import type { EventHandler } from 'h3'
import type { Import, InlinePreset, Unimport } from 'unimport' import type { Import, InlinePreset, Unimport } from 'unimport'
@ -9,7 +9,7 @@ import type { Compiler, Configuration, Stats } from 'webpack'
import type { Nuxt, NuxtApp, ResolvedNuxtTemplate } from './nuxt' import type { Nuxt, NuxtApp, ResolvedNuxtTemplate } from './nuxt'
import type { Nitro, NitroConfig } from 'nitropack' import type { Nitro, NitroConfig } from 'nitropack'
import type { Component, ComponentsOptions } from './components' import type { Component, ComponentsOptions } from './components'
import type { NuxtCompatibility, NuxtCompatibilityIssues } from '..' import type { NuxtCompatibility, NuxtCompatibilityIssues, ViteConfig } from '..'
import type { Schema, SchemaDefinition } from 'untyped' import type { Schema, SchemaDefinition } from 'untyped'
export type HookResult = Promise<void> | void export type HookResult = Promise<void> | void
@ -282,14 +282,14 @@ export interface NuxtHooks {
* @param viteBuildContext The vite build context object * @param viteBuildContext The vite build context object
* @returns Promise * @returns Promise
*/ */
'vite:extend': (viteBuildContext: { nuxt: Nuxt, config: ViteInlineConfig }) => HookResult 'vite:extend': (viteBuildContext: { nuxt: Nuxt, config: ViteConfig }) => HookResult
/** /**
* Allows to extend Vite default config. * Allows to extend Vite default config.
* @param viteInlineConfig The vite inline config object * @param viteInlineConfig The vite inline config object
* @param env Server or client * @param env Server or client
* @returns Promise * @returns Promise
*/ */
'vite:extendConfig': (viteInlineConfig: ViteInlineConfig, env: { isClient: boolean, isServer: boolean }) => HookResult 'vite:extendConfig': (viteInlineConfig: ViteConfig, env: { isClient: boolean, isServer: boolean }) => HookResult
/** /**
* Called when the Vite server is created. * Called when the Vite server is created.
* @param viteServer Vite development server * @param viteServer Vite development server

View File

@ -10,9 +10,10 @@ import { joinURL, withoutLeadingSlash } from 'ufo'
import { defu } from 'defu' import { defu } from 'defu'
import type { OutputOptions } from 'rollup' import type { OutputOptions } from 'rollup'
import { defineEventHandler } from 'h3' import { defineEventHandler } from 'h3'
import type { ViteConfig } from '@nuxt/schema'
import { cacheDirPlugin } from './plugins/cache-dir' import { cacheDirPlugin } from './plugins/cache-dir'
import { chunkErrorPlugin } from './plugins/chunk-error' import { chunkErrorPlugin } from './plugins/chunk-error'
import type { ViteBuildContext, ViteOptions } from './vite' import type { ViteBuildContext } from './vite'
import { devStyleSSRPlugin } from './plugins/dev-ssr-css' import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
import { runtimePathsPlugin } from './plugins/paths' import { runtimePathsPlugin } from './plugins/paths'
import { pureAnnotationsPlugin } from './plugins/pure-annotations' import { pureAnnotationsPlugin } from './plugins/pure-annotations'
@ -20,8 +21,7 @@ import { viteNodePlugin } from './vite-node'
import { createViteLogger } from './utils/logger' import { createViteLogger } from './utils/logger'
export async function buildClient (ctx: ViteBuildContext) { export async function buildClient (ctx: ViteBuildContext) {
const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, { const clientConfig: ViteConfig = vite.mergeConfig(ctx.config, {
entry: ctx.entry,
base: ctx.nuxt.options.dev base: ctx.nuxt.options.dev
? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir) ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir)
: './', : './',
@ -62,8 +62,6 @@ export async function buildClient (ctx: ViteBuildContext) {
}, },
plugins: [ plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'), cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'),
vuePlugin(ctx.config.vue),
viteJsxPlugin(ctx.config.vueJsx),
devStyleSSRPlugin({ devStyleSSRPlugin({
srcDir: ctx.nuxt.options.srcDir, srcDir: ctx.nuxt.options.srcDir,
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir) buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)
@ -81,7 +79,7 @@ export async function buildClient (ctx: ViteBuildContext) {
server: { server: {
middlewareMode: true middlewareMode: true
} }
} as ViteOptions) } satisfies vite.InlineConfig)
clientConfig.customLogger = createViteLogger(clientConfig) clientConfig.customLogger = createViteLogger(clientConfig)
@ -126,6 +124,11 @@ export async function buildClient (ctx: ViteBuildContext) {
await ctx.nuxt.callHook('vite:extendConfig', clientConfig, { isClient: true, isServer: false }) await ctx.nuxt.callHook('vite:extendConfig', clientConfig, { isClient: true, isServer: false })
clientConfig.plugins!.unshift(
vuePlugin(clientConfig.vue),
viteJsxPlugin(clientConfig.vueJsx)
)
if (ctx.nuxt.options.dev) { if (ctx.nuxt.options.dev) {
// Dev // Dev
const viteServer = await vite.createServer(clientConfig) const viteServer = await vite.createServer(clientConfig)

View File

@ -1,10 +1,10 @@
import { requireModule } from '@nuxt/kit' import { requireModule } from '@nuxt/kit'
import type { Nuxt } from '@nuxt/schema' import type { Nuxt } from '@nuxt/schema'
import type { ViteOptions } from './vite' import type { InlineConfig as ViteConfig } from 'vite'
import { distDir } from './dirs' import { distDir } from './dirs'
export function resolveCSSOptions (nuxt: Nuxt): ViteOptions['css'] { export function resolveCSSOptions (nuxt: Nuxt): ViteConfig['css'] {
const css: ViteOptions['css'] & { postcss: NonNullable<Exclude<NonNullable<ViteOptions['css']>['postcss'], string>> } = { const css: ViteConfig['css'] & { postcss: NonNullable<Exclude<NonNullable<ViteConfig['css']>['postcss'], string>> } = {
postcss: { postcss: {
plugins: [] plugins: []
} }

View File

@ -4,7 +4,8 @@ import vuePlugin from '@vitejs/plugin-vue'
import viteJsxPlugin from '@vitejs/plugin-vue-jsx' import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
import { logger, resolveModule, resolvePath } from '@nuxt/kit' import { logger, resolveModule, resolvePath } from '@nuxt/kit'
import { joinURL, withoutLeadingSlash, withTrailingSlash } from 'ufo' import { joinURL, withoutLeadingSlash, withTrailingSlash } from 'ufo'
import type { ViteBuildContext, ViteOptions } from './vite' import type { ViteConfig } from '@nuxt/schema'
import type { ViteBuildContext } from './vite'
import { createViteLogger } from './utils/logger' import { createViteLogger } from './utils/logger'
import { cacheDirPlugin } from './plugins/cache-dir' import { cacheDirPlugin } from './plugins/cache-dir'
import { initViteNodeServer } from './vite-node' import { initViteNodeServer } from './vite-node'
@ -17,8 +18,7 @@ export async function buildServer (ctx: ViteBuildContext) {
const _resolve = (id: string) => resolveModule(id, { paths: ctx.nuxt.options.modulesDir }) const _resolve = (id: string) => resolveModule(id, { paths: ctx.nuxt.options.modulesDir })
const helper = ctx.nuxt.options.nitro.imports !== false ? '' : 'globalThis.' const helper = ctx.nuxt.options.nitro.imports !== false ? '' : 'globalThis.'
const entry = ctx.nuxt.options.ssr ? ctx.entry : await resolvePath(resolve(ctx.nuxt.options.appDir, 'entry-spa')) const entry = ctx.nuxt.options.ssr ? ctx.entry : await resolvePath(resolve(ctx.nuxt.options.appDir, 'entry-spa'))
const serverConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, { const serverConfig: ViteConfig = vite.mergeConfig(ctx.config, {
entry,
base: ctx.nuxt.options.dev base: ctx.nuxt.options.dev
? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir) ? joinURL(ctx.nuxt.options.app.baseURL.replace(/^\.\//, '/') || '/', ctx.nuxt.options.app.buildAssetsDir)
: undefined, : undefined,
@ -111,14 +111,12 @@ export async function buildServer (ctx: ViteBuildContext) {
}, },
plugins: [ plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'), cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'),
vuePlugin(ctx.config.vue),
viteJsxPlugin(ctx.config.vueJsx),
pureAnnotationsPlugin.vite({ pureAnnotationsPlugin.vite({
sourcemap: ctx.nuxt.options.sourcemap.server, sourcemap: ctx.nuxt.options.sourcemap.server,
functions: ['defineComponent', 'defineAsyncComponent', 'defineNuxtLink', 'createClientOnly', 'defineNuxtPlugin', 'defineNuxtRouteMiddleware', 'defineNuxtComponent', 'useRuntimeConfig'] functions: ['defineComponent', 'defineAsyncComponent', 'defineNuxtLink', 'createClientOnly', 'defineNuxtPlugin', 'defineNuxtRouteMiddleware', 'defineNuxtComponent', 'useRuntimeConfig']
}) })
] ]
} as ViteOptions) } satisfies vite.InlineConfig)
serverConfig.customLogger = createViteLogger(serverConfig) serverConfig.customLogger = createViteLogger(serverConfig)
@ -146,6 +144,11 @@ export async function buildServer (ctx: ViteBuildContext) {
await ctx.nuxt.callHook('vite:extendConfig', serverConfig, { isClient: false, isServer: true }) await ctx.nuxt.callHook('vite:extendConfig', serverConfig, { isClient: false, isServer: true })
serverConfig.plugins!.unshift(
vuePlugin(serverConfig.vue),
viteJsxPlugin(serverConfig.vueJsx)
)
const onBuild = () => ctx.nuxt.callHook('vite:compiled') const onBuild = () => ctx.nuxt.callHook('vite:compiled')
// Production build // Production build

View File

@ -1,10 +1,7 @@
import * as vite from 'vite' import * as vite from 'vite'
import { join, resolve } from 'pathe' import { join, resolve } from 'pathe'
import type { Nuxt } from '@nuxt/schema' import type { Nuxt, ViteConfig } from '@nuxt/schema'
import type { InlineConfig, SSROptions } from 'vite'
import { logger, isIgnored, resolvePath, addVitePlugin } from '@nuxt/kit' import { logger, isIgnored, resolvePath, addVitePlugin } from '@nuxt/kit'
import type { Options as VueOptions } from '@vitejs/plugin-vue'
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx'
import replace from '@rollup/plugin-replace' import replace from '@rollup/plugin-replace'
import { sanitizeFilePath } from 'mlly' import { sanitizeFilePath } from 'mlly'
import { withoutLeadingSlash } from 'ufo' import { withoutLeadingSlash } from 'ufo'
@ -18,16 +15,9 @@ import { resolveCSSOptions } from './css'
import { composableKeysPlugin } from './plugins/composable-keys' import { composableKeysPlugin } from './plugins/composable-keys'
import { logLevelMap } from './utils/logger' import { logLevelMap } from './utils/logger'
export interface ViteOptions extends InlineConfig {
vue?: VueOptions
vueJsx?: VueJsxOptions
ssr?: SSROptions
devBundler?: 'vite-node' | 'legacy'
}
export interface ViteBuildContext { export interface ViteBuildContext {
nuxt: Nuxt nuxt: Nuxt
config: ViteOptions config: ViteConfig
entry: string entry: string
clientServer?: vite.ViteDevServer clientServer?: vite.ViteDevServer
ssrServer?: vite.ViteDevServer ssrServer?: vite.ViteDevServer
@ -104,7 +94,7 @@ export async function bundle (nuxt: Nuxt) {
] ]
} }
} }
} as ViteOptions, } satisfies ViteConfig,
nuxt.options.vite nuxt.options.vite
) )
} }