fix(nuxt): lazy-load entry CSS (#8278)

This commit is contained in:
Daniel Roe 2022-10-18 17:13:50 +01:00 committed by GitHub
parent 1c2d6e4e29
commit cfaa46201a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 11 deletions

View File

@ -10,7 +10,12 @@ import { useRuntimeConfig, useNitroApp, defineRenderHandler, getRouteRules } fro
import type { NuxtApp, NuxtSSRContext } from '#app' import type { NuxtApp, NuxtSSRContext } from '#app'
// @ts-ignore // @ts-ignore
import { buildAssetsURL } from '#paths' import { buildAssetsURL, publicAssetsURL } from '#paths'
// @ts-ignore
globalThis.__buildAssetsURL = buildAssetsURL
// @ts-ignore
globalThis.__publicAssetsURL = publicAssetsURL
export interface NuxtRenderHTMLContext { export interface NuxtRenderHTMLContext {
htmlAttrs: string[] htmlAttrs: string[]
@ -198,7 +203,7 @@ export default defineRenderHandler(async (event) => {
const renderedMeta = await ssrContext.renderMeta?.() ?? {} const renderedMeta = await ssrContext.renderMeta?.() ?? {}
// Render inline styles // Render inline styles
const inlinedStyles = process.env.NUXT_INLINE_STYLES && !(process.env.NUXT_NO_SSR || ssrContext.noSSR) const inlinedStyles = process.env.NUXT_INLINE_STYLES
? await renderInlineStyles(ssrContext.modules ?? ssrContext._registeredComponents ?? []) ? await renderInlineStyles(ssrContext.modules ?? ssrContext._registeredComponents ?? [])
: '' : ''
@ -284,6 +289,7 @@ function renderHTMLDocument (html: NuxtRenderHTMLContext) {
} }
async function renderInlineStyles (usedModules: Set<string> | string[]) { async function renderInlineStyles (usedModules: Set<string> | string[]) {
const { entryCSS } = await getClientManifest()
const styleMap = await getSSRStyles() const styleMap = await getSSRStyles()
const inlinedStyles = new Set<string>() const inlinedStyles = new Set<string>()
for (const mod of ['entry', ...usedModules]) { for (const mod of ['entry', ...usedModules]) {
@ -293,6 +299,9 @@ async function renderInlineStyles (usedModules: Set<string> | string[]) {
} }
} }
} }
for (const css of entryCSS?.css || []) {
inlinedStyles.add(`<link rel="stylesheet" href=${JSON.stringify(buildAssetsURL(css))} media="print" onload="this.media='all'; this.onload=null;">`)
}
return Array.from(inlinedStyles).join('') return Array.from(inlinedStyles).join('')
} }

View File

@ -240,8 +240,11 @@ export const publicPathTemplate: NuxtTemplate = {
' return path.length ? joinURL(publicBase, ...path) : publicBase', ' return path.length ? joinURL(publicBase, ...path) : publicBase',
'}', '}',
// On server these are registered directly in packages/nuxt/src/core/runtime/nitro/renderer.ts
'if (process.client) {',
' globalThis.__buildAssetsURL = buildAssetsURL', ' globalThis.__buildAssetsURL = buildAssetsURL',
'globalThis.__publicAssetsURL = publicAssetsURL' ' globalThis.__publicAssetsURL = publicAssetsURL',
'}'
].filter(Boolean).join('\n') ].filter(Boolean).join('\n')
} }
} }

View File

@ -129,13 +129,13 @@ export async function buildServer (ctx: ViteBuildContext) {
} }
// Add entry CSS as prefetch (non-blocking) // Add entry CSS as prefetch (non-blocking)
if (entry.isEntry) { if (entry.isEntry) {
manifest[key + '-css'] = { manifest.entryCSS = {
file: '', file: '',
css: entry.css css: entry.css
} }
entry.css = [] entry.css = []
entry.dynamicImports = entry.dynamicImports || [] entry.dynamicImports = entry.dynamicImports || []
entry.dynamicImports.push(key + '-css') entry.dynamicImports.push('entryCSS')
} }
} }
}) })

View File

@ -616,8 +616,7 @@ describe.skipIf(process.env.NUXT_TEST_DEV || process.env.TEST_WITH_WEBPACK)('inl
`) `)
}) })
// TODO: fix this in style inlining implementation: https://github.com/nuxt/framework/pull/8265#issuecomment-1282148407 it('still downloads client-only styles', async () => {
it.skip('still downloads client-only styles', async () => {
const page = await createPage('/styles') const page = await createPage('/styles')
await page.waitForLoadState('networkidle') await page.waitForLoadState('networkidle')
expect(await page.$eval('.client-only-css', e => getComputedStyle(e).color)).toBe('rgb(50, 50, 50)') expect(await page.$eval('.client-only-css', e => getComputedStyle(e).color)).toBe('rgb(50, 50, 50)')

View File

@ -1 +1,3 @@
export default () => 'foo' import { eventHandler } from 'h3'
export default eventHandler(() => 'foo')

View File

@ -1,4 +1,6 @@
// TODO: add back TypeScript and auto-importing once Nitro supports it // TODO: add back TypeScript and auto-importing once Nitro supports it
export default (event) => { import { eventHandler } from 'h3'
export default eventHandler((event) => {
event.res.setHeader('injected-header', 'foo') event.res.setHeader('injected-header', 'foo')
} })