summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/big-rocks-do.md5
-rw-r--r--packages/astro/src/core/build/plugins/plugin-css.ts4
-rw-r--r--packages/astro/src/core/render/dev/css.ts5
-rw-r--r--packages/astro/src/core/render/dev/util.ts9
-rw-r--r--packages/astro/src/core/render/dev/vite.ts6
-rw-r--r--packages/astro/src/core/render/util.ts18
-rw-r--r--packages/astro/test/css-inline.test.js28
-rw-r--r--packages/astro/test/fixtures/css-inline/package.json8
-rw-r--r--packages/astro/test/fixtures/css-inline/src/inline.css3
-rw-r--r--packages/astro/test/fixtures/css-inline/src/layouts/Layout.astro35
-rw-r--r--packages/astro/test/fixtures/css-inline/src/pages/index.astro19
-rw-r--r--packages/astro/test/fixtures/css-inline/src/raw.css3
-rw-r--r--pnpm-lock.yaml6
13 files changed, 123 insertions, 26 deletions
diff --git a/.changeset/big-rocks-do.md b/.changeset/big-rocks-do.md
new file mode 100644
index 000000000..52b8a1e5d
--- /dev/null
+++ b/.changeset/big-rocks-do.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Prevent ?inline and ?raw CSS from being bundled as CSS
diff --git a/packages/astro/src/core/build/plugins/plugin-css.ts b/packages/astro/src/core/build/plugins/plugin-css.ts
index 0d57cfb5e..9873ad889 100644
--- a/packages/astro/src/core/build/plugins/plugin-css.ts
+++ b/packages/astro/src/core/build/plugins/plugin-css.ts
@@ -2,7 +2,7 @@ import * as crypto from 'node:crypto';
import * as npath from 'node:path';
import type { GetModuleInfo } from 'rollup';
import { Plugin as VitePlugin, ResolvedConfig, transformWithEsbuild } from 'vite';
-import { isCSSRequest } from '../../render/util.js';
+import { isBuildableCSSRequest } from '../../render/dev/util.js';
import type { BuildInternals } from '../internal';
import type { AstroBuildPlugin } from '../plugin';
import type { PageBuildData, StaticBuildOptions } from '../types';
@@ -66,7 +66,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
after(id, meta) {
// For CSS, create a hash of all of the pages that use it.
// This causes CSS to be built into shared chunks when used by multiple pages.
- if (isCSSRequest(id)) {
+ if (isBuildableCSSRequest(id)) {
for (const [pageInfo] of walkParentInfos(id, {
getModuleInfo: meta.getModuleInfo,
})) {
diff --git a/packages/astro/src/core/render/dev/css.ts b/packages/astro/src/core/render/dev/css.ts
index 5667f705c..9338c531c 100644
--- a/packages/astro/src/core/render/dev/css.ts
+++ b/packages/astro/src/core/render/dev/css.ts
@@ -3,7 +3,7 @@ import type { ModuleLoader } from '../../module-loader/index';
import path from 'path';
import { RuntimeMode } from '../../../@types/astro.js';
import { viteID } from '../../util.js';
-import { STYLE_EXTENSIONS } from '../util.js';
+import { isCSSRequest } from './util.js';
import { crawlGraph } from './vite.js';
/** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
@@ -16,8 +16,7 @@ export async function getStylesForURL(
const importedStylesMap = new Map<string, string>();
for await (const importedModule of crawlGraph(loader, viteID(filePath), true)) {
- const ext = path.extname(importedModule.url).toLowerCase();
- if (STYLE_EXTENSIONS.has(ext)) {
+ if (isCSSRequest(importedModule.url)) {
let ssrModule: Record<string, any>;
try {
// The SSR module is possibly not loaded. Load it if it's null.
diff --git a/packages/astro/src/core/render/dev/util.ts b/packages/astro/src/core/render/dev/util.ts
new file mode 100644
index 000000000..85bf3dec2
--- /dev/null
+++ b/packages/astro/src/core/render/dev/util.ts
@@ -0,0 +1,9 @@
+import { isCSSRequest } from 'vite';
+
+const rawRE = /(?:\?|&)raw(?:&|$)/;
+const inlineRE = /(?:\?|&)inline\b/;
+
+export { isCSSRequest };
+
+export const isBuildableCSSRequest = (request: string): boolean => isCSSRequest(request) &&
+ !rawRE.test(request) && !inlineRE.test(request);
diff --git a/packages/astro/src/core/render/dev/vite.ts b/packages/astro/src/core/render/dev/vite.ts
index f927966b6..a3f0b6437 100644
--- a/packages/astro/src/core/render/dev/vite.ts
+++ b/packages/astro/src/core/render/dev/vite.ts
@@ -4,7 +4,7 @@ import npath from 'path';
import { PROPAGATED_ASSET_FLAG } from '../../../content/consts.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../constants.js';
import { unwrapId } from '../../util.js';
-import { STYLE_EXTENSIONS } from '../util.js';
+import { isCSSRequest } from './util.js';
/**
* List of file extensions signalling we can (and should) SSR ahead-of-time
@@ -43,7 +43,7 @@ export async function* crawlGraph(
}
if (id === entry.id) {
scanned.add(id);
- const entryIsStyle = STYLE_EXTENSIONS.has(npath.extname(id));
+ const entryIsStyle = isCSSRequest(id);
for (const importedModule of entry.importedModules) {
// some dynamically imported modules are *not* server rendered in time
// to only SSR modules that we can safely transform, we check against
@@ -57,7 +57,7 @@ export async function* crawlGraph(
// Tools like Tailwind might add HMR dependencies as `importedModules`
// but we should skip them--they aren't really imported. Without this,
// every hoisted script in the project is added to every page!
- if (entryIsStyle && !STYLE_EXTENSIONS.has(npath.extname(importedModulePathname))) {
+ if (entryIsStyle && !isCSSRequest(importedModulePathname)) {
continue;
}
if (fileExtensionsToSSR.has(npath.extname(importedModulePathname))) {
diff --git a/packages/astro/src/core/render/util.ts b/packages/astro/src/core/render/util.ts
deleted file mode 100644
index 2dddc49b0..000000000
--- a/packages/astro/src/core/render/util.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// https://vitejs.dev/guide/features.html#css-pre-processors
-export const STYLE_EXTENSIONS = new Set([
- '.css',
- '.pcss',
- '.postcss',
- '.scss',
- '.sass',
- '.styl',
- '.stylus',
- '.less',
-]);
-
-const cssRe = new RegExp(
- `\\.(${Array.from(STYLE_EXTENSIONS)
- .map((s) => s.slice(1))
- .join('|')})($|\\?)`
-);
-export const isCSSRequest = (request: string): boolean => cssRe.test(request);
diff --git a/packages/astro/test/css-inline.test.js b/packages/astro/test/css-inline.test.js
new file mode 100644
index 000000000..01d3133b8
--- /dev/null
+++ b/packages/astro/test/css-inline.test.js
@@ -0,0 +1,28 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Importing raw/inlined CSS', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/css-inline/',
+ });
+ await fixture.build();
+ });
+
+ it('?inline is imported as a string', async () => {
+ const html = await fixture.readFile('/index.html');
+ const $ = cheerio.load(html);
+
+ expect($('#inline').text()).to.contain('tomato');
+ });
+
+ it('?raw is imported as a string', async () => {
+ const html = await fixture.readFile('/index.html');
+ const $ = cheerio.load(html);
+
+ expect($('#raw').text()).to.contain('plum');
+ });
+});
diff --git a/packages/astro/test/fixtures/css-inline/package.json b/packages/astro/test/fixtures/css-inline/package.json
new file mode 100644
index 000000000..5fce13947
--- /dev/null
+++ b/packages/astro/test/fixtures/css-inline/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/css-inline",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/css-inline/src/inline.css b/packages/astro/test/fixtures/css-inline/src/inline.css
new file mode 100644
index 000000000..ea8200bd9
--- /dev/null
+++ b/packages/astro/test/fixtures/css-inline/src/inline.css
@@ -0,0 +1,3 @@
+body {
+ background: tomato;
+}
diff --git a/packages/astro/test/fixtures/css-inline/src/layouts/Layout.astro b/packages/astro/test/fixtures/css-inline/src/layouts/Layout.astro
new file mode 100644
index 000000000..f1a62a537
--- /dev/null
+++ b/packages/astro/test/fixtures/css-inline/src/layouts/Layout.astro
@@ -0,0 +1,35 @@
+---
+export interface Props {
+ title: string;
+}
+
+const { title } = Astro.props;
+---
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ <meta name="generator" content={Astro.generator} />
+ <title>{title}</title>
+ </head>
+ <body>
+ <slot />
+ </body>
+</html>
+<style is:global>
+ :root {
+ --accent: 124, 58, 237;
+ --accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
+ }
+ html {
+ font-family: system-ui, sans-serif;
+ background-color: #F6F6F6;
+ }
+ code {
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+ }
+</style>
diff --git a/packages/astro/test/fixtures/css-inline/src/pages/index.astro b/packages/astro/test/fixtures/css-inline/src/pages/index.astro
new file mode 100644
index 000000000..89a7288ae
--- /dev/null
+++ b/packages/astro/test/fixtures/css-inline/src/pages/index.astro
@@ -0,0 +1,19 @@
+---
+import Layout from '../layouts/Layout.astro';
+import inline from '../inline.css?inline';
+import raw from '../raw.css?raw';
+---
+<Layout title="Welcome to Astro.">
+ <main>
+ <h1>Welcome to Astro</h1>
+ <p>
+ This are some `?inline` styles to show as object:
+ </p>
+ <p id="inline">
+ {inline}
+ </p>
+ <p id="raw">
+ {raw}
+ </p>
+ </main>
+</Layout>
diff --git a/packages/astro/test/fixtures/css-inline/src/raw.css b/packages/astro/test/fixtures/css-inline/src/raw.css
new file mode 100644
index 000000000..916081876
--- /dev/null
+++ b/packages/astro/test/fixtures/css-inline/src/raw.css
@@ -0,0 +1,3 @@
+main {
+ background: plum;
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fb87e5f42..7577d37e1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1690,6 +1690,12 @@ importers:
packages/astro/test/fixtures/css-assets/packages/font-awesome:
specifiers: {}
+ packages/astro/test/fixtures/css-inline:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/css-no-code-split:
specifiers:
astro: workspace:*