Minimal reproduction repo (kind of): https://github.com/ferdaber/css-plugin-ordering-bug
Node: v9.11.1
OS: MacOS v10.12.6
With the latest version v0.4.1, in multiple-entry-points situations, I found that the CSS ordering is not deterministic. I set up a repo that "reproduces" the bug to the best of my ability (before getting stuck in Webpack internals).
The gist of it is that in cases where a chunk is shared between multiple chunk groups, it's not always the case that the first chunk group actually has the CSS modules that we want to sort on, which results in this line returning undefined for the module index:
https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/index.js#L393
Chunk groups:
entry-a~vendor: has a.js and shared_modules/other.jsentry-b~vendor: has b.js, shared_modules/red.css and shared_modules/blue.cssIn my repo, I set it up so that anything in shared_modules is split out into a separate chunk, but have the entry points ordered such that the first chunk group contains no CSS modules (entry-a's dependency tree only contains JS files but touches the shared_modules chunk group). This leads to the sorting mechanism as mentioned above to return undefined for a CSS module's index.
The output in this repo still ended up having the correct ordering but I think it was because the chunk.modulesIterable set had the correct ordering at the time:
Output css/vendor.css:
html {
background: blue;
}
html {
background: red;
}
Expected css/vendor.css:
html {
background: red;
}
html {
background: blue;
}
To my understanding, chunk.modulesIterable is generated (or added) asynchronously so the ordering is not always guaranteed?
At this point I got stuck trying to get more information to submit to this issue, if a maintainer could offer me some guidance to what a better chunking strategy would be to work around this, or a fix for this, that would be super appreciated - thanks!
/cc @sokra
@evilebottnawi I can report a similar issue from the v4.0.1 release. This is pretty much the exact same behavior I was seeing when upgrading to Webpack 4 and using the extract-text plugin https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/745
I have a single entrypoint and am using PostCSS Loader with CSS modules. In development without extraction everything works as expected, although in prod when using mini-css-extract I see a regression in order of some classes. Reverting to `0.4.01 fixes the issue.
This seems to be happening in combination with using the
composes: via CSS loaderex. the following css most likely occurs in various files throughout the application resulting in class duplication and changes in order
@import 'config/common.css';
@import 'config/header.css';
.container {
position: relative;
}
.cta-text {
composes: heading-4 from 'helpers/typography.css';
}
This problem is in a large repo and I'm having problems replicating it in a minimal use case but when I do I will post a demo.
In the real life situation:
the order of css is wrong (typography__heading-1 should be the base style, and then overwritten with the Hero__heading)

Resulting from the following CSS when both global.css and Hero.css are extracted together into the same file:
// global.css
@import 'helpers/typography.css';
```css
// Hero.css
.text-headline {
composes: heading-1 from 'helpers/typography.css';
color: var(--color-text);
@media (--large-up) {
width: 100%;
}
}
```js
//main.js
import './global.css';
import Hero from `./Hero'; // where Hero.js imports Hero.css as css-module
This issue is same as https://github.com/webpack-contrib/mini-css-extract-plugin/issues/188
I have also posted a repo that shows the problem at https://github.com/boraturant/MiniCssExtractPlugin_CSSOrderProblem
Ran into this as well. I have another somewhat minimal repro but it is not pretty, as triggering an actual bug with this requires hitting a random case where Array.prototype.sort yields weird behavior given the existence of a stray undefined. Altering file paths, order of imports, etc. can trigger or fix the problem.
https://github.com/smrq/mini-css-extract-plugin-repro
Perhaps order modules by their position in the first chunk group, then any modules not existing in the first chunk group by their position in the second chunk group, etc.?
https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/index.js#L390
- const [chunkGroup] = chunk.groupsIterable;
- if (typeof chunkGroup.getModuleIndex2 === 'function') {
- modules.sort((a, b) => chunkGroup.getModuleIndex2(a) - chunkGroup.getModuleIndex2(b));
- } else {
+ if (typeof chunk.groupsIterable[0].getModuleIndex2 === 'function') {
+ let sortedModules = [];
+ chunk.groupsIterable.forEach(chunkGroup => {
+ sortedModules = sortedModules.concat(
+ modules.filter(m => chunkGroup.getModuleIndex2(m) != null)
+ .sort((a, b) => chunkGroup.getModuleIndex2(a) - chunkGroup.getModuleIndex2(b)));
+ modules = modules.filter(m => chunkGroup.getModuleIndex2(m) == null);
+ });
+ modules = sortedModules;
+ } else {
I have a css ordering issue with multiple entry points broken for both 0.4.1 and 0.4.2
0.4.0 does the right thing
I was thinking about this issue and I think what the user would expect is that the css extractor orders the styles the same way they are done when you run devserver.
So, if there is a common chunk that needs to be ordered differently for two other chunks then I should think that either there needs to be two common chunks output.
The same issue.
Are there any changes? )
If we use style-loader instead of mini-css-extract-plugin then the problem is gone (chunks ordered correctly), but style-loader is not what we need cause it can't extract text :(
Any update on this? :thinking:
Mention maintainer: @sokra
PR welcome
If somebody have other minimum reproducible test repos, feel free to left link here, try to solve issue
@evilebottnawi I'm experiencing same order issue while using Nuxt 2.3.4 which is using mini-extract-css-plugin internally.
Repro link: https://codesandbox.io/s/qqp1wq28yw
Additional screenshot from a real world project:
https://monosnap.com/file/pbTr2qlW2Y5GByq2RoV3y3Mlmytrg4
as you can see app.css is linked twice and the second time it's linked after pages.css that should be last in a list of css linkages.
Correct order:
No duplicates should be present
version 0.5.0 same error. with sideEffects false you get bigger bundle size
I'm seeing this when I turn on tree shaking. Can someone explain why tree shaking impacts compiled CSS order?
FYI I discovered after some time that the issue I had wasn't a problem with mini-css-extract-plugin. I was just calling require in a different order than I had expected.
I got this problem after tree shaking. "sideEffects": [ ".css" ]
Is this still an issue? Are there any ways around it without switching to style-loader?
This is still ongoing. The common chunk ends up loading before the entrypoint specific chunk, but the common chunk has rules that are at the same specificity and meant to supersede entrypoint styles based on order. But right now the common chunk behaviour makes the opposite happen.
I think that I encountered this exact problem. A reproducible example can be found here:
https://github.com/ilicmarko/webpack-chunk-test/issues/1
_Note: This is vue-cli under the hood but it uses mini-css-extract-plugin._
any updates on this?
hm, should be fixed, what is the version?
Fixed in [email protected], all repos above output expected result (tested), please check you have webpack v5 and mini-css-extract-plugin v1.4.0, if you faced with the issue again please open a new issue with reproducible test repo
Most helpful comment
The same issue.
Are there any changes? )