diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 848fb84fbf1cd1..e447a486fc39b7 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -1085,17 +1085,27 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers { }, get sass() { - return ( - sassResolve || - (sassResolve = config.createResolver({ + if (!sassResolve) { + const resolver = config.createResolver({ extensions: ['.scss', '.sass', '.css'], mainFields: ['sass', 'style'], conditions: ['sass', 'style'], tryIndex: true, tryPrefix: '_', preferRelative: true, - })) - ) + }) + sassResolve = async (...args) => { + const id = args[0] + if (id.startsWith('file://')) { + const fileUrl = new URL(id) + if (fs.existsSync(fileUrl)) { + return fileURLToPath(fileUrl) + } + } + return resolver(...args) + } + } + return sassResolve }, get less() { diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts index cb7af939bbd152..14894bf11e4228 100644 --- a/playground/css/__tests__/css.spec.ts +++ b/playground/css/__tests__/css.spec.ts @@ -93,6 +93,7 @@ test('sass', async () => { isBuild ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`, ) expect(await getColor(partialImport)).toBe('orchid') + expect(await getColor(await page.$('.sass-file-absolute'))).toBe('orange') editFile('sass.scss', (code) => code.replace('color: $injectedColor', 'color: red'), diff --git a/playground/css/file-absolute.scss b/playground/css/file-absolute.scss new file mode 100644 index 00000000000000..508930e3678f6e --- /dev/null +++ b/playground/css/file-absolute.scss @@ -0,0 +1,3 @@ +.sass-file-absolute { + color: orange; +} diff --git a/playground/css/index.html b/playground/css/index.html index a0e92b205e79f6..396ffc02fd3d27 100644 --- a/playground/css/index.html +++ b/playground/css/index.html @@ -41,6 +41,9 @@

CSS

@import dependency w/ no scss entrypoint: this should be lavender

+

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

Less: This should be blue

diff --git a/playground/css/sass.scss b/playground/css/sass.scss index f2f9e685630597..44beb140e3fe3a 100644 --- a/playground/css/sass.scss +++ b/playground/css/sass.scss @@ -6,6 +6,7 @@ @import 'virtual-dep'; // virtual file added through importer @import '=/pkg-dep'; // package w/out sass field @import '=/weapp.wxss'; // wxss file +@import 'virtual-file-absolute'; .sass { /* injected via vite.config.js */ diff --git a/playground/css/vite.config-sass-modern-compiler.js b/playground/css/vite.config-sass-modern-compiler.js index 9759d58506f597..009da79192ec34 100644 --- a/playground/css/vite.config-sass-modern-compiler.js +++ b/playground/css/vite.config-sass-modern-compiler.js @@ -1,5 +1,6 @@ import { defineConfig } from 'vite' import baseConfig from './vite.config.js' +import configSassModern from './vite.config-sass-modern.js' export default defineConfig({ ...baseConfig, @@ -8,23 +9,7 @@ export default defineConfig({ preprocessorOptions: { ...baseConfig.css.preprocessorOptions, scss: { - api: 'modern-compiler', - additionalData: `$injectedColor: orange;`, - importers: [ - { - canonicalize(url) { - return url === 'virtual-dep' - ? new URL('custom-importer:virtual-dep') - : null - }, - load() { - return { - contents: ``, - syntax: 'scss', - } - }, - }, - ], + ...configSassModern.css.preprocessorOptions.scss, }, }, }, diff --git a/playground/css/vite.config-sass-modern.js b/playground/css/vite.config-sass-modern.js index 9f7acb3a098179..f83c2efb366f24 100644 --- a/playground/css/vite.config-sass-modern.js +++ b/playground/css/vite.config-sass-modern.js @@ -1,3 +1,5 @@ +import { pathToFileURL } from 'node:url' +import path from 'node:path' import { defineConfig } from 'vite' import baseConfig from './vite.config.js' @@ -24,6 +26,19 @@ export default defineConfig({ } }, }, + { + canonicalize(url) { + return url === 'virtual-file-absolute' + ? new URL('custom-importer:virtual-file-absolute') + : null + }, + load() { + return { + contents: `@import "${pathToFileURL(path.join(import.meta.dirname, 'file-absolute.scss')).href}"`, + syntax: 'scss', + } + }, + }, ], }, }, diff --git a/playground/css/vite.config.js b/playground/css/vite.config.js index 5ac9d448a2734a..e2b7411f0a2367 100644 --- a/playground/css/vite.config.js +++ b/playground/css/vite.config.js @@ -1,4 +1,5 @@ import path from 'node:path' +import { pathToFileURL } from 'node:url' import stylus from 'stylus' import { defineConfig } from 'vite' @@ -65,6 +66,13 @@ export default defineConfig({ function (url) { return url === 'virtual-dep' ? { contents: '' } : null }, + function (url) { + return url === 'virtual-file-absolute' + ? { + contents: `@import "${pathToFileURL(path.join(import.meta.dirname, 'file-absolute.scss')).href}"`, + } + : null + }, function (url) { return url.endsWith('.wxss') ? { contents: '' } : null },