summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2022-05-31 11:40:34 -0400
committerGravatar GitHub <noreply@github.com> 2022-05-31 11:40:34 -0400
commitefccebb9643f927d88e6b6f592e53c7c95e7c2b6 (patch)
tree0d85872e1cfe95d7fda64e3965d9d6d1b68f0c9c
parent55820fa784d6d4f66a45092321a47c8ce9de5546 (diff)
downloadastro-efccebb9643f927d88e6b6f592e53c7c95e7c2b6.tar.gz
astro-efccebb9643f927d88e6b6f592e53c7c95e7c2b6.tar.zst
astro-efccebb9643f927d88e6b6f592e53c7c95e7c2b6.zip
Set the correct content-type for CSS HMR (#3459)
* Set the correct content-type for CSS HMR * Adds a changeset
-rw-r--r--.changeset/fifty-mice-bow.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/index.ts28
-rw-r--r--packages/astro/test/fixtures/hmr-css/src/pages/index.astro11
-rw-r--r--packages/astro/test/hmr-css.test.js29
4 files changed, 73 insertions, 0 deletions
diff --git a/.changeset/fifty-mice-bow.md b/.changeset/fifty-mice-bow.md
new file mode 100644
index 000000000..b36bc3b64
--- /dev/null
+++ b/.changeset/fifty-mice-bow.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Forces the correct mime type for CSS in HMR
diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts
index f71e28ba0..ba5b54813 100644
--- a/packages/astro/src/vite-plugin-astro-server/index.ts
+++ b/packages/astro/src/vite-plugin-astro-server/index.ts
@@ -335,6 +335,31 @@ async function handleRequest(
}
}
+/**
+ * Vite HMR sends requests for new CSS and those get returned as JS, but we want it to be CSS
+ * since they are inside of a link tag for Astro.
+ */
+const forceTextCSSForStylesMiddleware: vite.Connect.NextHandleFunction = function(req, res, next) {
+ if(req.url) {
+ // We are just using this to parse the URL to get the search params object
+ // so the second arg here doesn't matter
+ const url = new URL(req.url, 'https://astro.build');
+ // lang.css is a search param that exists on Astro, Svelte, and Vue components.
+ // We only want to override for astro files.
+ if(url.searchParams.has('astro') && url.searchParams.has('lang.css')) {
+ // Override setHeader so we can set the correct content-type for this request.
+ const setHeader = res.setHeader;
+ res.setHeader = function(key, value) {
+ if(key.toLowerCase() === 'content-type') {
+ return setHeader.call(this, key, 'text/css');
+ }
+ return setHeader.apply(this, [key, value]);
+ };
+ }
+ }
+ next();
+};
+
export default function createPlugin({ config, logging }: AstroPluginOptions): vite.Plugin {
return {
name: 'astro:server',
@@ -354,6 +379,9 @@ export default function createPlugin({ config, logging }: AstroPluginOptions): v
viteServer.watcher.on('change', rebuildManifest.bind(null, false));
return () => {
removeViteHttpMiddleware(viteServer.middlewares);
+
+ // Push this middleware to the front of the stack so that it can intercept responses.
+ viteServer.middlewares.stack.unshift({ route: '', handle: forceTextCSSForStylesMiddleware });
viteServer.middlewares.use(async (req, res) => {
if (!req.url || !req.method) {
throw new Error('Incomplete request');
diff --git a/packages/astro/test/fixtures/hmr-css/src/pages/index.astro b/packages/astro/test/fixtures/hmr-css/src/pages/index.astro
new file mode 100644
index 000000000..840e60e01
--- /dev/null
+++ b/packages/astro/test/fixtures/hmr-css/src/pages/index.astro
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <title>Testing</title>
+ <style>
+ background { background: brown; }
+ </style>
+ </head>
+ <body>
+ <h1>Testing</h1>
+ </body>
+</html>
diff --git a/packages/astro/test/hmr-css.test.js b/packages/astro/test/hmr-css.test.js
new file mode 100644
index 000000000..2705d8fd1
--- /dev/null
+++ b/packages/astro/test/hmr-css.test.js
@@ -0,0 +1,29 @@
+import { isWindows, loadFixture } from './test-utils.js';
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+
+describe('HMR - CSS', () => {
+ if (isWindows) return;
+
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+ /** @type {import('./test-utils').DevServer} */
+ let devServer;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/hmr-css/',
+ });
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('Timestamp URL used by Vite gets the right mime type', async () => {
+ let res = await fixture.fetch('/src/pages/index.astro?astro=&type=style&index=0&lang.css=&t=1653657441095');
+ let headers = res.headers;
+ expect(headers.get('content-type')).to.equal('text/css');
+ });
+});