diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index f71185a96e..7b787f38f0 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -1,6 +1,5 @@ import { resolve } from 'pathe' import * as vite from 'vite' -import fse from 'fs-extra' import consola from 'consola' import vitePlugin from '@vitejs/plugin-vue' @@ -8,6 +7,7 @@ import { cacheDirPlugin } from './plugins/cache-dir' import { replace } from './plugins/replace' import { wpfs } from './utils/wpfs' import type { ViteBuildContext, ViteOptions } from './vite' +import { writeManifest } from './manifest' export async function buildClient (ctx: ViteBuildContext) { const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, { @@ -68,24 +68,5 @@ export async function buildClient (ctx: ViteBuildContext) { consola.info(`Client built in ${Date.now() - start}ms`) } - // Write client manifest for use in vue-bundle-renderer - const clientDist = resolve(ctx.nuxt.options.buildDir, 'dist/client') - const serverDist = resolve(ctx.nuxt.options.buildDir, 'dist/server') - - // Legacy dev manifest - const devClientManifest = { - publicPath: ctx.nuxt.options.build.publicPath, - all: ['@vite/client', 'entry.mjs'], - initial: ['@vite/client', 'entry.mjs'], - async: [], - modules: {} - } - - const clientManifest = ctx.nuxt.options.dev - ? devClientManifest - : await fse.readJSON(resolve(clientDist, 'manifest.json')) - - await fse.mkdirp(serverDist) - await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(clientManifest, null, 2), 'utf8') - await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), 'export default ' + JSON.stringify(clientManifest, null, 2), 'utf8') + await writeManifest(ctx) } diff --git a/packages/vite/src/dev-bundler.ts b/packages/vite/src/dev-bundler.ts index 93e0cd4f8b..36748427ef 100644 --- a/packages/vite/src/dev-bundler.ts +++ b/packages/vite/src/dev-bundler.ts @@ -194,5 +194,8 @@ async function __instantiateModule__(url, urlStack) { `export default await __ssrLoadModule__('${entryURL}')` ].join('\n\n') - return { code } + return { + code, + ids: chunks.map(i => i.id) + } } diff --git a/packages/vite/src/manifest.ts b/packages/vite/src/manifest.ts new file mode 100644 index 0000000000..a67cdbce3a --- /dev/null +++ b/packages/vite/src/manifest.ts @@ -0,0 +1,32 @@ +import fse from 'fs-extra' +import { resolve } from 'pathe' +import type { ViteBuildContext } from './vite' + +export async function writeManifest (ctx: ViteBuildContext, extracEntries: string[] = []) { + // Write client manifest for use in vue-bundle-renderer + const clientDist = resolve(ctx.nuxt.options.buildDir, 'dist/client') + const serverDist = resolve(ctx.nuxt.options.buildDir, 'dist/server') + + const entries = [ + '@vite/client', + 'entry.mjs', + ...extracEntries + ] + + // Legacy dev manifest + const devClientManifest = { + publicPath: ctx.nuxt.options.build.publicPath, + all: entries, + initial: entries, + async: [], + modules: {} + } + + const clientManifest = ctx.nuxt.options.dev + ? devClientManifest + : await fse.readJSON(resolve(clientDist, 'manifest.json')) + + await fse.mkdirp(serverDist) + await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(clientManifest, null, 2), 'utf8') + await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), 'export default ' + JSON.stringify(clientManifest, null, 2), 'utf8') +} diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index 4990012462..5966f8f937 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -9,6 +9,8 @@ import { ViteBuildContext, ViteOptions } from './vite' import { wpfs } from './utils/wpfs' import { cacheDirPlugin } from './plugins/cache-dir' import { bundleRequest } from './dev-bundler' +import { writeManifest } from './manifest' +import { isCSS } from './utils' export async function buildServer (ctx: ViteBuildContext) { const _resolve = id => resolveModule(id, { paths: ctx.nuxt.options.modulesDir }) @@ -100,8 +102,10 @@ export async function buildServer (ctx: ViteBuildContext) { // Build and watch const _doBuild = async () => { const start = Date.now() - const { code } = await bundleRequest({ viteServer }, resolve(ctx.nuxt.options.appDir, 'entry')) + const { code, ids } = await bundleRequest({ viteServer }, resolve(ctx.nuxt.options.appDir, 'entry')) await fse.writeFile(resolve(ctx.nuxt.options.buildDir, 'dist/server/server.mjs'), code, 'utf-8') + // Have CSS in the manifest to prevent FOUC on dev SSR + await writeManifest(ctx, ids.filter(isCSS).map(i => i.slice(1))) const time = (Date.now() - start) consola.success(`Vite server built in ${time}ms`) await onBuild() diff --git a/packages/vite/src/utils.ts b/packages/vite/src/utils.ts index e382d69de4..5466159941 100644 --- a/packages/vite/src/utils.ts +++ b/packages/vite/src/utils.ts @@ -14,3 +14,9 @@ export function hash (input: string, length = 8) { export function uniq (arr: T[]): T[] { return Array.from(new Set(arr)) } + +const IS_CSS_RE = /\.css(\?[^.]+)?$/ + +export function isCSS (file: string) { + return IS_CSS_RE.test(file) +}