From afc4eb9311fa01ac308f45fce1ad73e9c8f3f7c0 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:54:41 +0900 Subject: [PATCH] fix(css): root relative import in sass modern API on Windows --- packages/vite/src/node/plugins/css.ts | 10 ++++++++-- playground/css/__tests__/css.spec.ts | 1 + playground/css/index.html | 3 +++ playground/css/nested/_index.scss | 1 + playground/css/nested/root-relative.scss | 3 +++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 playground/css/nested/root-relative.scss diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 04c0f87982fa2e..3453cadf1d2332 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -82,7 +82,7 @@ import { urlRE, } from '../utils' import type { Logger } from '../logger' -import { cleanUrl, slash } from '../../shared/utils' +import { cleanUrl, isWindows, slash } from '../../shared/utils' import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' import { PartialEnvironment } from '../baseEnvironment' @@ -1162,8 +1162,14 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers { preferRelative: true, }) sassResolve = async (...args) => { + // the modern API calls `canonicalize` with resolved file URLs + // for relative URLs before raw specifiers if (args[1].startsWith('file://')) { - args[1] = fileURLToPath(args[1]) + args[1] = fileURLToPath(args[1], { + windows: + // file:///foo cannot be converted to path with windows mode + isWindows && args[1].startsWith('file:///') ? false : undefined, + }) } return resolver(...args) } diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts index 553a1c70331793..f0ff63c6b5dbb5 100644 --- a/playground/css/__tests__/css.spec.ts +++ b/playground/css/__tests__/css.spec.ts @@ -101,6 +101,7 @@ test('sass', async () => { expect(await getColor(partialImport)).toBe('orchid') expect(await getColor(await page.$('.sass-file-absolute'))).toBe('orange') expect(await getColor(await page.$('.sass-dir-index'))).toBe('orange') + expect(await getColor(await page.$('.sass-root-relative'))).toBe('orange') if (isBuild) return diff --git a/playground/css/index.html b/playground/css/index.html index 45525412570992..9918757eb1bee6 100644 --- a/playground/css/index.html +++ b/playground/css/index.html @@ -43,6 +43,9 @@

CSS

@import "file:///xxx/absolute-path.scss" should be orange

@import "./dir" should be orange

+

+ @import "/nested/root-relative.scss" should be orange +

Less: This should be blue

diff --git a/playground/css/nested/_index.scss b/playground/css/nested/_index.scss index 72e6b14268334e..ff81e7d82351b9 100644 --- a/playground/css/nested/_index.scss +++ b/playground/css/nested/_index.scss @@ -1,4 +1,5 @@ @use 'sass:string'; +@use '/nested/root-relative'; // root relative path @import './css-in-scss.css'; diff --git a/playground/css/nested/root-relative.scss b/playground/css/nested/root-relative.scss new file mode 100644 index 00000000000000..775dca855743b3 --- /dev/null +++ b/playground/css/nested/root-relative.scss @@ -0,0 +1,3 @@ +.sass-root-relative { + color: orange; +}