diff --git a/packages/playground/css/__tests__/css.spec.ts b/packages/playground/css/__tests__/css.spec.ts index 34858ab34bc09d..3fe4a09bcc94c8 100644 --- a/packages/playground/css/__tests__/css.spec.ts +++ b/packages/playground/css/__tests__/css.spec.ts @@ -54,6 +54,12 @@ test('css import from js', async () => { await untilUpdated(() => getColor(atImport), 'blue') }) +test('css import asset with space', async () => { + const importedWithSpace = await page.$('.import-with-space') + + expect(await getBg(importedWithSpace)).toMatch(/.*ok\..*png/) +}) + test('postcss config', async () => { const imported = await page.$('.postcss .nesting') expect(await getColor(imported)).toBe('pink') diff --git a/packages/playground/css/folder with space/ok.png b/packages/playground/css/folder with space/ok.png new file mode 100644 index 00000000000000..a8d1e52510c41c Binary files /dev/null and b/packages/playground/css/folder with space/ok.png differ diff --git a/packages/playground/css/folder with space/space.css b/packages/playground/css/folder with space/space.css new file mode 100644 index 00000000000000..55a8532da32a94 --- /dev/null +++ b/packages/playground/css/folder with space/space.css @@ -0,0 +1,5 @@ +.import-with-space { + color: green; + background: url(spacefolder/ok.png); + background-position: center; +} diff --git a/packages/playground/css/imported.css b/packages/playground/css/imported.css index 65743d08b932a7..7d582995fab9fd 100644 --- a/packages/playground/css/imported.css +++ b/packages/playground/css/imported.css @@ -1,4 +1,5 @@ @import './imported-at-import.css'; +@import 'spacefolder/space.css'; .imported { color: green; diff --git a/packages/playground/css/index.html b/packages/playground/css/index.html index a09d8e6e7c46aa..060aed7fb1b27f 100644 --- a/packages/playground/css/index.html +++ b/packages/playground/css/index.html @@ -10,6 +10,10 @@

CSS

@import in import from js: This should be purple

+

+ @import from file with space: This should be green and have a background + image +

Imported css string:


   

diff --git a/packages/playground/css/vite.config.js b/packages/playground/css/vite.config.js
index 53d001d8387989..639a1302debb88 100644
--- a/packages/playground/css/vite.config.js
+++ b/packages/playground/css/vite.config.js
@@ -9,7 +9,8 @@ module.exports = {
   },
   resolve: {
     alias: {
-      '@': __dirname
+      '@': __dirname,
+      spacefolder: __dirname + '/folder with space'
     }
   },
   css: {
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 87de63ef3ec306..4933f8455931c1 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1029,7 +1029,12 @@ async function doUrlReplace(
     return matched
   }
 
-  return `url(${wrap}${await replacer(rawUrl)}${wrap})`
+  const newUrl = await replacer(rawUrl)
+  if (wrap === '' && newUrl !== encodeURI(newUrl)) {
+    // The new url might need wrapping even if the original did not have it, e.g. if a space was added during replacement
+    wrap = "'"
+  }
+  return `url(${wrap}${newUrl}${wrap})`
 }
 
 async function doImportCSSReplace(