Skip to content

Commit

Permalink
Fix CSS modules ordering (#8877)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Oct 23, 2023
1 parent e4ba501 commit 26b77b8
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/silent-goats-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes CSS modules ordering by rendering styles before links
8 changes: 7 additions & 1 deletion packages/astro/src/runtime/server/render/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ export function renderAllHeadContent(result: SSRResult) {
.filter(uniqueElements)
.map((link) => renderElement('link', link, false));

let content = links.join('\n') + styles.join('\n') + scripts.join('\n');
// Order styles -> links -> scripts similar to src/content/runtime.ts
// The order is usually fine as the ordering between these groups are mutually exclusive,
// except for CSS styles and CSS stylesheet links. However CSS stylesheet links usually
// consist of CSS modules which should naturally take precedence over CSS styles, so the
// order will still work. In prod, all CSS are stylesheet links.
// In the future, it may be better to have only an array of head elements to avoid these assumptions.
let content = styles.join('\n') + links.join('\n') + scripts.join('\n');

if (result._metadata.extraHead.length > 0) {
for (const part of result._metadata.extraHead) {
Expand Down
20 changes: 20 additions & 0 deletions packages/astro/test/0-css.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ describe('CSS', function () {
// 2. check CSS
expect(bundledCSS).to.match(new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`));
});

it('.module.css ordering', () => {
const globalStyleClassIndex = bundledCSS.indexOf('.module-ordering');
const moduleStyleClassIndex = bundledCSS.indexOf('._module_ordering');
// css module has higher priority than global style
expect(globalStyleClassIndex).to.be.greaterThan(-1);
expect(moduleStyleClassIndex).to.be.greaterThan(-1);
expect(moduleStyleClassIndex).to.be.greaterThan(globalStyleClassIndex);
});
});

describe('Vue', () => {
Expand Down Expand Up @@ -412,6 +421,17 @@ describe('CSS', function () {
);
});

it('.module.css ordering', () => {
const globalStyleTag = $('style[data-vite-dev-id$="default.css"]');
const moduleStyleTag = $('link[href$="ModuleOrdering.module.css"]');
const globalStyleClassIndex = globalStyleTag.index();
const moduleStyleClassIndex = moduleStyleTag.index();
// css module has higher priority than global style
expect(globalStyleClassIndex).to.be.greaterThan(-1);
expect(moduleStyleClassIndex).to.be.greaterThan(-1);
expect(moduleStyleClassIndex).to.be.greaterThan(globalStyleClassIndex);
});

it('.css?raw return a string', () => {
const el = $('#css-raw');
expect(el.text()).to.equal('.foo {color: red;}');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { module_ordering } from './ModuleOrdering.module.css';

export default function Counter() {
return (
<p className={`module-ordering ${module_ordering}`}>This should be green</p>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.module_ordering {
color: green;
}
4 changes: 4 additions & 0 deletions packages/astro/test/fixtures/0-css/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
import '../styles/default.css'
import AstroComponent from '../components/Astro.astro';
import AstroComponentNone from '../components/AstroNone.astro';
import AstroSass from '../components/AstroSass.astro';
Expand All @@ -19,6 +21,7 @@ import VueScoped from '../components/VueScoped.vue';
import VueScss from '../components/VueScss.vue';
import ReactDynamic from '../components/ReactDynamic.jsx';
import SvelteDynamic from '../components/SvelteDynamic.svelte';
import ModuleOrdering from '../components/ModuleOrdering.jsx';
import '../styles/imported-url.css';
import '../styles/imported.sass';
Expand Down Expand Up @@ -76,6 +79,7 @@ import raw from '../styles/raw.css?raw'
<ReactDynamic client:load />
<SvelteDynamic client:load />
<pre id="css-raw">{raw}</pre>
<ModuleOrdering />
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions packages/astro/test/fixtures/0-css/src/styles/default.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.module-ordering {
color: red;
}

0 comments on commit 26b77b8

Please sign in to comment.