mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
fix(vite): emit assets referenced in inline css (#21790)
This commit is contained in:
parent
58e75689d8
commit
12403d160f
@ -41,15 +41,13 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
||||
resolveId: {
|
||||
order: 'pre',
|
||||
async handler (id, importer, _options) {
|
||||
// We deliberately prevent importing `#build/css` to avoid including it in the client bundle
|
||||
// in its entirety. We will instead include _just_ the styles that can't be inlined,
|
||||
// in the <NuxtRoot> component below
|
||||
if (options.mode === 'client' && id === '#build/css' && (options.shouldInline === true || (typeof options.shouldInline === 'function' && options.shouldInline(importer)))) {
|
||||
return this.resolve('unenv/runtime/mock/empty', importer, _options)
|
||||
// We want to remove side effects (namely, emitting CSS) from `.vue` files and explicitly imported `.css` files
|
||||
// but only as long as we are going to inline that CSS.
|
||||
if ((options.shouldInline === false || (typeof options.shouldInline === 'function' && !options.shouldInline(importer)))) {
|
||||
return
|
||||
}
|
||||
|
||||
if (options.mode === 'client' || !id.endsWith('.vue')) { return }
|
||||
|
||||
if (id === '#build/css' || id.endsWith('.vue') || isCSS(id)) {
|
||||
const res = await this.resolve(id, importer, { ..._options, skipSelf: true })
|
||||
if (res) {
|
||||
return {
|
||||
@ -58,6 +56,7 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
generateBundle (outputOptions) {
|
||||
if (options.mode === 'client') { return }
|
||||
|
@ -1180,6 +1180,13 @@ describe.skipIf(isDev() || isWebpack)('inlining component styles', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('should emit assets referenced in inlined CSS', async () => {
|
||||
// @ts-expect-error ssssh! untyped secret property
|
||||
const publicDir = useTestContext().nuxt._nitro.options.output.publicDir
|
||||
const files = await readdir(join(publicDir, '_nuxt')).catch(() => [])
|
||||
expect(files.map(m => m.replace(/\.\w+(\.\w+)$/, '$1'))).toContain('css-only-asset.svg')
|
||||
})
|
||||
|
||||
it('should not include inlined CSS in generated CSS file', async () => {
|
||||
const html: string = await $fetch('/styles')
|
||||
const cssFiles = new Set([...html.matchAll(/<link [^>]*href="([^"]*\.css)">/g)].map(m => m[1]))
|
||||
|
7
test/fixtures/basic/assets/css-only-asset.svg
vendored
Normal file
7
test/fixtures/basic/assets/css-only-asset.svg
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<svg viewBox="0 0 221 65" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-8">
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path fill="#fff" d="M0 0h221v65H0z"></path>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 201 B |
2
test/fixtures/basic/assets/global.css
vendored
2
test/fixtures/basic/assets/global.css
vendored
@ -1,4 +1,4 @@
|
||||
:root {
|
||||
--global: 'global';
|
||||
--asset: url('~/assets/logo.svg');
|
||||
--asset: url('~/assets/css-only-asset.svg');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user