Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions .changeset/fix-sass-baseurl-resolution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes Sass/SCSS `@use` and `@import` not resolving bare specifiers against `baseUrl` in `tsconfig.json`. Projects using `@use "colors.scss"` with `"baseUrl": "src"` now resolve correctly.
21 changes: 20 additions & 1 deletion packages/astro/src/vite-plugin-config-alias/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const getViteResolveAlias = (settings: AstroSettings) => {
for (const resolvedValue of resolvedValues) {
const resolved = resolvedValue.replace('*', id);
const stats = fs.statSync(resolved, { throwIfNoEntry: false });
if (stats && stats.isFile()) {
if (stats?.isFile()) {
return normalizePath(resolved);
}
}
Expand All @@ -110,6 +110,25 @@ const getViteResolveAlias = (settings: AstroSettings) => {
}
}

// Add baseUrl alias for CSS/Sass bare specifiers (e.g. `@use "colors.scss"`).
// This mirrors the baseUrl handling in getConfigAlias() but is scoped to
// style file extensions to avoid intercepting JS/npm package imports,
// which are handled by the resolveId hook instead.
if (baseUrl) {
aliases.push({
find: /^(?!\.*\/|\.*$|\w:)(.+\.(?:css|scss|sass|less|styl|stylus))$/,
replacement: '$1',
customResolver(id: string) {
const resolved = path.resolve(resolvedBaseUrl, id);
const stats = fs.statSync(resolved, { throwIfNoEntry: false });
if (stats?.isFile()) {
return normalizePath(resolved);
}
return null;
},
});
}

return aliases;
};

Expand Down
14 changes: 14 additions & 0 deletions packages/astro/test/alias-tsconfig.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ describe('Aliases with tsconfig.json', () => {
assert.equal($('#alias').text(), 'foo');
});

it('resolves Sass @use via baseUrl', async () => {
const html = await fixture.fetch('/').then((res) => res.text());
// The Sass variable $accent: green should be applied via baseUrl resolution
assert.ok(html.includes('green'));
});

it('works for import.meta.glob', async () => {
const html = await fixture.fetch('/').then((res) => res.text());
const $ = cheerio.load(html);
Expand Down Expand Up @@ -144,6 +150,14 @@ describe('Aliases with tsconfig.json', () => {
assert.equal($('#alias').text(), 'foo');
});

it('resolves Sass @use via baseUrl', async () => {
const html = await fixture.readFile('/index.html');
const content = await Promise.all(getLinks(html).map((href) => getLinkContent(href)));
const allCss = content.map(({ css }) => css).join('');
// The Sass variable $accent: green should be compiled into the CSS
assert.ok(allCss.includes('green'));
});

it('handles multiple replacements in one alias', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$accent: green;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
---
<p id="sass-baseurl">sass-baseurl</p>

<style lang="scss">
@use "src/colors.scss";

#sass-baseurl {
color: colors.$accent;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Baz from "@short/Baz"
import StyleComp from 'src/components/Style.astro';
import { foo, index } from 'src/utils/constants';
import { doNothing } from '@pages';
import SassBaseUrl from '@components/SassBaseUrl.astro';

const globResult = Object.keys(import.meta.glob('@components/glob/*.js')).join(', ')

Expand Down Expand Up @@ -37,6 +38,7 @@ doNothing()
<p id="style-red">style-red</p>
<p id="style-blue">style-blue</p>
<p id="glob">{globResult}</p>
<SassBaseUrl />
</main>
</body>
</html>
Loading