fix(nuxt): do not inline global styles in html response (#8666)

This commit is contained in:
Daniel Roe 2022-11-03 15:17:43 -04:00 committed by GitHub
parent cda89b36e1
commit cda498b070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 8 additions and 37 deletions

View File

@ -289,19 +289,15 @@ function renderHTMLDocument (html: NuxtRenderHTMLContext) {
}
async function renderInlineStyles (usedModules: Set<string> | string[]) {
const { entryCSS } = await getClientManifest()
const styleMap = await getSSRStyles()
const inlinedStyles = new Set<string>()
for (const mod of ['entry', ...usedModules]) {
for (const mod of usedModules) {
if (mod in styleMap) {
for (const style of await styleMap[mod]()) {
inlinedStyles.add(`<style>${style}</style>`)
}
}
}
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('')
}

View File

@ -5,7 +5,6 @@ import { dirname, relative } from 'pathe'
import { genObjectFromRawEntries } from 'knitwork'
import { filename } from 'pathe/utils'
import { parseQuery, parseURL } from 'ufo'
import { isCSS } from '../utils'
interface SSRStylePluginOptions {
srcDir: string
@ -16,7 +15,6 @@ interface SSRStylePluginOptions {
export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
const cssMap: Record<string, { files: string[], inBundle: boolean }> = {}
const idRefMap: Record<string, string> = {}
const globalStyles = new Set<string>()
const relativeToSrcDir = (path: string) => relative(options.srcDir, path)
@ -49,8 +47,6 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
})
}
const globalStylesArray = Array.from(globalStyles).map(css => idRefMap[css] && this.getFileName(idRefMap[css])).filter(Boolean)
for (const key in emitted) {
// Track the chunks we are inlining CSS for so we can omit including links to the .css files
options.chunksWithInlinedCSS.add(key)
@ -61,12 +57,10 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
fileName: 'styles.mjs',
source:
[
...globalStylesArray.map((css, i) => `import style_${i} from './${css}';`),
'const interopDefault = r => r.default || r || []',
`export default ${genObjectFromRawEntries([
['entry', `() => [${globalStylesArray.map((_, i) => `style_${i}`).join(', ')}]`],
...Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`]) as [string, string][]
])}`
`export default ${genObjectFromRawEntries(
Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`]) as [string, string][]
)}`
].join('\n')
})
},
@ -80,14 +74,6 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
}
}
if (chunk.isEntry) {
// Entry
for (const mod in chunk.modules) {
if (isCSS(mod) && !mod.includes('&used')) {
globalStyles.add(relativeToSrcDir(mod))
}
}
}
return null
},
async transform (code, id) {

View File

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

View File

@ -598,19 +598,18 @@ describe.skipIf(process.env.NUXT_TEST_DEV || process.env.TEST_WITH_WEBPACK)('inl
for (const style of [
'{--assets:"assets"}', // <script>
'{--scoped:"scoped"}', // <style lang=css>
'{--postcss:"postcss"}', // <style lang=postcss>
'{--global:"global"', // entryfile dependency
'{--plugin:"plugin"}' // plugin dependency
'{--postcss:"postcss"}' // <style lang=postcss>
]) {
expect(html).toContain(style)
}
})
it('only renders prefetch for entry styles', async () => {
it('does not load stylesheet for page styles', async () => {
const html: string = await $fetch('/styles')
expect(html.match(/<link [^>]*href="[^"]*\.css">/g)?.filter(m => m.includes('entry'))?.map(m => m.replace(/\.[^.]*\.css/, '.css'))).toMatchInlineSnapshot(`
[
"<link rel=\\"prefetch\\" as=\\"style\\" href=\\"/_nuxt/entry.css\\">",
"<link rel=\\"preload\\" as=\\"style\\" href=\\"/_nuxt/entry.css\\">",
"<link rel=\\"stylesheet\\" href=\\"/_nuxt/entry.css\\">",
]
`)
})