diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index 8148d28eda..707e1a1ecf 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -12,10 +12,11 @@ import { env, nodeless } from 'unenv' import { defineEventHandler, handleCors, setHeader } from 'h3' import type { ViteConfig } from '@nuxt/schema' import type { ViteBuildContext } from './vite' -import { devStyleSSRPlugin } from './plugins/dev-ssr-css' -import { runtimePathsPlugin } from './plugins/paths' -import { typeCheckPlugin } from './plugins/type-check' -import { viteNodePlugin } from './vite-node' +import { DevStyleSSRPlugin } from './plugins/dev-ssr-css' +import { RuntimePathsPlugin } from './plugins/paths' +import { TypeCheckPlugin } from './plugins/type-check' +import { ModulePreloadPolyfillPlugin } from './plugins/module-preload-polyfill' +import { ViteNodePlugin } from './vite-node' import { createViteLogger } from './utils/logger' export async function buildClient (ctx: ViteBuildContext) { @@ -131,14 +132,14 @@ export async function buildClient (ctx: ViteBuildContext) { }, }, plugins: [ - devStyleSSRPlugin({ + DevStyleSSRPlugin({ srcDir: ctx.nuxt.options.srcDir, buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir), }), - runtimePathsPlugin({ + RuntimePathsPlugin({ sourcemap: !!ctx.nuxt.options.sourcemap.client, }), - viteNodePlugin(ctx), + ViteNodePlugin(ctx), ], appType: 'custom', server: { @@ -198,9 +199,14 @@ export async function buildClient (ctx: ViteBuildContext) { // Add type checking client panel if (!ctx.nuxt.options.test && ctx.nuxt.options.typescript.typeCheck === true && ctx.nuxt.options.dev) { - clientConfig.plugins!.push(typeCheckPlugin({ sourcemap: !!ctx.nuxt.options.sourcemap.client })) + clientConfig.plugins!.push(TypeCheckPlugin({ sourcemap: !!ctx.nuxt.options.sourcemap.client })) } + clientConfig.plugins!.push(ModulePreloadPolyfillPlugin({ + sourcemap: !!ctx.nuxt.options.sourcemap.client, + entry: ctx.entry, + })) + await ctx.nuxt.callHook('vite:extendConfig', clientConfig, { isClient: true, isServer: false }) clientConfig.plugins!.unshift( diff --git a/packages/vite/src/plugins/dev-ssr-css.ts b/packages/vite/src/plugins/dev-ssr-css.ts index 87420efa13..3f95f5f7d7 100644 --- a/packages/vite/src/plugins/dev-ssr-css.ts +++ b/packages/vite/src/plugins/dev-ssr-css.ts @@ -7,7 +7,7 @@ interface DevStyleSSRPluginOptions { buildAssetsURL: string } -export function devStyleSSRPlugin (options: DevStyleSSRPluginOptions): Plugin { +export function DevStyleSSRPlugin (options: DevStyleSSRPluginOptions): Plugin { return { name: 'nuxt:dev-style-ssr', apply: 'serve', diff --git a/packages/vite/src/plugins/module-preload-polyfill.ts b/packages/vite/src/plugins/module-preload-polyfill.ts new file mode 100644 index 0000000000..14e77a513f --- /dev/null +++ b/packages/vite/src/plugins/module-preload-polyfill.ts @@ -0,0 +1,26 @@ +import MagicString from 'magic-string' +import type { Plugin } from 'vite' + +const QUERY_RE = /\?.+$/ + +export function ModulePreloadPolyfillPlugin (options: { sourcemap: boolean, entry: string }): Plugin { + let isDisabled = false + return { + name: 'nuxt:module-preload-polyfill', + configResolved (config) { + isDisabled = config.build.modulePreload === false || config.build.modulePreload.polyfill === false + }, + transform (code, id) { + if (isDisabled || id.replace(QUERY_RE, '') !== options.entry) { return } + + const s = new MagicString(code) + + s.prepend('import "vite/modulepreload-polyfill";\n') + + return { + code: s.toString(), + map: options.sourcemap ? s.generateMap({ hires: true }) : undefined, + } + }, + } +} diff --git a/packages/vite/src/plugins/paths.ts b/packages/vite/src/plugins/paths.ts index 1a6a1cb7bf..d3e8b40a84 100644 --- a/packages/vite/src/plugins/paths.ts +++ b/packages/vite/src/plugins/paths.ts @@ -10,7 +10,7 @@ interface RuntimePathsOptions { const VITE_ASSET_RE = /__VITE_ASSET__|__VITE_PUBLIC_ASSET__/ -export function runtimePathsPlugin (options: RuntimePathsOptions): Plugin { +export function RuntimePathsPlugin (options: RuntimePathsOptions): Plugin { return { name: 'nuxt:runtime-paths-dep', enforce: 'post', diff --git a/packages/vite/src/plugins/type-check.ts b/packages/vite/src/plugins/type-check.ts index f875187fc4..e0f660b999 100644 --- a/packages/vite/src/plugins/type-check.ts +++ b/packages/vite/src/plugins/type-check.ts @@ -3,7 +3,7 @@ import type { Plugin } from 'vite' const QUERY_RE = /\?.+$/ -export function typeCheckPlugin (options: { sourcemap?: boolean } = {}): Plugin { +export function TypeCheckPlugin (options: { sourcemap?: boolean } = {}): Plugin { let entry: string return { name: 'nuxt:type-check', diff --git a/packages/vite/src/vite-node.ts b/packages/vite/src/vite-node.ts index 7352fee43c..81d4ec0178 100644 --- a/packages/vite/src/vite-node.ts +++ b/packages/vite/src/vite-node.ts @@ -14,7 +14,7 @@ import { isCSS } from './utils' // TODO: Remove this in favor of registerViteNodeMiddleware // after Nitropack or h3 allows adding middleware after setup -export function viteNodePlugin (ctx: ViteBuildContext): VitePlugin { +export function ViteNodePlugin (ctx: ViteBuildContext): VitePlugin { // Store the invalidates for the next rendering const invalidates = new Set()