From b28cc04ee9cf655fa6343f3d7c51c902b73250f2 Mon Sep 17 00:00:00 2001
From: frank
Date: Fri, 24 Jun 2022 22:03:19 +0800
Subject: [PATCH 1/5] fix(css):url() with variable or relative path in
sass/scss is broken (fix:#7651)
---
packages/vite/src/node/plugins/css.ts | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index ad46e5ba738f37..b8234c749fdf7b 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1209,10 +1209,17 @@ UrlRewritePostcssPlugin.postcss = true
function rewriteCssUrls(
css: string,
- replacer: CssUrlReplacer
+ replacer: CssUrlReplacer,
+ file?: string
): Promise {
return asyncReplace(css, cssUrlRE, async (match) => {
const [matched, rawUrl] = match
+ const inLess = file?.endsWith('.less')
+ const inSass = file?.endsWith('.sass')
+ const inScss = file?.endsWith('.scss')
+ if (inLess && rawUrl.startsWith('@') || (inSass || inScss) && rawUrl.startsWith('$')) {
+ return `url('${rawUrl}')`
+ }
return await doUrlReplace(rawUrl, matched, replacer)
})
}
@@ -1621,7 +1628,7 @@ async function rebaseUrls(
}
if (hasUrls) {
- rebased = await rewriteCssUrls(rebased || content, rebaseFn)
+ rebased = await rewriteCssUrls(rebased || content, rebaseFn, file)
}
if (hasDataUris) {
From 4ac0fba581ace57fd6711bf32262e4b4fea56509 Mon Sep 17 00:00:00 2001
From: frank
Date: Fri, 24 Jun 2022 22:39:38 +0800
Subject: [PATCH 2/5] chore:prettier
---
packages/vite/src/node/plugins/css.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index b8234c749fdf7b..6c7a5ad14dc608 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1217,7 +1217,10 @@ function rewriteCssUrls(
const inLess = file?.endsWith('.less')
const inSass = file?.endsWith('.sass')
const inScss = file?.endsWith('.scss')
- if (inLess && rawUrl.startsWith('@') || (inSass || inScss) && rawUrl.startsWith('$')) {
+ if (
+ (inLess && rawUrl.startsWith('@')) ||
+ ((inSass || inScss) && rawUrl.startsWith('$'))
+ ) {
return `url('${rawUrl}')`
}
return await doUrlReplace(rawUrl, matched, replacer)
From d80a02769127df9fbff9df7a223c9e11b4d62a58 Mon Sep 17 00:00:00 2001
From: sapphi-red
Date: Mon, 31 Oct 2022 22:24:49 +0900
Subject: [PATCH 3/5] refactor: variablePrefix
---
packages/vite/src/node/plugins/css.ts | 28 +++++++++++++--------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 6c7a5ad14dc608..d107b13ed60017 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1209,20 +1209,10 @@ UrlRewritePostcssPlugin.postcss = true
function rewriteCssUrls(
css: string,
- replacer: CssUrlReplacer,
- file?: string
+ replacer: CssUrlReplacer
): Promise {
return asyncReplace(css, cssUrlRE, async (match) => {
const [matched, rawUrl] = match
- const inLess = file?.endsWith('.less')
- const inSass = file?.endsWith('.sass')
- const inScss = file?.endsWith('.scss')
- if (
- (inLess && rawUrl.startsWith('@')) ||
- ((inSass || inScss) && rawUrl.startsWith('$'))
- ) {
- return `url('${rawUrl}')`
- }
return await doUrlReplace(rawUrl, matched, replacer)
})
}
@@ -1503,7 +1493,7 @@ const scss: SassStylePreprocessor = async (
const internalImporter: Sass.Importer = (url, importer, done) => {
resolvers.sass(url, importer).then((resolved) => {
if (resolved) {
- rebaseUrls(resolved, options.filename, options.alias)
+ rebaseUrls(resolved, options.filename, options.alias, '$')
.then((data) => done?.(data))
.catch((data) => done?.(data))
} else {
@@ -1587,7 +1577,8 @@ const sass: SassStylePreprocessor = (source, root, options, aliasResolver) =>
async function rebaseUrls(
file: string,
rootFile: string,
- alias: Alias[]
+ alias: Alias[],
+ variablePrefix: string
): Promise {
file = path.resolve(file) // ensure os-specific flashes
// in the same dir, no need to rebase
@@ -1612,6 +1603,8 @@ async function rebaseUrls(
let rebased
const rebaseFn = (url: string) => {
if (url.startsWith('/')) return url
+ // ignore url's starting with variable
+ if (url.startsWith(variablePrefix)) return url
// match alias, no need to rewrite
for (const { find } of alias) {
const matches =
@@ -1631,7 +1624,7 @@ async function rebaseUrls(
}
if (hasUrls) {
- rebased = await rewriteCssUrls(rebased || content, rebaseFn, file)
+ rebased = await rewriteCssUrls(rebased || content, rebaseFn)
}
if (hasDataUris) {
@@ -1744,7 +1737,12 @@ function createViteLessPlugin(
path.join(dir, '*')
)
if (resolved) {
- const result = await rebaseUrls(resolved, this.rootFile, this.alias)
+ const result = await rebaseUrls(
+ resolved,
+ this.rootFile,
+ this.alias,
+ '@'
+ )
let contents: string
if (result && 'contents' in result) {
contents = result.contents
From f68b907ad5331eef57eb258028ab0d9f82a8b1b0 Mon Sep 17 00:00:00 2001
From: sapphi-red
Date: Tue, 1 Nov 2022 00:16:11 +0900
Subject: [PATCH 4/5] refactor: replace alias from @ to =
---
playground/css/composes-path-resolving.module.css | 6 +++---
playground/css/less.less | 2 +-
playground/css/linked.css | 2 +-
playground/css/nested/_index.scss | 2 +-
playground/css/nested/nested.less | 2 +-
playground/css/nested/nested.sss | 2 +-
playground/css/nested/nested.styl | 2 +-
playground/css/sass.scss | 8 ++++----
playground/css/sugarss.sss | 2 +-
playground/css/vite.config.js | 2 +-
10 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/playground/css/composes-path-resolving.module.css b/playground/css/composes-path-resolving.module.css
index 4fe7cdbad42136..a5a5172eb4104c 100644
--- a/playground/css/composes-path-resolving.module.css
+++ b/playground/css/composes-path-resolving.module.css
@@ -1,11 +1,11 @@
.path-resolving-css {
- composes: apply-color from '@/composed.module.css';
+ composes: apply-color from '=/composed.module.css';
}
.path-resolving-sass {
- composes: apply-color from '@/composed.module.scss';
+ composes: apply-color from '=/composed.module.scss';
}
.path-resolving-less {
- composes: apply-color from '@/composed.module.less';
+ composes: apply-color from '=/composed.module.less';
}
diff --git a/playground/css/less.less b/playground/css/less.less
index 49cbd3c3bb336e..f5f6fa52b36740 100644
--- a/playground/css/less.less
+++ b/playground/css/less.less
@@ -1,4 +1,4 @@
-@import '@/nested/nested';
+@import '=/nested/nested';
@import './nested/css-in-less.less';
// Test data-uri calls with relative images.
diff --git a/playground/css/linked.css b/playground/css/linked.css
index ff38b8bc9345ba..55b11f672fc500 100644
--- a/playground/css/linked.css
+++ b/playground/css/linked.css
@@ -1,4 +1,4 @@
-@import '@/linked-at-import.css';
+@import '=/linked-at-import.css';
/* test postcss nesting */
.wrapper {
diff --git a/playground/css/nested/_index.scss b/playground/css/nested/_index.scss
index 48d630b573ae1b..192e9de3b0e203 100644
--- a/playground/css/nested/_index.scss
+++ b/playground/css/nested/_index.scss
@@ -7,5 +7,5 @@
.sass-at-import-alias {
color: olive;
- background: url(@/nested/icon.png) 10px no-repeat;
+ background: url(=/nested/icon.png) 10px no-repeat;
}
diff --git a/playground/css/nested/nested.less b/playground/css/nested/nested.less
index e4ce110ab73679..f5a40a69d88839 100644
--- a/playground/css/nested/nested.less
+++ b/playground/css/nested/nested.less
@@ -5,5 +5,5 @@
.less-at-import-alias {
color: darkslateblue;
- background: url(@/nested/icon.png) 10px no-repeat;
+ background: url(=/nested/icon.png) 10px no-repeat;
}
diff --git a/playground/css/nested/nested.sss b/playground/css/nested/nested.sss
index 2de4c96564a100..9dc685cb3e50c3 100644
--- a/playground/css/nested/nested.sss
+++ b/playground/css/nested/nested.sss
@@ -5,4 +5,4 @@
.sugarss-at-import-alias
color: darkslateblue
- background: url(@/nested/icon.png) 10px no-repeat
+ background: url(=/nested/icon.png) 10px no-repeat
diff --git a/playground/css/nested/nested.styl b/playground/css/nested/nested.styl
index 72e6f7a5074685..8a371948538de0 100644
--- a/playground/css/nested/nested.styl
+++ b/playground/css/nested/nested.styl
@@ -3,4 +3,4 @@
.stylus-import-alias
color darkslateblue
- background url('@/nested/icon.png') 10px no-repeat
+ background url('=/nested/icon.png') 10px no-repeat
diff --git a/playground/css/sass.scss b/playground/css/sass.scss
index 1db47622b016ad..721e6b9bfbca6c 100644
--- a/playground/css/sass.scss
+++ b/playground/css/sass.scss
@@ -1,9 +1,9 @@
-@import '@/nested'; // alias + custom index resolving -> /nested/_index.scss
-@import '@/nested/partial'; // sass convention: omitting leading _ for partials
+@import '=/nested'; // alias + custom index resolving -> /nested/_index.scss
+@import '=/nested/partial'; // sass convention: omitting leading _ for partials
@import 'css-dep'; // package w/ sass entry points
@import 'virtual-dep'; // virtual file added through importer
-@import '@/pkg-dep'; // package w/out sass field
-@import '@/weapp.wxss'; // wxss file
+@import '=/pkg-dep'; // package w/out sass field
+@import '=/weapp.wxss'; // wxss file
.sass {
/* injected via vite.config.js */
diff --git a/playground/css/sugarss.sss b/playground/css/sugarss.sss
index cd393b10519041..80cfc3861b9417 100644
--- a/playground/css/sugarss.sss
+++ b/playground/css/sugarss.sss
@@ -1,4 +1,4 @@
-@import '@/nested/nested.sss'
+@import '=/nested/nested.sss'
.sugarss
color: blue
diff --git a/playground/css/vite.config.js b/playground/css/vite.config.js
index 221c2a75187f35..40ca1a186e58da 100644
--- a/playground/css/vite.config.js
+++ b/playground/css/vite.config.js
@@ -14,7 +14,7 @@ module.exports = {
},
resolve: {
alias: {
- '@': __dirname,
+ '=': __dirname,
spacefolder: __dirname + '/folder with space',
'#alias': __dirname + '/aliased/foo.css',
'#alias-module': __dirname + '/aliased/bar.module.css'
From ef8d9b86c79f2e8594424b0796f50a9790076f95 Mon Sep 17 00:00:00 2001
From: sapphi-red
Date: Mon, 31 Oct 2022 23:06:19 +0900
Subject: [PATCH 5/5] test: add test
---
playground/css/__tests__/css.spec.ts | 9 +++++++++
playground/css/index.html | 2 ++
playground/css/nested/_index.scss | 6 ++++++
playground/css/nested/nested.less | 6 ++++++
4 files changed, 23 insertions(+)
diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts
index 833063f61c7497..e2f41d893021c3 100644
--- a/playground/css/__tests__/css.spec.ts
+++ b/playground/css/__tests__/css.spec.ts
@@ -10,6 +10,7 @@ import {
removeFile,
serverLogs,
untilUpdated,
+ viteTestUrl,
withRetry
} from '~utils'
@@ -78,6 +79,7 @@ test('sass', async () => {
const imported = await page.$('.sass')
const atImport = await page.$('.sass-at-import')
const atImportAlias = await page.$('.sass-at-import-alias')
+ const urlStartsWithVariable = await page.$('.sass-url-starts-with-variable')
const partialImport = await page.$('.sass-partial')
expect(await getColor(imported)).toBe('orange')
@@ -87,6 +89,9 @@ test('sass', async () => {
expect(await getBg(atImportAlias)).toMatch(
isBuild ? /base64/ : '/nested/icon.png'
)
+ expect(await getBg(urlStartsWithVariable)).toMatch(
+ isBuild ? /ok\.\w+\.png/ : `${viteTestUrl}/ok.png`
+ )
expect(await getColor(partialImport)).toBe('orchid')
editFile('sass.scss', (code) =>
@@ -109,6 +114,7 @@ test('less', async () => {
const imported = await page.$('.less')
const atImport = await page.$('.less-at-import')
const atImportAlias = await page.$('.less-at-import-alias')
+ const urlStartsWithVariable = await page.$('.less-url-starts-with-variable')
expect(await getColor(imported)).toBe('blue')
expect(await getColor(atImport)).toBe('darkslateblue')
@@ -117,6 +123,9 @@ test('less', async () => {
expect(await getBg(atImportAlias)).toMatch(
isBuild ? /base64/ : '/nested/icon.png'
)
+ expect(await getBg(urlStartsWithVariable)).toMatch(
+ isBuild ? /ok\.\w+\.png/ : `${viteTestUrl}/ok.png`
+ )
editFile('less.less', (code) => code.replace('@color: blue', '@color: red'))
await untilUpdated(() => getColor(imported), 'red')
diff --git a/playground/css/index.html b/playground/css/index.html
index 799cfebf7adbe3..93f77dfa2eb970 100644
--- a/playground/css/index.html
+++ b/playground/css/index.html
@@ -32,6 +32,7 @@ CSS
contains alias
@import from SASS _partial: This should be orchid
+ url starts with variable
Imported SASS string:
@@ -46,6 +47,7 @@
CSS
@import from Less: This should be darkslateblue and have bg image which url
contains alias
+ url starts with variable
Imported Less string:
diff --git a/playground/css/nested/_index.scss b/playground/css/nested/_index.scss
index 192e9de3b0e203..fee2eb88b168f2 100644
--- a/playground/css/nested/_index.scss
+++ b/playground/css/nested/_index.scss
@@ -9,3 +9,9 @@
color: olive;
background: url(=/nested/icon.png) 10px no-repeat;
}
+
+$var: '/ok.png';
+.sass-url-starts-with-variable {
+ background: url($var);
+ background-position: center;
+}
diff --git a/playground/css/nested/nested.less b/playground/css/nested/nested.less
index f5a40a69d88839..25aa1944d32c14 100644
--- a/playground/css/nested/nested.less
+++ b/playground/css/nested/nested.less
@@ -7,3 +7,9 @@
color: darkslateblue;
background: url(=/nested/icon.png) 10px no-repeat;
}
+
+@var: '/ok.png';
+.less-url-starts-with-variable {
+ background: url('@{var}');
+ background-position: center;
+}