Skip to content

Commit c773dcd

Browse files
author
Tony Sullivan
authored
Exclude any ?raw or ?url css imports when adding asset links (#3020)
* exclude any ?raw css imports when adding css asset links * ?url imports should be ignored as well * chore: adding changeset
1 parent c757427 commit c773dcd

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

.changeset/dull-bobcats-clean.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Add support for advanced CSS imports with `?raw` and `?url`
6+
7+
> ⚠️WARNING⚠️:
8+
> Be careful when bypassing Astro's built-in CSS bundling! Styles won't be included in the built output - this is best used in combination with `set:html` to inline styles directly into the built HTML page.

packages/astro/src/vite-plugin-build-css/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ function isPageStyleVirtualModule(id: string) {
4747
return id.startsWith(ASTRO_PAGE_STYLE_PREFIX);
4848
}
4949

50+
function isRawOrUrlModule(id: string) {
51+
return id.match(/(\?|\&)([^=]+)(raw|url)/gm)
52+
}
53+
5054
interface PluginOptions {
5155
internals: BuildInternals;
5256
legacy: boolean;
@@ -69,7 +73,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin {
6973
const info = ctx.getModuleInfo(id);
7074
if (info) {
7175
for (const importedId of info.importedIds) {
72-
if (!seen.has(importedId)) {
76+
if (!seen.has(importedId) && !isRawOrUrlModule(importedId)) {
7377
yield* walkStyles(ctx, importedId, seen);
7478
}
7579
}

packages/astro/test/astro-css-bundling-import.test.js

+28
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,32 @@ describe('CSS Bundling (ESM import)', () => {
4848
}
4949
}
5050
});
51+
52+
it('?raw and ?url CSS imports are ignored', async () => {
53+
// note: this test is a little confusing as well, but the main idea is that
54+
// page-3.astro should have site.css imported as an ESM in InlineLayout.astro
55+
// as well as the styles from page-3.css as an inline <style>.
56+
const html = await fixture.readFile('/page-3/index.html');
57+
const $ = cheerio.load(html);
58+
59+
let css = '';
60+
61+
for (const style of $('link[rel=stylesheet]')) {
62+
const href = style.attribs.href.replace(/^\.\./, '');
63+
if (!href) continue;
64+
css += await fixture.readFile(href);
65+
}
66+
67+
// test 1: insure green is included (site.css)
68+
expect(css.indexOf('p{color:red}')).to.be.greaterThanOrEqual(0);
69+
70+
// test 2: insure purple is not included as an import (page-3.css)
71+
// this makes sure the styles imported with ?raw and ?url weren't bundled
72+
expect(css.indexOf('p{color:purple}')).to.be.lessThan(0);
73+
74+
// test 3: insure purple was inlined (page-3.css inlined with set:html)
75+
// this makes sure the styles imported with ?url were inlined
76+
let inlineCss = $('style').html().replace(/\s/g, '').replace('/n', '');
77+
expect(inlineCss.indexOf('p{color:purple;}')).to.be.greaterThanOrEqual(0);
78+
})
5179
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
import "../styles/site.css"
3+
4+
const {title} = Astro.props;
5+
---
6+
7+
<html lang="en">
8+
9+
<head>
10+
<meta charset="utf-8" />
11+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
12+
<meta name="viewport" content="width=device-width" />
13+
<title>{title}</title>
14+
</head>
15+
16+
<body>
17+
<ul>
18+
<li><a href="/page-1">Page 1</a></li>
19+
<li><a href="/page-2">Page 2</a></li>
20+
<li><a href="/page-3">Page 3</a></li>
21+
<!-- <li><a href="/page-2-reduced-layout">Page 2 reduced layout</a></li> -->
22+
</ul>
23+
<main id="page">
24+
<slot></slot>
25+
</main>
26+
</body>
27+
28+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
import PageLayout from "../layouts/InlineLayout.astro"
3+
import styles from "../styles/page-three.css?raw"
4+
import stylesUrl from "../styles/page-one.css?url"
5+
---
6+
7+
<PageLayout title="Page 3">
8+
<style set:html={styles}></style>
9+
10+
<h1>Page 3</h1>
11+
<p>This text should be purple, because we want the inlined <code>page-3.css</code> to override <code>site.css</code></p>
12+
</PageLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
p {
2+
color: purple;
3+
}

0 commit comments

Comments
 (0)