Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 28 additions & 19 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2433,23 +2433,31 @@ const makeScssWorker = (
return unquotedUrl.startsWith('#{')
}

const internalImporter: Sass.Importer<'async'> = {
const createInternalImporter = (
isForRelative: boolean,
): Sass.Importer<'async'> => ({
async canonicalize(url, context) {
const importer = context.containingUrl
? fileURLToPath(context.containingUrl)
: options.filename
const resolved = await resolvers.sass(
environment,
url,
cleanScssBugUrl(importer),
)
if (
resolved &&
(resolved.endsWith('.css') ||
resolved.endsWith('.scss') ||
resolved.endsWith('.sass'))
) {
return pathToFileURL(resolved)
if (isForRelative) {
// sass passes resolved paths for importer passed to `importer` option
const resolved = new URL(url, context.containingUrl ?? undefined)
if (fs.existsSync(resolved)) return resolved
} else {
const importer = context.containingUrl
? fileURLToPath(context.containingUrl)
: options.filename
const resolved = await resolvers.sass(
environment,
url,
cleanScssBugUrl(importer),
)
if (
resolved &&
(resolved.endsWith('.css') ||
resolved.endsWith('.scss') ||
resolved.endsWith('.sass'))
) {
return pathToFileURL(resolved)
}
}
return null
},
Expand All @@ -2472,12 +2480,13 @@ const makeScssWorker = (
result.contents ?? (await fsp.readFile(result.file, 'utf-8'))
return { contents, syntax, sourceMapUrl: canonicalUrl }
},
}
})

sassOptions.importers = [
...(sassOptions.importers ?? []),
internalImporter,
createInternalImporter(false),
]
sassOptions.importer ??= internalImporter
sassOptions.importer ??= createInternalImporter(true)

const result = await compiler.compileStringAsync(data, sassOptions)
return {
Expand Down
4 changes: 4 additions & 0 deletions playground/css/__tests__/sass-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const sassTest = () => {
const atImport = await page.$('.sass-at-import')
const atImportAlias = await page.$('.sass-at-import-alias')
const atImportRelative = await page.$('.sass-at-import-relative')
const atImportReplacementAlias = await page.$(
'.sass-at-import-replacement-alias',
)
const urlStartsWithVariable = await page.$('.sass-url-starts-with-variable')
const urlStartsWithVariableInterpolation1 = await page.$(
'.sass-url-starts-with-interpolation1',
Expand Down Expand Up @@ -35,6 +38,7 @@ export const sassTest = () => {
expect(await getBg(atImportRelative)).toMatch(
isBuild ? /base64/ : '/nested/icon.png',
)
expect(await getColor(atImportReplacementAlias)).toBe('olive')
expect(await getBg(urlStartsWithVariable)).toMatch(
isBuild ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
)
Expand Down
3 changes: 3 additions & 0 deletions playground/css/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ <h1>CSS</h1>
<p class="sass-at-import-relative">
@import from SASS relative: This should be olive and have bg image
</p>
<p class="sass-at-import-replacement-alias">
@import with replacement alias from SASS: This should be olive
</p>
<p class="sass-partial">@import from SASS _partial: This should be orchid</p>
<p class="sass-url-starts-with-variable">url starts with variable</p>
<p class="sass-url-starts-with-interpolation1">
Expand Down
3 changes: 3 additions & 0 deletions playground/css/nested/replacement-alias.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.sass-at-import-replacement-alias {
color: olive;
}
1 change: 1 addition & 0 deletions playground/css/sass.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@use '=/weapp.wxss'; // wxss file
@use 'virtual-file-absolute';
@use '=/scss-dir/main.scss'; // "./dir" reference from vite custom importer
@use '=replace/nested/replacement-alias.scss';

.sass {
/* injected via vite.config.js */
Expand Down
21 changes: 14 additions & 7 deletions playground/css/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,20 @@ export default defineConfig({
},
},
resolve: {
alias: {
'=': __dirname,
spacefolder: __dirname + '/folder with space',
'#alias': __dirname + '/aliased/foo.css',
'#alias?inline': __dirname + '/aliased/foo.css?inline',
'#alias-module': __dirname + '/aliased/bar.module.css',
},
alias: [
{ find: '=', replacement: __dirname },
{ find: /=replace\/(.*)/, replacement: `${__dirname}/$1` },
{ find: 'spacefolder', replacement: __dirname + '/folder with space' },
{ find: '#alias', replacement: __dirname + '/aliased/foo.css' },
{
find: '#alias?inline',
replacement: __dirname + '/aliased/foo.css?inline',
},
{
find: '#alias-module',
replacement: __dirname + '/aliased/bar.module.css',
},
],
},
css: {
modules: {
Expand Down