diff --git a/.changeset/curvy-donuts-build.md b/.changeset/curvy-donuts-build.md new file mode 100644 index 000000000..a9a7c44d0 --- /dev/null +++ b/.changeset/curvy-donuts-build.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes SSR CSS ordering to match static mode diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts index e7fbfd995..7e373d0ea 100644 --- a/packages/astro/src/core/build/vite-plugin-ssr.ts +++ b/packages/astro/src/core/build/vite-plugin-ssr.ts @@ -139,7 +139,7 @@ function buildManifest( routes.push({ file: '', - links: Array.from(pageData.css), + links: Array.from(pageData.css).reverse(), scripts: [ ...scripts, ...astroConfig._ctx.scripts diff --git a/packages/astro/test/css-order.test.js b/packages/astro/test/css-order.test.js new file mode 100644 index 000000000..82370af2b --- /dev/null +++ b/packages/astro/test/css-order.test.js @@ -0,0 +1,57 @@ +import { expect } from 'chai'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; +import testAdapter from './test-adapter.js'; + +describe('CSS production ordering', () => { + let staticHTML, serverHTML; + let staticCSS, serverCSS; + + const commonConfig = Object.freeze({ + root: './fixtures/css-order/', + }); + + function getLinks(html) { + let $ = cheerio.load(html); + let out = []; + $('link[rel=stylesheet]').each((i, el) => { + out.push($(el).attr('href')) + }); + return out; + } + + before(async () => { + let fixture = await loadFixture({ ...commonConfig }); + await fixture.build(); + staticHTML = await fixture.readFile('/one/index.html'); + staticCSS = await Promise.all(getLinks(staticHTML).map(async (href) => { + const css = await fixture.readFile(href); + return { href, css }; + })); + }); + + before(async () => { + let fixture = await loadFixture({ + ...commonConfig, + adapter: testAdapter(), + output: 'server', + }); + await fixture.build(); + + const app = await fixture.loadTestAdapterApp(); + const request = new Request('http://example.com/one'); + const response = await app.render(request); + serverHTML = await response.text(); + serverCSS = await Promise.all(getLinks(serverHTML).map(async (href) => { + const css = await fixture.readFile(`/client${href}`); + return { href, css }; + })); + }); + + it('is in the same order for output: server and static', async () => { + const staticContent = staticCSS.map(o => o.css); + const serverContent = serverCSS.map(o => o.css); + + expect(staticContent).to.deep.equal(serverContent); + }); +}); diff --git a/packages/astro/test/fixtures/css-order/package.json b/packages/astro/test/fixtures/css-order/package.json new file mode 100644 index 000000000..cf8074efe --- /dev/null +++ b/packages/astro/test/fixtures/css-order/package.json @@ -0,0 +1,6 @@ +{ + "name": "@test/css-order", + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/css-order/src/components/CommonHead.astro b/packages/astro/test/fixtures/css-order/src/components/CommonHead.astro new file mode 100644 index 000000000..8341c981c --- /dev/null +++ b/packages/astro/test/fixtures/css-order/src/components/CommonHead.astro @@ -0,0 +1,5 @@ + diff --git a/packages/astro/test/fixtures/css-order/src/pages/one.astro b/packages/astro/test/fixtures/css-order/src/pages/one.astro new file mode 100644 index 000000000..6bd665de8 --- /dev/null +++ b/packages/astro/test/fixtures/css-order/src/pages/one.astro @@ -0,0 +1,17 @@ +--- +import CommonHead from '../components/CommonHead.astro'; +--- + +
+