diff --git a/packages/vite/src/utils/warmup.ts b/packages/vite/src/utils/warmup.ts index ac98838a82..7543460a32 100644 --- a/packages/vite/src/utils/warmup.ts +++ b/packages/vite/src/utils/warmup.ts @@ -1,6 +1,33 @@ import { logger } from '@nuxt/kit' +import { join, normalize, relative } from 'pathe' +import { withoutBase } from 'ufo' +import { isCSSRequest } from 'vite' import type { ViteDevServer } from 'vite' +// https://github.com/vitejs/vite/tree/main/packages/vite/src/node/server/warmup.ts#L62-L70 +function fileToUrl (file: string, root: string) { + const url = relative(root, file) + // out of root, use /@fs/ prefix + if (url[0] === '.') { + return join('/@fs/', normalize(file)) + } + // file within root, create root-relative url + return '/' + normalize(url) +} + +function normaliseURL (url: string, base: string) { + // remove any base url + url = withoutBase(url, base) + // unwrap record + if (url.startsWith('/@id/')) { + url = url.slice('/@id/'.length).replace('__x00__', '\0') + } + // strip query + url = url.replace(/(\?|&)import=?(?:&|$)/, '').replace(/[?&]$/, '') + return url +} + +// TODO: use built-in warmup logic when we update to vite 5 export async function warmupViteServer ( server: ViteDevServer, entries: string[], @@ -9,7 +36,12 @@ export async function warmupViteServer ( const warmedUrls = new Set() const warmup = async (url: string) => { - if (warmedUrls.has(url)) { + url = normaliseURL(url, server.config.base) + + if (warmedUrls.has(url)) { return } + const m = await server.moduleGraph.getModuleByUrl(url, isServer) + // a module that is already compiled (and can't be warmed up anyway) + if (m?.transformResult?.code || m?.ssrTransformResult?.code) { return } warmedUrls.add(url) @@ -18,10 +50,14 @@ export async function warmupViteServer ( } catch (e) { logger.debug('Warmup for %s failed with: %s', url, e) } + + // Don't warmup CSS file dependencies as they have already all been loaded to produce result + if (isCSSRequest(url)) { return } + const mod = await server.moduleGraph.getModuleByUrl(url, isServer) const deps = mod?.ssrTransformResult?.deps /* server */ || Array.from(mod?.importedModules /* client */ || []).map(m => m.url) - await Promise.all(deps.map(m => warmup(m.replace('/@id/__x00__', '\0')))) + await Promise.all(deps.map(m => warmup(m))) } - await Promise.all(entries.map(entry => warmup(entry))) + await Promise.all(entries.map(entry => warmup(fileToUrl(entry, server.config.root)))) } diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index 962c36f9c7..62d850872a 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -192,13 +192,9 @@ export const bundle: NuxtBuilder['bundle'] = async (nuxt) => { } }) - if ( - nuxt.options.vite.warmupEntry !== false && - // https://github.com/nuxt/nuxt/issues/14898 - !(env.isServer && ctx.nuxt.options.vite.devBundler !== 'legacy') - ) { + if (nuxt.options.vite.warmupEntry !== false) { const start = Date.now() - warmupViteServer(server, [join('/@fs/', ctx.entry)], env.isServer) + warmupViteServer(server, [ctx.entry], env.isServer) .then(() => logger.info(`Vite ${env.isClient ? 'client' : 'server'} warmed up in ${Date.now() - start}ms`)) .catch(logger.error) }