mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-29 09:02:03 +00:00
fix(nuxt): do not inline global styles in html response (#8666)
This commit is contained in:
parent
cda89b36e1
commit
cda498b070
@ -289,19 +289,15 @@ 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 usedModules) {
|
||||||
if (mod in styleMap) {
|
if (mod in styleMap) {
|
||||||
for (const style of await styleMap[mod]()) {
|
for (const style of await styleMap[mod]()) {
|
||||||
inlinedStyles.add(`<style>${style}</style>`)
|
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('')
|
return Array.from(inlinedStyles).join('')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import { dirname, relative } from 'pathe'
|
|||||||
import { genObjectFromRawEntries } from 'knitwork'
|
import { genObjectFromRawEntries } from 'knitwork'
|
||||||
import { filename } from 'pathe/utils'
|
import { filename } from 'pathe/utils'
|
||||||
import { parseQuery, parseURL } from 'ufo'
|
import { parseQuery, parseURL } from 'ufo'
|
||||||
import { isCSS } from '../utils'
|
|
||||||
|
|
||||||
interface SSRStylePluginOptions {
|
interface SSRStylePluginOptions {
|
||||||
srcDir: string
|
srcDir: string
|
||||||
@ -16,7 +15,6 @@ interface SSRStylePluginOptions {
|
|||||||
export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
||||||
const cssMap: Record<string, { files: string[], inBundle: boolean }> = {}
|
const cssMap: Record<string, { files: string[], inBundle: boolean }> = {}
|
||||||
const idRefMap: Record<string, string> = {}
|
const idRefMap: Record<string, string> = {}
|
||||||
const globalStyles = new Set<string>()
|
|
||||||
|
|
||||||
const relativeToSrcDir = (path: string) => relative(options.srcDir, path)
|
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) {
|
for (const key in emitted) {
|
||||||
// Track the chunks we are inlining CSS for so we can omit including links to the .css files
|
// Track the chunks we are inlining CSS for so we can omit including links to the .css files
|
||||||
options.chunksWithInlinedCSS.add(key)
|
options.chunksWithInlinedCSS.add(key)
|
||||||
@ -61,12 +57,10 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
|||||||
fileName: 'styles.mjs',
|
fileName: 'styles.mjs',
|
||||||
source:
|
source:
|
||||||
[
|
[
|
||||||
...globalStylesArray.map((css, i) => `import style_${i} from './${css}';`),
|
|
||||||
'const interopDefault = r => r.default || r || []',
|
'const interopDefault = r => r.default || r || []',
|
||||||
`export default ${genObjectFromRawEntries([
|
`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][]
|
||||||
...Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`]) as [string, string][]
|
)}`
|
||||||
])}`
|
|
||||||
].join('\n')
|
].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
|
return null
|
||||||
},
|
},
|
||||||
async transform (code, id) {
|
async transform (code, id) {
|
||||||
|
@ -126,16 +126,6 @@ export async function buildServer (ctx: ViteBuildContext) {
|
|||||||
if (shouldRemoveCSS) {
|
if (shouldRemoveCSS) {
|
||||||
entry.css = []
|
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')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -598,19 +598,18 @@ describe.skipIf(process.env.NUXT_TEST_DEV || process.env.TEST_WITH_WEBPACK)('inl
|
|||||||
for (const style of [
|
for (const style of [
|
||||||
'{--assets:"assets"}', // <script>
|
'{--assets:"assets"}', // <script>
|
||||||
'{--scoped:"scoped"}', // <style lang=css>
|
'{--scoped:"scoped"}', // <style lang=css>
|
||||||
'{--postcss:"postcss"}', // <style lang=postcss>
|
'{--postcss:"postcss"}' // <style lang=postcss>
|
||||||
'{--global:"global"', // entryfile dependency
|
|
||||||
'{--plugin:"plugin"}' // plugin dependency
|
|
||||||
]) {
|
]) {
|
||||||
expect(html).toContain(style)
|
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')
|
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(`
|
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\\">",
|
||||||
]
|
]
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user