facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.51k stars 26.78k forks source link

mini-css-extract-plugin throws "Conflicting order" errors during build #5372

Open dviry opened 5 years ago

dviry commented 5 years ago

(react-scripts 2.0.4) Same as in this issue I am getting a lot of errors from the mini-css-extract-plugin when doing a CI build - which fails since no warnings are allowed. Since CRA does not allow customizing the WebPack plugin config, I cannot use the warningsFilters and the question about CRA also already popped up.

I am not sure what the CRA team can do about this - but maybe just keep an eye on it (or have it documented as a Known Issue) until WebPack somehow solves it.

PS: for now I am running "set CI=&&react-scripts build" to disable the CI build warnings limit.

andriijas commented 5 years ago

Are you using 3rd party styling library like antd, bootstrap or anything else?

Like mentioned in the related issue https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250#issuecomment-415345126 the problem should not just be ignored by disabling and hiding the warnings but addressing the source cause instead, its not healthy to have fragile and inconsistent builds.

holloway commented 5 years ago

@dviry fyi I solved this by importing all CSS from a single file, and for code-split styles I'll migrate to a CSS-in-JS approach (probably Glamor styled-components).

Timer commented 5 years ago

Yeah, this is a very valid problem. A light change in your code could alter the cascading effects of your CSS, so this is warranted. Maybe some docs on how to fix it would be nice.

ryancogswell commented 5 years ago

@Timer This seems like more than a documentation problem. I'm working on un-ejecting, but couldn't before 2.0 because of using Sass and CSS modules. Now with 2.0, I'm getting a bunch of these warnings, but we are using CSS modules for everything so there's no chance of the order actually being important (we aren't using any global styles -- just CSS classes).

ryancogswell commented 5 years ago

In our case, I've worked around this by importing within index.js the components that directly use the CSS files that the warnings were complaining about. This resolves the order ambiguity and in my case, the components are shared pieces that are fine to be in my "main" chunk.

bogdan-calapod commented 5 years ago

I also have this problem, and the error message is utterly useless and frustrating. On a large project it isn't feasible to randomly start requiring the devs to update their CSS based on arbitrary rules.

I'm using this with SCSS, and I'm even more confused on what it wants from me. The linked issue doesn't help much either.

stereobooster commented 5 years ago
chunk 0 [mini-css-extract-plugin]
Conflicting order between:
 * css ./node_modules/css-loader??ref--6-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/form.module.css
 * css ./node_modules/css-loader??ref--6-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/components/Footer/Footer.module.css

We use CSS Modules. The problem is in our code, but it is hard to understand what exactly is the issue. It complains about order of css imports in asset graph, but which exactly files?

Related https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250

theZieger commented 5 years ago

I also had an issue with the mini-css-extract-plugin warning about a confliction order. Good thing was I'm in complete control of the component library we are using. But finding the correct spot where the problem occurs was really tough. I'm not an expert regarding webpack and neither the mini-css-extract-plugin or any of this. That's why I use CRA in the first place - I don't want to deal in detail with webpack and it's plugin ecosystem.

Nonetheless I was able to fix my component library. I'll just leave this here, so it may be some help to others hopefully.

Before the change:

BaseButton.js

import React from 'react';
import classnames from '../../../classnames';

import '../../../global/Global.css';
import './BaseButton.css';

export default function BaseButton({ children, type, className, ...other }) {
  return (
    <button
      className={classnames('base-button', className)}
      type={type}
      {...other}
    >
      {children}
    </button>
  );
}
BaseButton.defaultProps = {
  /** the type of the button */
  type: 'button'
};

IconButton.js

import React from 'react';

import BaseButton from '../BaseButton/BaseButton';
import classnames from '../../../classnames';

import '../../../global/Global.css';
import './IconButton.css';

export default function IconButton({ className, ...props }) {
  return (
    <BaseButton className={classnames('icon-button', className)} {...props} />
  );
}

When I used the components in that way, the CSS generated on build was not in the order I suspected it to be. When looking at the code of IconButton.js I would assume that the build process would put BaseButton.css before IconButton.css. But in fact it was in the wrong order ... this led to wrongly applied CSS rules (because cascading). And yeah maybe I should move on to use CSS Modules.

Anyway her my solution - even though I can't explain why this works now:

BaseButton.js

import React from 'react';
import classnames from '../../../classnames';

export default function BaseButton({ children, type, className, ...other }) {
  return (
    <button
      className={classnames('base-button', className)}
      type={type}
      {...other}
    >
      {children}
    </button>
  );
}
BaseButton.defaultProps = {
  /** the type of the button */
  type: 'button'
};

IconButton.js

import React from 'react';

import BaseButton from '../BaseButton/BaseButton';
import classnames from '../../../classnames';

import '../../../global/Global.css';
import '../BaseButton/BaseButton.css';
import './IconButton.css';

export default function IconButton({ className, ...props }) {
  return (
    <BaseButton className={classnames('icon-button', className)} {...props} />
  );
}

Maybe one of you can explain this to me or maybe this even helps you finding a similiar solution on your projects. Just wanted to share ... and this is the first issue I found regarding CRA and mini-css-extract-plugin.

gonzofish commented 5 years ago

@theZieger what's in Global.css?

theZieger commented 5 years ago

@gonzofish some normalize styles but mostly custom properties (CSS variables)

gonzofish commented 5 years ago

I'm wondering if importing them over and over is causing a headache? I can't get mine to stop spitting out errors either

theZieger commented 5 years ago

In my case it doesn't seem to be a problem importing Global.css over and over again in multiple components. And btw I don't get any warnings anymore after I applied the above changes I posted... But still discover smaller issues regarding the final output order.

gonzofish commented 5 years ago

In my case, I had to reorder my imports, but it's not clear why:

I went from:

import AudienceComposition from '../../../shared/components/AudienceComposition/AudienceComposition';
import MetricPicker from '../../../shared/components/Bb8MetricPicker/Bb8MetricPicker';
import BulmaMessage from '../../../shared/components/BulmaMessage/BulmaMessage';
import EntityCard from '../../../shared/containers/Bb8EntityCard/Bb8EntityCard';
import EntitySearch from '../../../shared/containers/EntitySearch/EntitySearch';

to

import MetricPicker from '../../../shared/components/Bb8MetricPicker/Bb8MetricPicker';
import BulmaMessage from '../../../shared/components/BulmaMessage/BulmaMessage';
import EntityCard from '../../../shared/containers/Bb8EntityCard/Bb8EntityCard';
import EntitySearch from '../../../shared/containers/EntitySearch/EntitySearch';
import AudienceComposition from '../../../shared/components/AudienceComposition/AudienceComposition';

Even as I look at the imports of SASS files from each of those files (and anything they import), I can't figure out what was causing problems. Because a SASS file that was used by a component AudienceComposition imported was causing conflicts with all of the other SASS files from MetricPicker, BulmaMEssage, EntityCard, and EntitySearch...even when I had removed all code from the SASS file...

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

rfearing commented 5 years ago

I'm still having this issue too

ryanashcraft commented 5 years ago

This was one of the few reasons I needed to fork react-scripts. We use CSS modules so ordering doesn't really matter for us. And there's no clear way to address the warnings as the modules in conflict are in completely separate, very-distant parts of the parsed module tree.

pelotom commented 5 years ago

For users of CSS Modules it seems like ignoring the warnings (as described here) is a safe workaround.

ryanashcraft commented 5 years ago

@pelotom Indeed but it requires ejecting or forking.

mAiNiNfEcTiOn commented 5 years ago

Well we're also using CSS Modules (with dynamic imports) and also had this issue... So we decided to downgrade.

While downgrading got rid of the warnings, it did not get rid of the consequence of having this reported issue. We basically ran into cases where based on your starting page it would determine how the styles would be affected.

We kind of solved it by adding this to webpack's config:

  optimization: {
    /* ... */
    splitChunks: {
      chunks: 'all',
      name: false,
      cacheGroups: {
        styles: {
          name: false,
          test: /\.css$/,
          chunks: 'all',
          enforce: true,
        }
      },
    },
    runtimeChunk: true, // This line is just for you to know where I added the lines above.
  },

which resulted on certain common styles being moved to one chunk.

Now, is it the right way, or a way to solve issues? Probably not.... Just putting it out as either you guys will tell me "NO DON'T DO IT" or maybe it solves your problem.

valscion commented 5 years ago

Please note that my comment linked by @pelotom above does not reflect the opinions of webpack or mini-css-extract-plugin team. Don't let the "Member" highlight give me authority on that specific issue. I merely have that highlight as I'm maintaining a different webpack-contrib package, webpack-bundle-analyzer.

feonit commented 5 years ago

I tried to find the import place that invoke the trouble (by method exception) and after I replaced some strings annoyance is out, but this behavior still looks like some weird for me

patientplatypus commented 5 years ago

Yeah, I'm having this. Why?

joa commented 5 years ago

It seems like there are three solutions to this issue:

  1. Eject and use custom warning filters
  2. Sort all imports in all files of your code base alphabetically
  3. Use CI=false which means you still get the warning but your pipelines won't freak out

It would be great if one could chose to suppress this warning OR if CI=true yarn build would simply have a 0-exit-code albeit the warnings -- without having to eject.

When using CSS modules one is probably not interested in any cascading overrides. At least it would go against the idea of using modules in the first place.

lvl99 commented 5 years ago

We're consistently getting this inconsistent error message. It's hard to debug because am unsure how to better order the imports based off the error messages.

CSS modules is ideal for our current project because it will effectively also be a reusable component library across multiple apps. If we can't import the component-specific CSS per component JS file (and I personally am not a fan of styled-components as it makes it harder to customise based on pure CSS alone -- it forces one to get dirty in JS code to do CSS. It's just not appropriate for our project) then it kind of defeats the purpose of using CSS modules.

designbyadrian commented 5 years ago

@pelotom ignoring these errors is not a safe workaround, as the dev and prod might have CSS declarations in different order.

slavagoreev commented 5 years ago

I had the same problem. The solution was to rearrange imports in the top of the component or page that caused this kind of warning. I moved the import of buggy component to the last line so that the error disappeared.

Hope, this will help you.

lvl99 commented 5 years ago

Just following up: the solution I came up with was to maintain a separate /src/styles.ts file whereby I import all the necessary CSS in the preferred order and put that import into my /index.tsx file. It's not an entirely elegant solution (because each component has its own imported CSS, so feels a bit weird doubling up the CSS imports) but it does allow me to remove the warning messages.

alaycock commented 5 years ago

Would a PR that suppresses this warning, for css/sass module files, be accepted?

For example, in my project I have this error:

chunk 1 [mini-css-extract-plugin]
Conflicting order between:
 * css ./node_modules/css-loader??ref--6-oneOf-6-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-6-3!./src/components/Component1/Component1.module.scss
 * css ./node_modules/css-loader??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./src/components/Component2/Component2.module.scss

But there will never be a conflict between those two files.

SHRoberts91 commented 5 years ago

My issue is that I'm getting this error for packages in my node_modules:

chunk 0 [mini-css-extract-plugin]
Conflicting order between:
 * css ./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./node_modules/box-ui-elements/es/components/menu/Menu.scss
 * css ./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./node_modules/box-ui-elements/es/components/dropdown-menu/MenuToggle.scss

chunk 1 [mini-css-extract-plugin]
Conflicting order between:
 * css ./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./node_modules/box-ui-elements/es/components/label/Label.scss
 * css ./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./node_modules/box-ui-elements/es/components/datalist-item/DatalistItem.scss
 * css ./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/sass-loader/lib/loader.js??ref--6-oneOf-5-3!./node_modules/box-ui-elements/es/components/flyout/Flyout.scss

And since I have a CRA project the solutions given wouldn't work for me as far as I could tell. Any ideas?

bugzpodder commented 5 years ago

This is just a warning, you can ignore it. Make sure your CI flag is not set.

sherlockwang commented 5 years ago

I still got the same issue, and I'm sure that those file listed in the warnings don't have any interaction. Is there any possible solution to it?

sapkra commented 5 years ago

I think this PR should fix the problem but it's not released yet. https://github.com/webpack-contrib/mini-css-extract-plugin/pull/422

sherlockwang commented 5 years ago

I think this PR should fix the problem but it's not released yet. webpack-contrib/mini-css-extract-plugin#422

Cool. Thanks. Is there a release schedule?

sapkra commented 5 years ago

It was directly released after I posted my comment. So you can use version 0.8.0 and set the options documented in the README.

GiovanniGiampaolo commented 4 years ago

Yeah, this is a very valid problem. A light change in your code could alter the cascading effects of your CSS, so this is warranted. Maybe some docs on how to fix it would be nice.

SOLVED! Thanks

fabienbranchel commented 4 years ago

Since the PR was released and mini-css-extract-plugin 0.8.0, I still have this issue.

On my project, I also use storybook-react using 0.7.0 version of this plugin. I don't think so, but is it possible that this older version is use during the build ? Moreover, since this issue is still open, I guess 0.8.0 version don't fix it for CRA.

Is there someone else still experiencing it ?

Really a nightmare... :(

h-jennings commented 4 years ago

After a lot of searching around for a fix for this problem I came across this medium article which provides a method for explicitly declaring the order of your SASS imports within your project.

Consider this common folder structure for components:

components/
--| component-1
----| component-1.jsx
----| component-1.scss
---- index.js
--| component-2
--| component-3

When creating a new component I would typically import the component-1.scss into the component-1.jsx file like so:

import React from 'react'; 
import './component-1.scss';

function component1(props) {
// ...
}

This seems to cause issues of conflicting order when you use these components throughout your application.

As the article above suggests, instead of importing the component-1.scss directly into the component-1.jsx file, you should create a components.scss file at the root of your components/ folder.

Inside that components.scss declare your scss import like so:

@import './component-1/component-1.scss';
@import './component-2/component-2.scss';
@import './component-3/component-3.scss';

Then you want to @import that components.scss file into an index.scss which is referenced in your application.

Event with those changes your new folder structure should remain largely the same:

components/
--| component-1/
----| component-1.jsx
----| component-1.scss
---- index.js
--| component-2/
--| component-3/
--| components.scss

scss/
--| global/
----| global.scss
--| index.scss

Your newly created index.scss file should look something like this:

@import './global/global.scss';
@import '../components/components.scss';

And be imported into your projects index.js like so:

import React from 'react';
import '../scss/index.scss';

function App(props) {
  //...
}

To reiterate, this new SCSS architecture no longer requires you to import a components .scss file directly into the .jsx which is what causes those ordering issues. Instead, with this new architecture, you're explicitly declaring the order of your .scss component files in the components.scss file and then importing that file into the index.scss files.

No more conflicting order warnings! Hopefully this is helpful.

gonzofish commented 4 years ago

@h-jennings that would make sense...but now you'd be loading all of your site's CSS in a single chunk, which means users are loading a bunch of CSS they may not need

h-jennings commented 4 years ago

@gonzofish Yeah to be clear, this approach definitely doesn't address that. But rather, I just wanted to provide a clearer explanation of organizing your component styles in a way that avoids any ordering issues. Perhaps a hybrid approach as mentioned in this comment above would be worth looking into if you wanted to load css on a component level as needed.

fa7ad commented 4 years ago

After a lot of searching around for a fix for this problem I came across this medium article which provides a method for explicitly declaring the order of your SASS imports within your project.

Consider this common folder structure for components:

components/
--| component-1
----| component-1.jsx
----| component-1.scss
---- index.js
--| component-2
--| component-3

When creating a new component I would typically import the component-1.scss into the component-1.jsx file like so:

import React from 'react'; 
import './component-1.scss';

function component1(props) {
// ...
}

This seems to cause issues of conflicting order when you use these components throughout your application.

As the article above suggests, instead of importing the component-1.scss directly into the component-1.jsx file, you should create a components.scss file at the root of your components/ folder.

Inside that components.scss declare your scss import like so:

@import './component-1/component-1.scss';
@import './component-2/component-2.scss';
@import './component-3/component-3.scss';

Then you want to @import that components.scss file into an index.scss which is referenced in your application.

Event with those changes your new folder structure should remain largely the same:

components/
--| component-1/
----| component-1.jsx
----| component-1.scss
---- index.js
--| component-2/
--| component-3/
--| components.scss

scss/
--| global/
----| global.scss
--| index.scss

Your newly created index.scss file should look something like this:

@import './global/global.scss';
@import '../components/components.scss';

And be imported into your projects index.js like so:

import React from 'react';
import '../scss/index.scss';

function App(props) {
  //...
}

To reiterate, this new SCSS architecture no longer requires you to import a components .scss file directly into the .jsx which is what causes those ordering issues. Instead, with this new architecture, you're explicitly declaring the order of your .scss component files in the components.scss file and then importing that file into the index.scss files.

No more conflicting order warnings! Hopefully this is helpful.

That sounds like it would work, but how would that work with CSS modules?

h-jennings commented 4 years ago

@fa7ad I've never used CSS modules, so I'm not sure to be honest. Maybe someone who has could speak on that!

AndrewBogdanovTSS commented 4 years ago

I don't know about React, but I have this problem with a Vue app and it comes from a workflow of having 2 separate places for CSS - one is global css - which resides in separate CSS/SCSS files and other is in .vue file components. So if you want to blend those two together and than extract it into a single file - you can get into this case of conflicting order. Of course you won't get into such troubles if you just using one way or another, but the main question here is how to solve the issue without braking existing workflows. I will just give you a simple example where such workflow is required - imaging using SCSS version of Bootstrap in your project. You have to have imported Bootstrap scss assets as well as your own css that will come from component/jsx.

meiminjun commented 4 years ago
new MiniCssExtractPlugin({
      filename: assetsPath('css/[name].[contenthash].css'),
      allChunks: true,
      ignoreOrder: true       // **this is ok**
    }),
enzoferey commented 4 years ago

If you are using create-react-app and styled-components, you can do something like this using raw.macro:

import raw from 'raw.macro';

const myStyles = raw("./styles.css");

const MyComponent = () => {
    return <div><GlobalStyles /></div>;
}

const GlobalStyles = createGlobalStyle`
    ${myStyles}
`
bulutfatih commented 4 years ago

Is there any certain way to fix this? I'm using Next.js + Ant Design and I see a lot of warnings like this.

Conflicting order between:

  • css ./node_modules/@zeit/next-css/node_modules/css-loader??ref--5-2!./node_modules/less-loader/dist/cjs.js??ref--5-3!./node_modules/antd/lib/typography/style/index.less
  • css ./node_modules/@zeit/next-css/node_modules/css-loader??ref--5-2!./node_modules/less-loader/dist/cjs.js??ref--5-3!./node_modules/antd/lib/pagination/style/index.less
  • css ./node_modules/@zeit/next-css/node_modules/css-loader??ref--5-2!./node_modules/less-loader/dist/cjs.js??ref--5-3!./node_modules/antd/lib/spin/style/index.less

Also, pages sometimes don't display properly. I think it is because of this conflict error.

Shaquu commented 4 years ago

Is there any certain way to fix this? I'm using Next.js + Ant Design and I see a lot of warnings like this.

The same situation here. A lot of conflicts.

ChuckJonas commented 4 years ago

@bulutfatih did you ever figure anything out? Same issue (using antd & nextjs)

bulutfatih commented 4 years ago

@ChuckJonas unfortunately, I didn't find anything yet., I'm still searching for a solution.

SashaDesigN commented 4 years ago

My solution for Next.js is just to render all forms on client side, like:

class App extends React.Component {
    state = {
        mounted: false
    }

    componentDidMount(){
        this.setState({mounted: true})
    }

    render () {
        if(!this.mounted) return (<div></div>)
        // render below sensitive to this bug components
    }
}

I know, I know it's a bad approach but works for me well, I use it only for forms and doing other stuff on server side.

cpouldev commented 4 years ago

I have this issue too (I'm using Next.js). A workaround I found (as I see https://github.com/facebook/create-react-app/issues/5372#issuecomment-495509789 uses the same method too) is to put the css imports at the end of the imports.

for example, instead of

import css from './mycss.css'
import {Button} from 'components/Button'

I do

import {Button} from 'components/Button'
import css from './mycss.css'

And the warnings are gone. But its very counterproductive, especially if you have a ton of components.