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
This commit is contained in:
Tony Sullivan 2022-04-07 18:26:26 +00:00 committed by GitHub
parent c757427fca
commit c773dcde31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 1 deletions

View file

@ -0,0 +1,8 @@
---
'astro': patch
---
Add support for advanced CSS imports with `?raw` and `?url`
> ⚠WARNING⚠:
> 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.

View file

@ -47,6 +47,10 @@ function isPageStyleVirtualModule(id: string) {
return id.startsWith(ASTRO_PAGE_STYLE_PREFIX);
}
function isRawOrUrlModule(id: string) {
return id.match(/(\?|\&)([^=]+)(raw|url)/gm)
}
interface PluginOptions {
internals: BuildInternals;
legacy: boolean;
@ -69,7 +73,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin {
const info = ctx.getModuleInfo(id);
if (info) {
for (const importedId of info.importedIds) {
if (!seen.has(importedId)) {
if (!seen.has(importedId) && !isRawOrUrlModule(importedId)) {
yield* walkStyles(ctx, importedId, seen);
}
}

View file

@ -48,4 +48,32 @@ describe('CSS Bundling (ESM import)', () => {
}
}
});
it('?raw and ?url CSS imports are ignored', async () => {
// note: this test is a little confusing as well, but the main idea is that
// page-3.astro should have site.css imported as an ESM in InlineLayout.astro
// as well as the styles from page-3.css as an inline <style>.
const html = await fixture.readFile('/page-3/index.html');
const $ = cheerio.load(html);
let css = '';
for (const style of $('link[rel=stylesheet]')) {
const href = style.attribs.href.replace(/^\.\./, '');
if (!href) continue;
css += await fixture.readFile(href);
}
// test 1: insure green is included (site.css)
expect(css.indexOf('p{color:red}')).to.be.greaterThanOrEqual(0);
// test 2: insure purple is not included as an import (page-3.css)
// this makes sure the styles imported with ?raw and ?url weren't bundled
expect(css.indexOf('p{color:purple}')).to.be.lessThan(0);
// test 3: insure purple was inlined (page-3.css inlined with set:html)
// this makes sure the styles imported with ?url were inlined
let inlineCss = $('style').html().replace(/\s/g, '').replace('/n', '');
expect(inlineCss.indexOf('p{color:purple;}')).to.be.greaterThanOrEqual(0);
})
});

View file

@ -0,0 +1,28 @@
---
import "../styles/site.css"
const {title} = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<title>{title}</title>
</head>
<body>
<ul>
<li><a href="/page-1">Page 1</a></li>
<li><a href="/page-2">Page 2</a></li>
<li><a href="/page-3">Page 3</a></li>
<!-- <li><a href="/page-2-reduced-layout">Page 2 reduced layout</a></li> -->
</ul>
<main id="page">
<slot></slot>
</main>
</body>
</html>

View file

@ -0,0 +1,12 @@
---
import PageLayout from "../layouts/InlineLayout.astro"
import styles from "../styles/page-three.css?raw"
import stylesUrl from "../styles/page-one.css?url"
---
<PageLayout title="Page 3">
<style set:html={styles}></style>
<h1>Page 3</h1>
<p>This text should be purple, because we want the inlined <code>page-3.css</code> to override <code>site.css</code></p>
</PageLayout>

View file

@ -0,0 +1,3 @@
p {
color: purple;
}