Skip to content

Commit ea6a7a6

Browse files
authored
fix(build): decode urls in CSS files (fix #15109) (#15246)
1 parent 921ca41 commit ea6a7a6

File tree

5 files changed

+23
-6
lines changed

5 files changed

+23
-6
lines changed

packages/vite/src/node/plugins/css.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -264,22 +264,23 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
264264
const ssr = options?.ssr === true
265265

266266
const urlReplacer: CssUrlReplacer = async (url, importer) => {
267-
if (checkPublicFile(url, config)) {
267+
const decodedUrl = decodeURI(url)
268+
if (checkPublicFile(decodedUrl, config)) {
268269
if (encodePublicUrlsInCSS(config)) {
269-
return publicFileToBuiltUrl(url, config)
270+
return publicFileToBuiltUrl(decodedUrl, config)
270271
} else {
271-
return joinUrlSegments(config.base, url)
272+
return joinUrlSegments(config.base, decodedUrl)
272273
}
273274
}
274-
const resolved = await resolveUrl(url, importer)
275+
const resolved = await resolveUrl(decodedUrl, importer)
275276
if (resolved) {
276277
return fileToUrl(resolved, config, this)
277278
}
278279
if (config.command === 'build') {
279280
const isExternal = config.build.rollupOptions.external
280281
? resolveUserExternal(
281282
config.build.rollupOptions.external,
282-
url, // use URL as id since id could not be resolved
283+
decodedUrl, // use URL as id since id could not be resolved
283284
id,
284285
false,
285286
)
@@ -288,7 +289,7 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
288289
if (!isExternal) {
289290
// #9800 If we cannot resolve the css url, leave a warning.
290291
config.logger.warnOnce(
291-
`\n${url} referenced in ${id} didn't resolve at build time, it will remain unchanged to be resolved at runtime`,
292+
`\n${decodedUrl} referenced in ${id} didn't resolve at build time, it will remain unchanged to be resolved at runtime`,
292293
)
293294
}
294295
}

playground/assets/__tests__/assets.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ const assetMatch = isBuild
2323
? /\/foo\/bar\/assets\/asset-[-\w]{8}\.png/
2424
: '/foo/bar/nested/asset.png'
2525

26+
const encodedAssetMatch = isBuild
27+
? /\/foo\/bar\/assets\/asset_small_-[-\w]{8}\.png/
28+
: '/foo/bar/nested/asset[small].png'
29+
2630
const iconMatch = `/foo/bar/icon.png`
2731

2832
const fetchPath = (p: string) => {
@@ -153,6 +157,10 @@ describe('css url() references', () => {
153157
expect(await getBg('.css-url-relative')).toMatch(assetMatch)
154158
})
155159

160+
test('encoded', async () => {
161+
expect(await getBg('.css-url-encoded')).toMatch(encodedAssetMatch)
162+
})
163+
156164
test('image-set relative', async () => {
157165
const imageSet = await getBg('.css-image-set-relative')
158166
imageSet.split(', ').forEach((s) => {

playground/assets/css/css-url.css

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/assets/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ <h2>CSS url references</h2>
4141
<div class="css-url-relative">
4242
<span style="background: #fff">CSS background (relative)</span>
4343
</div>
44+
<div class="css-url-encoded">
45+
<span style="background: #fff">CSS background (encoded)</span>
46+
</div>
4447
<div class="css-image-set-relative">
4548
<span style="background: #fff"
4649
>CSS background with image-set() (relative)</span
10.9 KB
Loading

0 commit comments

Comments
 (0)