diff options
6 files changed, 84 insertions, 1 deletions
diff --git a/.changeset/dull-bobcats-clean.md b/.changeset/dull-bobcats-clean.md new file mode 100644 index 000000000..28ca881a8 --- /dev/null +++ b/.changeset/dull-bobcats-clean.md @@ -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.
\ No newline at end of file diff --git a/packages/astro/src/vite-plugin-build-css/index.ts b/packages/astro/src/vite-plugin-build-css/index.ts index 686dc3e52..dfbfeaa28 100644 --- a/packages/astro/src/vite-plugin-build-css/index.ts +++ b/packages/astro/src/vite-plugin-build-css/index.ts @@ -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); } } diff --git a/packages/astro/test/astro-css-bundling-import.test.js b/packages/astro/test/astro-css-bundling-import.test.js index 62e996dbd..5bb37dfd4 100644 --- a/packages/astro/test/astro-css-bundling-import.test.js +++ b/packages/astro/test/astro-css-bundling-import.test.js @@ -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); + }) }); diff --git a/packages/astro/test/fixtures/astro-css-bundling-import/src/layouts/InlineLayout.astro b/packages/astro/test/fixtures/astro-css-bundling-import/src/layouts/InlineLayout.astro new file mode 100644 index 000000000..f58d50dfd --- /dev/null +++ b/packages/astro/test/fixtures/astro-css-bundling-import/src/layouts/InlineLayout.astro @@ -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> diff --git a/packages/astro/test/fixtures/astro-css-bundling-import/src/pages/page-3.astro b/packages/astro/test/fixtures/astro-css-bundling-import/src/pages/page-3.astro new file mode 100644 index 000000000..11863b52c --- /dev/null +++ b/packages/astro/test/fixtures/astro-css-bundling-import/src/pages/page-3.astro @@ -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> diff --git a/packages/astro/test/fixtures/astro-css-bundling-import/src/styles/page-three.css b/packages/astro/test/fixtures/astro-css-bundling-import/src/styles/page-three.css new file mode 100644 index 000000000..ab17cb5cf --- /dev/null +++ b/packages/astro/test/fixtures/astro-css-bundling-import/src/styles/page-three.css @@ -0,0 +1,3 @@ +p { + color: purple; +} |