diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 873bcfc360d79b..46db13a0f15f51 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -3237,21 +3237,25 @@ async function compileLightningCSS( let css = decoder.decode(res.code) for (const dep of res.dependencies!) { switch (dep.type) { - case 'url': + case 'url': { + let replaceUrl: string if (skipUrlReplacer(dep.url)) { - css = css.replace(dep.placeholder, () => dep.url) - break - } - if (urlReplacer) { - const replaceUrl = await urlReplacer( - dep.url, - toAbsolute(dep.loc.filePath), - ) - css = css.replace(dep.placeholder, () => replaceUrl) + replaceUrl = dep.url + } else if (urlReplacer) { + replaceUrl = await urlReplacer(dep.url, toAbsolute(dep.loc.filePath)) } else { - css = css.replace(dep.placeholder, () => dep.url) + replaceUrl = dep.url } + + css = css.replace( + dep.placeholder, + // lightningcss always generates `url("placeholder")` + // (`url('placeholder')`, `url(placeholder)` is not generated) + // so escape double quotes + () => replaceUrl.replaceAll('"', '\\"'), + ) break + } default: throw new Error(`Unsupported dependency type: ${dep.type}`) } diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts index 0f33ca7d4b55fb..b778c6718cdf69 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -276,6 +276,12 @@ describe('css url() references', () => { expect(bg).toMatch(assetMatch) }) + test('preinlined SVG', async () => { + expect(await getBg('.css-url-preinlined-svg')).toMatch( + /data:image\/svg\+xml,.+/, + ) + }) + test.runIf(isBuild)('generated paths in CSS', () => { const css = findAssetFile(/index-[-\w]{8}\.css$/, 'foo') diff --git a/playground/assets/css/css-url.css b/playground/assets/css/css-url.css index 61282fb20fa3b7..caab9bf8f96cf6 100644 --- a/playground/assets/css/css-url.css +++ b/playground/assets/css/css-url.css @@ -104,6 +104,11 @@ background-size: 10px; } +.css-url-preinlined-svg { + background: url('data:image/svg+xml,'); + background-size: 20px; +} + /* urls inside comments should be ignored diff --git a/playground/assets/index.html b/playground/assets/index.html index e41ae78cff0227..b6055c78cc4e3f 100644 --- a/playground/assets/index.html +++ b/playground/assets/index.html @@ -139,6 +139,9 @@