Webpack: CSS resolving order

Created on 28 Mar 2014  Â·  160Comments  Â·  Source: webpack/webpack

Hi!

I have two files

require('bootstrap.css')
require('./myfile.css')

where the file bootstrap.css needs to be loaded before ./myfile.css.
Is there any way to do set the CSS resolving order properly in webpack for CSS?

bug question

Most helpful comment

I have, but it still happens.

All 160 comments

It's loaded in the order you call the requires

It's not happening on my case, any reason?
One of the files is a bower component, the other is in a local directory.

I define this:

require('se7en-bootstrap-3/build/stylesheets/bootstrap.min.css')
require('./stf-styles.css')

But they get compiled in this order:

   [45] ./res/app/layout/stf-styles.css 363 {0}
   [46] ./~/css-loader!./res/app/layout/stf-styles.css 7666 {0}
...
   [55] ./res/bower_components/se7en-bootstrap-3/build/stylesheets/bootstrap.min.css 408 {0}
   [56] ./~/css-loader!./res/bower_components/se7en-bootstrap-3/build/stylesheets/bootstrap.min.css 98258 {0}

The order in the bundle is not the order they are added to the DOM.

The oder in the bundle depends on the module id. And the module id depends on how often the id is used and alphabetical order. Or is random in dev mode.

I see.
In my case the DOM order is also the opposite, any hint?

  • --display-reasons
  • Set breakpoints in the modules and check where they are loaded.

This is strange, putting breakpoints shows them loading in the correct order.

Can I specify a css as a dependency of another css?

closing because it's old

+1

This still happens. What's the workaround?

@luisrudge Check if you have the lastest version of webpack, extract-text-webpack-plugin and css-loader. This shouldn't happen.

I have, but it still happens.

I have observed this issue using both a legacy and (at the time of writing) most up-to-date webpack and loaders. It appears to only happen on on rebuilds, however.

For example, this works as expected:

require('normalize.css');
require('app.css');

But if I comment out the 2nd line, save, wait for rebuild, uncomment, save, wait for rebuild, the order of the file content in the output is reversed.

I am splitting code with the CommonChunksPlugin but haven't explored if that matters.

My workaround is to have an entry point for each "module" that has SASS dependencies.

/* my-module/index.js */

require('./index.sass');

/* my-module/index.sass */

@import 'sass-dependency-a';
@import 'sass-dependency-b';

I'm seeing a very similar issue. Going to try the entry hack that @raypatterson is trying too.

I have this issue only if I use the extract-text-webpack-plugin.
If I turn it off the order is correct

@timaschew Have you tried the latest versions for css-loader extract-text-webpack-plugin and webpack? They should have the correct css order.

I've updated now from css-loader 0.14.5 to 0.15.1, the extract plugin is up to date at 0.8.2
but unfortunately it still doesn't work.

It's normalize.css which is almost at the end of the css file.
I used some console.logs before requiring the styles and in the browser console, the logs are in the right order

I can reproduce the issue in this repo: https://github.com/timaschew/webpack-amd-commonJs-demo

I've started to debug the issue
So first of all, the extractedChunks have the wrong order from the beginning.

But there is an getOrder function which is comparing against the index2 property.

Then I printed out the both items which are compared

{ _identifier: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css/normalize.css',
  _originalModule: 
   { dependencies: [],
     blocks: [],
     variables: [],
     context: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css',
     reasons: [ [Object] ],
     debugId: 1004,
     lastId: -1,
     id: 9,
     index: 7,
     index2: 6,
     chunks: [ [Object] ],
     warnings: [],
     dependenciesWarnings: [],
     errors: [],
     dependenciesErrors: [],
     request: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/extract-text-webpack-plugin/loader.js?{"omit":1,"extract":true,"remove":true}!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/style-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css/normalize.css',
     userRequest: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css/normalize.css',
     rawRequest: 'normalize.css/normalize.css',

and

{ _identifier: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/stylus-loader/index.js?{"resolve url": true}!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a/styles.styl',
  _originalModule: 
   { dependencies: [],
     blocks: [],
     variables: [],
     context: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a',
     reasons: [ [Object] ],
     debugId: 1006,
     lastId: -1,
     id: 4,
     index: 2,
     index2: 4,
     chunks: [ [Object] ],
     warnings: [],
     dependenciesWarnings: [],
     errors: [],
     dependenciesErrors: [],
     request: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/extract-text-webpack-plugin/loader.js?{"omit":1,"extract":true,"remove":true}!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/style-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/index.js!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/stylus-loader/index.js?{"resolve url": true}!/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a/styles.styl',
     userRequest: '/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a/styles.styl',
     rawRequest: './styles.styl',

So, okay the order function is working, but why the values for index2 have the wrong order?
So I found that webpack has two places where this variable is set

  1. lib/Compilation.js#seal
  2. [lib/Compilation.js#iteratorDependency

If I add some logs between these lines and combine some others from the css-loader and extract-plugin I get this:

>>>> css-loader/loader
>> normalize.css
>>>> css-loader/loader
>> styles.styl
####l lib/Compilation.js#seal
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/lib
##i index2: 0
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-b/icons
##i index2: 1
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##i index2: 2
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/style-loader
##i index2: 3
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##i index2: 4
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css
##i index2: 5
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css
##i index2: 6
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/domify
##i index2: 7
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-b
##i index2: 8
####i lib/Compilation.js#iteratorDependency
##i null
##i index2: 9
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/jade/lib
##i index2: 10
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##i index2: 11
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-b
##i index2: 12
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##i index2: 13
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##i index2: 14
##l /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src
##l index2: 15
<<<< extract plugin
>>>> css-loader/loader
>> normalize.css
>>>> css-loader/loader
>> styles.styl
####l lib/Compilation.js#seal
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/lib
##i index2: 0
##l /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css
##l index2: 1
####l lib/Compilation.js#seal
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/css-loader/lib
##i index2: 0
####i lib/Compilation.js#iteratorDependency
##i /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-b/icons
##i index2: 1
##l /Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a
##l index2: 2
<< getOrder, index2
/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/node_modules/normalize.css/normalize.css
6
---
/Users/awilhelm/dev/webpack-test/webpack-amd-commonJs-demo/src/feature-a/styles.styl
4

At this point it's too complex for me ^^
I don't get it, how and why index2 is set and why for normalize it's called two times.

btw: I tried this with the new version of webpack: 1.9.12

Still happen with webpack 1.10.1, css-loader 0.15.2, extract-text-webpack-plugin 0.8.2.

  • app.js
...
require('./bower_components/bootstrap/css/bootstrap.css');
require('./assets/styles/app.scss');
...
  • app.scss
body {
  background: red;
}
  • result:
    screenshot from 2015-07-12 23 34 25

Having the same problem as @timaschew and @vn38minhtran

+1

any thouhgts on this?

@luisrudge @Coobaha I just bumped my installed webpack version to 1.11.0 and css-loader to 0.15.6 and I started getting the correct import order, so this may be fixed.

I'll try that

Still doesn't work for me :(

image

Still seeing the issue here too.

These font rules are supposed to be overridden for me, they are being put at the bottom of my common.css output...

I'm using Extract + CommonChunks.

I'm having the same issue. I tried updating to webpack 1.11 and css loader but it made no difference. My bootstrap style is being loaded after my custom style eventhough it's defined before.

I have two entry points

entry.js
    require('bootstrap/dist/css/bootstrap.min.css')
    require('bootstrap/dist/js/bootstrap.min.js')
app.js
   require('mystyle.scss')
index.html
      vendor.js
      app.js

+1

+1

Also having this issue +1

+1

+1

As workaround require the vendor entry point in the application entry point.

@sokra what do you mean? I'm already requiring bootstrap's main file from my entry point file. Do I need to do something different?

The problem is propably the CommonChunkPlugin. webpack doesn't "learn" order from it. From webpacks point it just a bunch of entry points without order. So you can give webpack a hint by adding a dependency from one entry point to another (The CommonsChunkPlugin will optimize it away).

I'm not using CommonChunkPlugin

I'm using this plugins:

new webpack.optimize.OccurrenceOrderPlugin()
new webpack.optimize.DedupePlugin()
new ExtractTextPlugin('bundle.css')

A single entry or multiple?

Single.

entry: { app: [ './App/app.js' ] }

Is extract-text-webpack-plugin, css-loader and webpack up-to-date?

yes.

"extract-text-webpack-plugin": "0.8.2",
"css-loader": "0.19.0",
"webpack": "1.12.2",

My app.js file has this: import 'app.less';
My app.less file has this: @import 'CustomBootstrap.less';
My CustomBootstrap.less file has this:

@import '../node_modules/bootstrap/less/bootstrap.less';
@import 'CustomBootstrap.Variables.less';
@import 'CustomBootstrap.Styles.less';

hmm... Could you make a repo with the bug?

I'll try to create a repo with the bug in the weekend

Thanks

+1

+1

I've been running into this issue as well, but can't track down a use case of what's causing it. It seems inconsistent, but OccurrenceOrderPlugin helps make it more consistent.

+1

I've been running into this issue as well, for jQuery and bootstrap.

I resolved this by adding jQuery to plugin in webpack config :

new webpack.ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery

Hi, any news on this issue ?

Also, has anyone tried to use require.ensure to specify the desired order ?

 var a = require("a");
 require.ensure(["b"], function(require) {
    require("a").dosomething();
    var c = require("c");
});

+1

+1

+1

1) In my tests without the Extract Text Plugin, load order is very reliable and predictable, even with Live Reload and a hierarchy of views each with with their own css. The first instance of a css file is loaded first.

2) What's not clear to me is why the Webpack documentation says:

Keep in mind that it’s difficult to manage the execution order of modules, so design your stylesheets so that order doesn’t matter. (But you can rely on the order in one css file.)

Is this no longer the case? Or does this just mean don't create undefined relationships between css files and js views? It seems that require(css) as an architecture wouldn't work if load order couldn't be controlled.

3) Given that no one has provided reproduction steps and many of the comments are off topic, I really hope this is just individuals' misconfigurations or a misalignment of css and js views.

In "node_modules/extract-text-webpack-plugin/index.js" comment out the following code for a temporary fix:

 /*
 extractedChunk.modules.sort(function(a, b) {
      if(isInvalidOrder(a, b)) {
           compilation.errors.push(new OrderUndefinedError(a.getOriginalModule()));
           compilation.errors.push(new OrderUndefinedError(b.getOriginalModule()));
      }
      return getOrder(a, b); 
 }); 
 */

+1

Is there any way to set load order or priority?

This problem still exists.

main.js
@import '../node_modules/bootstrap/bootstrap.min.css';
@import 'reset.scss';

webpack.config.js
{
'test': [/.css$/, /.scss$/],
'loader': 'style!css!sass'
}

Reset loads first.

+1

Not sure if this is the same issue. I'm using react / webpack / sass.

I'm trying to have a main layout component and have a core.scss, which has a partial imported, _base.scss, which imports all my variables such as colors.

But then when I try to include components such as a Nav react component, and it has it's own component CSS such as Nav.scss, it doesn't have access to the colors since the Nav.scss loaded before the core.scss. Tested this with modifying the body colors and it indeed does load afterwards...

We should definitely build in support to change the load order. My current work around is to re-import the colors file.

Any workaround for this bug?

@Andrey-Pavlov For now, I embed all the base css code like reset.css or main.css in the index.html file itself.

I had this issue when using bootstrap loader.

webpackConfig.entry = {
  app: ['bootstrap-loader', 'src/index.js']
}

With this config, I get normalize and bootstrap loaded after my css in the <style> tag append

bootstrap-loader

Changing the bootstrap-loader to use extractStyles fixes this

webpackConfig.entry = {
  app: ['bootstrap-loader/extractStyles', 'src/index.js']
}

+1

Hi all,

I got the same problem, but I also find the solution (well, it worked for me... hopefully could be helpful for someone else).

In the middle of my codebase, there was a dynamic require, something like:

this.loadImage = (path) => require(`../../../../${path}`)

Ok so seems that this 💩y line was tricking webpack in some way _to load every single file in the code base_... killer! 😲 Removing that line solved this weird issue (and some other strange warning message in the console that started appearing...oh my god).

Dynamic requires... eeeh! 💀

+1 This is really bugging me. In the end i need to prepend my base css into my webpack build using gulp :(

This is still a problem and I'm not sure why, however, in my case it had a simple fix. I saw this issue when a main tag that I had set to display: flex was instead being set to display: block, because of the defaults from normalize.css, which are incorrectly not at the top of the stylesheet.

In my case, all I had to do (which I should've been doing in the first place) was to use a classname to style the tag instead. So (correct me if I'm wrong) but I think that most of the issues arising from weird ordering of stylesheets should be solvable by strictly enforcing something like BEM or CSS modules.

Um... @hph I get your point, and I'm glad to hear that the solution was easy to solve in your case (and if applied widely, in most cases.) However, since I typically push back against using non-semantic or redundant classes (because I'm religious about all the wrong things), and typically don't use any specific module implementation other than the native Shadow DOM (yes, I live in the future), I'm afraid enforcing BEM or CSS modules wouldn't really fly well here.

Webpack needs to get the ordering right without forcing us to change the way we think about solving problems.

Plus, the original issue wasn't with a normalizing file, it was with importing Bootstrap, and Bootstrap has classes out the wazoo.

@Jwashton I completely agree that this should be fixed and I'm not suggesting otherwise, merely mentioning an acceptable workaround for many people while this is still an issue.

I haven't tried using CSS with webpack yet, but from what I can tell on the code snippets in here, it looks like dependencies are underspecified.

You are requiring the files in a particular order _at runtime_, but from a dependency tracker's point of view, you're just a file that depends on an _unordered set_ of different files.

If your index.css file needs a dependency to appear before it, then the index.css itself should @import the dependency, telling the dependency resolver that the dependency should come first.

The other snippet with a main.jssass just moves the dependency problem down a level; the dependency tracker still doesn't know that reset.scss depends on bootstrap.min.css. It just happens that webpack does "execute" the sass before extracting the css, so the "runtime" order is preserved.

I suspect this is an issue in the extract-text-webpack-plugin and/or the css-loader. I worked around it by adding the -minimize flag to the css-loader as suggested here. As you would suspect, this also turns off CSS minification in production; I added optimize-css-assets-webpack-plugin to get minified CSS again.

+1

+1

I am also hitting this. Did anyone find a solution or workaround?

+1

People who just +1 may should check their webpack configs. There are some ideas may help

  1. try to enable/disable the loaders/plugins
  2. import will always be hoist but require wont
  3. do you extract styles from node_modules and then use common chunks plugin to merge it into a single file, and then when it is insert into the html file in the unwanted order?
  4. do you async load styles? and style loaded order is really you want?
  5. and so on

I hope this will be help, for webpack is quite complex but versatile, many may don't know what happened under the tons of configs in minutes.

+1 may not help at all IMHO

I always feel confused with styles

is there a good way for us to handle styles in webpack, css may not well designed to fit in javascript modules.

or we should just use something like less/sass/stylus and so on,?

or mysterious css in js or css module?

I kind of feel the same.
We use less + common chunks plugin, but the weird order of the css ( I say weird, as I don't fully understand it... and if something breaks I just jiggle it until it works ).

@andreechristian

+1 This is really bugging me. In the end i need to prepend my base css into my webpack build using gulp :(

Wait a minute. Why don't you just include your base css in your entry point at the very beginning (before importing other components)?

Sokra asked @luisrudge to create a repo that reproduces this bug, he never did. I suppose this is a good next step for everybody who is affected. Fairy minor contribution, but at least can help maintainer to put this issue into the queue. Much more helpful than +1's or workarounds.

@cage1618 @tugberkugurlu @jverrone3 @srahulprdxn @omarjcamo @shalanah @epilande

@pavelkornev i was pretty sure it is not going to solve it. But then i tried and then it works! I guess, my mistake was to include the base css on Page container level. Now i include it on the page controller level. The ordering works now. Thanks!

I don't use the extract-text plugin and I put the CSS at the top of my main JS entrypoint (tried both require and import). Always out of order.

I wonder if using a Map would help.
https://github.com/MoOx/postcss-cssnext/issues/282

Hi, in my case the order can be ok or not. I use the less preprocessor and different loaders depending on when I want to speeds up things.

Configuration when the order is ok (slower)
Here we have sourcemaps and css cleanup.

let lessLoader = {
  test: /\.less$/,
  loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!less-loader?sourceMap'),
  lessPlugins: [
    new LessPluginCleanCSS({
      advanced: true
    })
  ]
}

Configuration when it's NOT ok (faster)
No sourcemap, no CSS cleanup, for local development.

if (fasterLess) {
  lessLoader = {
    test: /\.less$/,
    loader: 'style!css!less'
  }
}

I don't have time to investigate myself but this can provide a hint to someone...

+1

+1

Same problem here, specifically when combining SCSS imports and webpack node_modules imports (with ~ prefix).

index.scss

@import "comp-1";
@import "~external-comp";
@import "comp-2";

Expected output

/* comp-1 */
/* external-comp */
/* comp-2 */

Actual output

/* external-comp */
/* comp-1 */
/* comp-2 */

This occurs whether I use ExtractTextPlugin or not. My SCSS loader config is as follows:

{
  test: /\.scss$/,
  loader: 'style!css?sourceMap&importLoaders=2!resolve-url!sass?sourceMap'
}

importsLoaders doesn't seem to have an effect either, as the issue remains when I remove it. The node_modules import always ends up at the top of the CSS output...

Old code:
entry.js

import `index.global.css`

index.global.css

@import url('https://fonts.googleapis.com/css?family=Open+Sans');
@import "~leaflet/dist/leaflet.css";

// custom styles
.foo {
  display: flex;
}
....
@import "~tachyons";

My solution:

@import url('https://fonts.googleapis.com/css?family=Open+Sans');
@import "~leaflet/dist/leaflet.css";
@import "./custom-styles.css";
@import "~tachyons";

Current solution I have found (using SASS to be specific) is to put dependencies to the sass file itself.

So for example that we have problem with order like:

module.js
   include a.css
   include b.scss

in index.html we got wrong order like:

   style b.css
   style a.css

All we need to do is to define depedencies explicitly in a scss file, like in b.css:

@import 'a.css';

Then webpack can properly resolve dependencies as they are explicitly defined.

Wow what a tool!
And so many great things to discover in webpack for a newcomers (as myself).
I should write another article about how cool webpack is!
Mar 28, 2014 — CSS resolving order...

@PeterStegnar Good idea, but didn't work for my setup for whatever reason. Going back to the drawing board on this one

EDIT Just kidding, needed to add a large comment to my main.scss to see that in fact that the order is indeed inforced.

If you're still not seeing your CSS changes taking effect, don't forget you can probably use an !important to assist. However that's hacky and the fact that webpack doesn't respect the SCSS import ordering is kind of embarassing.

In the meantime you can most definitely enforce order by using SCSS import'ing rather than relying on (slightly broken) JS importing.

I don't mind that there are issues which are open for years.

But it's unclear to me if this will be ever fixed and that is concerning me. @sokra please your opinion, and is there plan what to do with this issue?

tldr; If you are currently using extract-text-webpack-plugin for only some of your styling related loaders (css, scss, sass), try using it for all of them.

If your loaders for handling styling extensions (.css, .scss, etc.) are set up like mine were, than here is solution which appears to be working for me and may work for you. In my original set up, I was using the extract-text-webpack-plugin for my .scss and .sass files, but not for my .css files, which are likely most, if not all, of the stylesheets from the node modules I am using (e.g. tether, bootstrap, etc.):

config (original)

{
  test: /\.css$/,
  use: ['style-loader', 'css-loader']
},
{
  test: /\.*(sass|scss)$/,
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader', 'sass-loader']
  })
},

requires (using aliases, in the order I want them to load)

require('tetherCss');
require('tetherThemeArrowsCss');
require('tetherThemeArrowsDarkCss');
require('tetherThemeBasicCss');
require('bootstrapCss');
require('materialCss');
require('materialProjectCss');
require('pygmentsRougeDefaultCss');
require('globalStyleScss');

But the result was that none of my custom styling from globalStyleScss was having any affect. Additionally, all of the styles from the other stylesheets were each appearing in there own separate set of style tags. Not necessarily a problem, but different than what you'll see below. They were, however, appearing in the order I required them.

index.html (after webpack)

<html lang='en'>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
    <meta charset='utf-8'>
    <meta content='width=device-width, initial-scale=1, shrink-to-fit=no' name='viewport'>
    <title>My App</title>
    <link rel="stylesheet" media="screen" href="http://localhost:8080/global.css" />
    <script src="http://localhost:8080/global.js"></script>
    <style type="text/css">...</style>    <!-- styles from tether css -->
    <style type="text/css">...</style>    <!-- styles from tether theme arrows css -->
    <style type="text/css">...</style>    <!-- styles from tether theme arrows dark css -->
    <style type="text/css">...</style>    <!-- styles from tether theme basic css -->
    <style type="text/css">...</style>    <!-- styles from bootstrap css -->
    <style type="text/css">...</style>    <!-- styles from material css -->
    <style type="text/css">...</style>    <!-- styles from material project css -->
    <style type="text/css">...</style>    <!-- styles from pygments rouge default css -->
  </head>

It occurred to me to try using the extract-text-webpack-plugin for all styling files, then I would at least know they were all being handled in the same way. So, I changed my configuration to this:

config (revised)

{
  test: /\.css$/,
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader']
  })
},
{
  test: /\.*(sass|scss)$/,
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader', 'sass-loader']
  })
},

Suddenly, I had my custom styling. And notice now, there are no longer multiple style tags for styles from each of the stylesheets. There is only one stylesheet link tag, which combines all of the styles into one, in the order I listed them, with my custom styles at the bottom of all others, just like I want them.

index.html (after webpack, revised)

<html lang='en'>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
    <meta charset='utf-8'>
    <meta content='width=device-width, initial-scale=1, shrink-to-fit=no' name='viewport'>
    <title>My App</title>
    <link rel="stylesheet" media="screen" href="http://localhost:8080/global.css" />
    <script src="http://localhost:8080/global.js"></script>
  </head>

Just to be sure, I created another custom stylesheet globalExtraStyleScss, which had styling which would override globalStyleScss, and I required it after globalStyleScss. Reloading the page, I was indeed getting the styling from globalExtraStyleScss. When I moved the require for globalExtraStyleScss before globalStyleScss and reloaded the page, I got the styling from globalStyleScss as desired.

I haven't done extensive testing to see if this has permanently solved the issue for me, but I've done enough switching back and forth to see that it likely isn't random. Perhaps others can try it out and report their results. If it should suddenly stop working for me, I will report back.

Hope it helps. Cheers!

@secondstreetmedia This isn't a viable solution. Usually extract-text-webpack-plugin is used in production builds only, As the plugin doesn't support hot-module-replacement.

Using your proposition, during dev build, this issue will occur without using the plugin.

does anyone feel like producing a small repo to reproduce this problem?:)

+1 for fixing this

+1

+1 please fix…

+1 please fix it

+1

+1

Any update/plans from the Webpack team? Why isn't this resolved? What are the difficulties? When is a PR accepted?

does anyone feel like producing a small repo to reproduce this problem?:)

Does anyone has a small repo? Please post it instead of +1 ;)

For those who

  • Uses webpack v3
  • Hits this issue only in production builds (with extract-text-webpack-plugin)

Please upgrade your extract-text-webpack-plugin to 3.0.0, which is released just 6 hours ago. It solves my issue.

Related issue: https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/548

I am not using a extract-text-webpack-plugin at all. I'll be good to target the issue at its root, not by wrapping it with fixable plugin. I`ll try to provide a repo soon.

PS: Its possible to use any "css in js" approach, so this issue even won't be faced.

Unfortunately it's still an issue for us with extract-text-webpack-plugin, any way of helping to debug this even further ?

+1 Please fix!

I have installed extract-text-wepback-plugin ^3.0.0 and still experiencing this issue.

My problem was mixing require and import: the former just for loading the styles, the latter for the ES6 modules. Changing the former to use the latter fixed my problem.

to add to @jpzwarte's comment, for those who didn't know, you can do import "module-name" which is equivalent to require("module-name") if you want anonymous imports.

I have this issue too.

  • I'm using the latest release of Webpack and all of my other dependencies.
  • I'm not using extract text plugin.
  • I'm hot loading.
  • I'm using css-next.
  • The problem scripts are normalize.css and my global.css. It doesn't matter what order I put them in, whether they're import or require or either combination. global.css always loads in the document before normalize.css.

I have found no solution other than to add specificity to the rules in global.css, which is obviously not good.

+1 Please fix!

I'm experiencing the same issue as others using the latest extract text plugin.

timse commented on Mar 18

does anyone feel like producing a small repo to reproduce this problem?:)

@timse
I've created a small repo to demo this issue
https://github.com/josser/css-order-example

However, I'm not sure this is correct example ))
Guys, can you please check the code?

@josser to be sure, you are trying to demonstrate that you expect the Button to have red text, but it does not?

I haven't tried executing it, but from looking at the source, it looks like your styles.scss will be added to the head synchronously (either through a .css file or through style-loader executing at import time), _before_ the material UI styles. This is because the material UI styles are added by material-ui at runtime on componentDidMount (styles done as dynamically generated css-in-js). There is nothing webpack can do to make material UI's styles be lower specificity than your own styles.

@Kovensky You answered your own question )
But I didn't know how css-in-js working.
However if webpack can't resolve this, who can tho?

Maybe there is possibility to specify place for webpack css, so I can put them after material UI?

@josser in the case of specificity, the order of inclusion does not matter. Make your own style have higher specificity somehow.

@GGAlanSmithee it does matter as it disambiguates styles that have the same weight (if the calculated weight is the same, styles later in tree order, and if in the same tree order, later in text order have higher specificity). However, you can always boost your own specificity by adding a :root in front of your selector (:root .button); it'll still always match, but it'll have higher calculated weight.

@GGAlanSmithee it does matter as it disambiguates styles that have the same weight

@Kovensky you are right. I was only referring to rules of higher specificity, not the same:

in the case of __specificity__

Maybe I am mixing the terminology, but I guess I was talking about weight then, so let me rephrase:

If a rule with a higher weight precedes a conflicting rule with a lesser weight, the first rule will get applied.

Thanks for keeping things clear @Kovensky

@GGAlanSmithee Can you please take a look at my repo? if I'm importing scss, I just have class name and nothing to control specificity

gunta opened this issue on 28 Mar 2014

really?

gatsbyjs/gatsby#1994
is there an update about the issue? @sokra

so how do you handle the css order problem?

@Miller547719886 Only one file required is what I've decided to do. All the imports are handled by my CSS pre-processor and I have 100% control about the order in which the styles are defined. I have an index.less (or scss, etc) which is the only one imported through Webpack.

@AoDev what if I need to import the css in node_modules? In my project,I need to import a UI Toolkit with its css file.In this case how should I handle the css file in production mode?I don't want to copy one and use it as my static assets.

@Miller547719886 I import such files like this (with ~)

Example:

@import '~react-grid-layout/css/styles.css';
@import '~react-resizable/css/styles.css';

This is what I would have in my index.less file for example.

I try to avoid UI components / libraries that inject their style themselves.

@Miller547719886 I personally have included extract-text plugin and configured it to produce 2 css files. app.css(general styles) and components.css(specific styles). The order they are included is defined in index.html.

Probably soon will switch to css-in-js solution.

+1 Please fix, thanks.

My case, global styles without CSS modules plus typescript components with CSS modules (typings-for-css-modules-loader).

    {
      test: /\.p?css$/,
      include: /global/,
      use: [
        { loader: "style-loader" },
        { loader: "css-loader", options: { minimize: true } },
        { loader: "postcss-loader" }
      ]
    },
    {
      test: /\.p?css$/,
      exclude: /global/,
      use: [
        { loader: "style-loader" },
        {
          loader: "typings-for-css-modules-loader",
          options: {
            minimize: true,
            modules: true,
            namedExport: true,
            camelCase: true,
            localIdentName: "[name]-[local]-[hash:base64:5]"
          }
        },
        { loader: "postcss-loader" }
      ]
    }

Then it gets the wrong order (I want global styles at the top), no matter how I adjust the require-css order in JS:

screenshot

All packages are up to date.

Aha, I found the solution… :point_up:

Change: require("foo.css") to import "foo.css" in JS, then I got the right order:

<style type="text/css">
/* global style */
</style>

<style type="text/css">
/* components style */
</style>

is it possible to extract Bootstrap and other libraries to it's own file, so it does not appear in inline-js in our code?

"css-loader": "^1.0.0, "style-loader": "^0.21.0" -- When I used import() for a.css and b.css, b was injected into the html before a was injected. I changed import() to require(), and now the injection order matched the order of the requires

This is still a problem, I'm using v3, but requiring Sass files does not maintain order in webpack.

It's very frustrating because order matters with CSS.

@tedfitzpatrick's suggestion of using require instead of import is not working for me. It's not practical for me to use a preprocessor for these stylesheets, so what options am I left with?

using require instead of import did not work for me.

I can't reproduce the issue. I tried with Webpack 3, 4, Bootstrap 3, 4, CSS, SASS, minification, source maps, production, development mode. If you still think it exists, make a PR to my test repo, or at least tell me what I'm missing.

CSS modules are concatenated in the order of execution (requiring/importing). The only nuance here is that imports are hoisted to the beginning of a module. That's what babel does as well. So if you mix importss and requires in the same file, like,

require('./2.css');
import './1.css';

Then 1.css comes before 2.css.

Seriously, this issue continues for four years? This is very sad

@vladimir-kondratenko Try to read the thread more carefully next time.

@x-yuri sry, what solution I've missed?

@vladimir-kondratenko The issue is that there doesn't seem to be an issue. Can you please help us with reproducing it? Do you not see a way to affect the order of CSS files? Or you have a better idea of how it's supposed to work?

@x-yuri I also probably missing the same as @vladimir-kondratenko . I switched off ExtractTextWebpackPlugin and now order is correct, but with that plugin order is incorrect. I am using wepack v3. Could u tell me how to resolve issue with extract text plugin?

Could u tell me how to resolve issue with extract text plugin?

@egemon Sure, if you give me a way to reproduce it (repository or archive with the files needed to reproduce the issue).

This is insanity this is still a thing. Also:

And the module id depends on how often the id is used and alphabetical order. Or is random in dev mode.

While this seems to be true, it is very puzzling why it's the case. What good is a development environment if it doesn't even seek to emulate a production one? And worse, you have to find a four year old comment to even know.

@thomashibbard I admit that webpack is no simple piece of software, but I'd say the order is more or less obvious or expected, granted you have an idea how webpack works. From the first page of the documentation:

When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles.

You don't tell weback about the order in any way, so dependency graph basically determines the order.

What good is a development environment if it doesn't even seek to emulate a production one?

The order must not change from one environment to another. Can you help to reproduce it?

Also, if you don't like its idea of order, what's yours? How would you like it to work?

Could u tell me how to resolve issue with extract text plugin?

@egemon Sure, if you give me a way to reproduce it (repository or archive with the files needed to reproduce the issue).

Hello. I looked at your repository and it seems you are importing them inside a js file. Im not sure if that`s why its working for you, but for me its like this -

I have app.scss file with -

@import '~bootstrap/scss/bootstrap'; @import "~bootstrap-social/bootstrap-social.css";

And bootstrap seems to be added after bootstrap-social. Maybe this helps you to figure this out? Im using laravel-mix. I understand that adds another element in the equation, but as I dont know much about the workings of webpack, this is what I use to make it easy.

The main problem with css order - css is not deterministic. Example:
A.js:

@import 'foo.css';
@import 'bar.css';

B.js:

@import 'bar.css';
@import 'foo.css';

App.js:

@import 'A.js';
@import 'B.js';

When we extract css, who should be first?

@evilebottnawi from my point of view it would be great to have a flag to make that error out and force the same order everywhere, since if there's any shared css in those files, A and B will have different outputs

@CoolGoose we already do warning in mini-css-extract-plugin, do you have other case where you have invalid order and no warnings?

@evilebottnawi I wouldn't call that nondeterministic. I believe nondeterministic is when output changes when input doesn't. What we have in the example though is contradicting demands.

I take it the resulting order is determined by the first time a file was required. And a warning is given when css files are required in different orders. Which means... case closed, no? :)

I'd like to check the last suggested case, but it's unlikely we'll learn anything new.

@x-yuri we can have more difficult cases, so need good algorithm for this, maybe with options about preferences and controlling (this should be implemented in mini-css-wepback-plugin) and in next iteration union with style-loader and css-loader and when moving as css support out of box in webpack

I don't know if it could be an important point but: is webpack's dependency graph created synchronously or asynchronously?

It's 2020 and people (like @Abhi0725) are still asking those kind of questions? Instead of putting effort. Like, reporting his/her specific case and telling what he/she expects webpack to do (exactly). Or reading the issue carefully to see that (most likely) webpack does as expected.

@evilebottnawi So you believe there are still cases where webpack's behavior is suboptimal, and you keep this issue open for people to report those cases? Or you keep the issue to not forget to improve the algorithm? I wonder what might those improvements be like?

@x-yuri I shall attempt to clarify what I believe other people are experiencing and what I myself am, in relation to how I should expect webpack to behave in this scenario.

Given the following code in the root App.js in my react application:

import 'semantic-ui-css/semantic.min.css';
import './assets/scss/layout.scss';

I should expect the rules from layout.scss to be included in my bundle after the rules from semantic. This is not the case. However, when I change the code to this:

import 'semantic-ui-css/semantic.min.css';
import './assets/scss/z_layout.scss';

(note the 'z' before layout) the rules in my layout file are rendered after the rules from semantic.

This is not how I personally should have expected webpack to behave. I should expect the bundle to reflect the order in which the files were requires / imported, rather than including them alphabetically. Hopefully that helps clear things up.

@alexanderharwood (hopefully I guessed the username right) The behavior you're describing is not correct. Can you please create a test repository that I can git clone && npm i && webpack to reproduce the issue? Then I can investigate the case.

+1

This might help

I can't reproduce the issue. I tried with Webpack 3, 4, Bootstrap 3, 4, CSS, SASS, minification, source maps, production, development mode. If you still think it exists, make a PR to my test repo, or at least tell me what I'm missing.

CSS modules are concatenated in the order of execution (requiring/importing). The only nuance here is that imports are hoisted to the beginning of a module. That's what babel does as well. So if you mix importss and requires in the same file, like,

require('./2.css');
import './1.css';

Then 1.css comes before 2.css.

In my case this was my issue. I mixed require and import but import files were always loaded first. The solution is to use the same require or import for all CSS files import.

This might help

I can't reproduce the issue. I tried with Webpack 3, 4, Bootstrap 3, 4, CSS, SASS, minification, source maps, production, development mode. If you still think it exists, make a PR to my test repo, or at least tell me what I'm missing.
CSS modules are concatenated in the order of execution (requiring/importing). The only nuance here is that imports are hoisted to the beginning of a module. That's what babel does as well. So if you mix importss and requires in the same file, like,

require('./2.css');
import './1.css';

Then 1.css comes before 2.css.

In my case this was my issue. I mixed require and import but import files were always loaded first. The solution is to use the same require or import for all CSS files import.

Yeah, but don't do that manually. Instead, use some tool like this: https://github.com/ggascoigne/prettier-plugin-import-sort

Does the tool allow exceptions? Like, sort alphabetically but z.css should go before d.css? If not, that's not relevant here. Most people come here with order dependencies. Although, the tool itself sounds interesting.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haohcraft picture haohcraft  Â·  3Comments

d4goxn picture d4goxn  Â·  3Comments

nwhite89 picture nwhite89  Â·  3Comments

nicksparks picture nicksparks  Â·  3Comments

andersekdahl picture andersekdahl  Â·  3Comments