mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
fix(vite): emit assets referenced in inline css (#21790)
This commit is contained in:
parent
58e75689d8
commit
12403d160f
@ -41,20 +41,19 @@ export function ssrStylesPlugin (options: SSRStylePluginOptions): Plugin {
|
|||||||
resolveId: {
|
resolveId: {
|
||||||
order: 'pre',
|
order: 'pre',
|
||||||
async handler (id, importer, _options) {
|
async handler (id, importer, _options) {
|
||||||
// We deliberately prevent importing `#build/css` to avoid including it in the client bundle
|
// We want to remove side effects (namely, emitting CSS) from `.vue` files and explicitly imported `.css` files
|
||||||
// in its entirety. We will instead include _just_ the styles that can't be inlined,
|
// but only as long as we are going to inline that CSS.
|
||||||
// in the <NuxtRoot> component below
|
if ((options.shouldInline === false || (typeof options.shouldInline === 'function' && !options.shouldInline(importer)))) {
|
||||||
if (options.mode === 'client' && id === '#build/css' && (options.shouldInline === true || (typeof options.shouldInline === 'function' && options.shouldInline(importer)))) {
|
return
|
||||||
return this.resolve('unenv/runtime/mock/empty', importer, _options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 })
|
||||||
const res = await this.resolve(id, importer, { ..._options, skipSelf: true })
|
if (res) {
|
||||||
if (res) {
|
return {
|
||||||
return {
|
...res,
|
||||||
...res,
|
moduleSideEffects: false
|
||||||
moduleSideEffects: false
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 () => {
|
it('should not include inlined CSS in generated CSS file', async () => {
|
||||||
const html: string = await $fetch('/styles')
|
const html: string = await $fetch('/styles')
|
||||||
const cssFiles = new Set([...html.matchAll(/<link [^>]*href="([^"]*\.css)">/g)].map(m => m[1]))
|
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 {
|
:root {
|
||||||
--global: 'global';
|
--global: 'global';
|
||||||
--asset: url('~/assets/logo.svg');
|
--asset: url('~/assets/css-only-asset.svg');
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user