fix(vite): dev ssr fouc (#757)

This commit is contained in:
Anthony Fu 2021-10-12 22:05:20 +08:00 committed by GitHub
parent 2e87a76721
commit 44f8904957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 23 deletions

View File

@ -1,6 +1,5 @@
import { resolve } from 'pathe' import { resolve } from 'pathe'
import * as vite from 'vite' import * as vite from 'vite'
import fse from 'fs-extra'
import consola from 'consola' import consola from 'consola'
import vitePlugin from '@vitejs/plugin-vue' import vitePlugin from '@vitejs/plugin-vue'
@ -8,6 +7,7 @@ import { cacheDirPlugin } from './plugins/cache-dir'
import { replace } from './plugins/replace' import { replace } from './plugins/replace'
import { wpfs } from './utils/wpfs' import { wpfs } from './utils/wpfs'
import type { ViteBuildContext, ViteOptions } from './vite' import type { ViteBuildContext, ViteOptions } from './vite'
import { writeManifest } from './manifest'
export async function buildClient (ctx: ViteBuildContext) { export async function buildClient (ctx: ViteBuildContext) {
const clientConfig: vite.InlineConfig = vite.mergeConfig(ctx.config, { 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`) consola.info(`Client built in ${Date.now() - start}ms`)
} }
// Write client manifest for use in vue-bundle-renderer await writeManifest(ctx)
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')
} }

View File

@ -194,5 +194,8 @@ async function __instantiateModule__(url, urlStack) {
`export default await __ssrLoadModule__('${entryURL}')` `export default await __ssrLoadModule__('${entryURL}')`
].join('\n\n') ].join('\n\n')
return { code } return {
code,
ids: chunks.map(i => i.id)
}
} }

View File

@ -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')
}

View File

@ -9,6 +9,8 @@ import { ViteBuildContext, ViteOptions } from './vite'
import { wpfs } from './utils/wpfs' import { wpfs } from './utils/wpfs'
import { cacheDirPlugin } from './plugins/cache-dir' import { cacheDirPlugin } from './plugins/cache-dir'
import { bundleRequest } from './dev-bundler' import { bundleRequest } from './dev-bundler'
import { writeManifest } from './manifest'
import { isCSS } from './utils'
export async function buildServer (ctx: ViteBuildContext) { export async function buildServer (ctx: ViteBuildContext) {
const _resolve = id => resolveModule(id, { paths: ctx.nuxt.options.modulesDir }) const _resolve = id => resolveModule(id, { paths: ctx.nuxt.options.modulesDir })
@ -100,8 +102,10 @@ export async function buildServer (ctx: ViteBuildContext) {
// Build and watch // Build and watch
const _doBuild = async () => { const _doBuild = async () => {
const start = Date.now() 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') 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) const time = (Date.now() - start)
consola.success(`Vite server built in ${time}ms`) consola.success(`Vite server built in ${time}ms`)
await onBuild() await onBuild()

View File

@ -14,3 +14,9 @@ export function hash (input: string, length = 8) {
export function uniq<T> (arr: T[]): T[] { export function uniq<T> (arr: T[]): T[] {
return Array.from(new Set(arr)) return Array.from(new Set(arr))
} }
const IS_CSS_RE = /\.css(\?[^.]+)?$/
export function isCSS (file: string) {
return IS_CSS_RE.test(file)
}