Control CSS imports order for Next.js & webpack based production applications

Author Sagi Liba
Sagi Liba on Jul 18, 2020
4 min 🕐

Solving mini-css-extract-plugin conflicting order warning

While working on a web application at work ( React + Next.js ) I’ve encountered the following warning while running a build of the application:

THE WARNING I'VE ENCOUNTERED:

Copy
Compiled with warnings
chunk styles [mini-css-extract-plugin]
Conflicting order between:
* css ./node_modules/css-loader??ref--6-1!./node-modules/sass-loader/lib/loader.js??ref--6-2!./src/UI/containers/Gifts/SendGifts.scss
* css ./node_modules/css-loader??ref--6-1!./node-modules/sass-loader/lib/loader.js??ref--6-2!./src/UI/components/Share/ShareFlag.component.scss

At first we decided to ignore the warning because it seemed like it did not affect our application but one of the developers noticed that there are parts of the css that was changing its order when switching from development mode to production mode.

Development CSS with correct order of classes:

Correct CSS Order

Production build CSS with incorrect order of classes:

Correct CSS Order

Now the warning itself doesn’t say much about how to fix the problem or where it actually occurs , it only shows the files that are associated with the problem, so I’ve started commenting out code sections where i suspected it occurs until I’ve found the component that causes the warning.

I should note that one of the weird parts of debugging the issue was that while i was commenting code sections and rebuilding the project each time so that i could see the change of the CSS classes in production, I was commenting code from a component that was unmounted and i actually saw the CSS changes order after production build. (I didn’t understand at the time that the problem was strictly build related)

Now while looking at the components code and .scss file I could not find any issues that could cause the CSS to change from development to production.

The CSS for this file was encapsulated / scoped in its own class so its CSS style won’t change/override another component’s style and the class component itself while commenting out its content still affected the other css file.

Copy
import React from 'react';
interface IProps {}
interface IState {}
export default class ScopedCSSComponent extends React.Component<IProps,IState> {
public render(){
return {
<div className='scope-container'>
<div className='class-one'> Info </div>
<div className='class-two'> Info </div>
</div>
};
}
}
Copy
// Any classes contained inside this container
// won't affect any other components style in the application
// as long as .scope-container is a unique class name.
.scope-container {
.class-one {
...
}
.class-two {
...
}
}

Now to understand the issue we must first understand how Next.js builds its application. If you’re new to the framework then you might think that while building the project it creates a single bundle with all the files as a regular application that uses webpack would, but instead Next.js builds each page of the application separately with its own imports and CSS files.

Every page is being built separately so we get the warning because for every page there is a different order of importing the components, so in one page we imported X.scss before Y.scss and for another page we imported Y.scss before X.scss so the mini-css-extract-plugin doesn’t know in which order it should bundle those pages CSS.

Now I’ve tried setting the order of the imports alphabetically for the components involved in the warning to be the same for the entire project but it still didn’t work, so i had to introduce a certain order to the CSS file imports that will not change throughout the build process.

The solution i came to was creating a single index.scss file that will hold all of the css files imports for the entire project and will be imported at _app.js so it will be used once for the entire application.

The index.scss imports components.scss and containers.scss so it will be easier to read instead of having one file with all your projects imports.

index.scss:

Copy
@import "./components/components.scss";
@import "./containers/containers.scss";
Copy
@import "./FirstComponent/FirstComponent.component.scss";
@import "./SecondComponent/SecondComponent.component.scss";
@import "./ThirdComponent/ThirdComponent.component.scss";

By creating this file we introduced our own order to the .scss imports and when Next.js builds the project it calls all the .scss files at once and the order will stay the same, therefore the problem is solved and the warning will go away.

One downside to this approach will be the loss of css chunking because we import all the css at the start of the application. Depending on your project and if you compress your files you should decide whether to use this or not.

For this current project at work it didn’t make a big difference because the size of the css files was already pretty small, so loading them at once did not affect the project noticeably.

We also compress our files with gzip compression so the size difference was not an issue.

If you’ve encountered the same problem for non Next.js applications, using encapsulation for each component’s CSS should solve the problem for you and you can ignore the warning if it continues. Even though the order is different, each components style is unique to that component and will not interfere with other components css, and while using non Next.js applications the build process using webpack will create a single bundle, so there will be no overrides to the css.

© 2020-present Sagi Liba. All Rights Reserved