Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS resolving order #215

Closed
gunta opened this issue Mar 28, 2014 · 169 comments
Closed

CSS resolving order #215

gunta opened this issue Mar 28, 2014 · 169 comments

Comments

@gunta
Copy link

gunta commented Mar 28, 2014

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?

@sokra
Copy link
Member

sokra commented Mar 28, 2014

It's loaded in the order you call the requires

@gunta
Copy link
Author

gunta commented Mar 28, 2014

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}

@sokra
Copy link
Member

sokra commented Mar 28, 2014

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.

@gunta
Copy link
Author

gunta commented Mar 28, 2014

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

@sokra
Copy link
Member

sokra commented Mar 28, 2014

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

@gunta
Copy link
Author

gunta commented Mar 28, 2014

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

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

@sokra sokra added the question label Mar 28, 2014
@sokra
Copy link
Member

sokra commented May 8, 2014

closing because it's old

@sokra sokra closed this as completed May 8, 2014
@crittelmeyer
Copy link

+1

@luisrudge
Copy link

This still happens. What's the workaround?

@sokra
Copy link
Member

sokra commented Jun 9, 2015

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

@luisrudge
Copy link

I have, but it still happens.

@raypatterson
Copy link

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.

@raypatterson
Copy link

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';

@jcreamer898
Copy link

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

@timaschew
Copy link

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

@sokra
Copy link
Member

sokra commented Jun 24, 2015

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

@timaschew
Copy link

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

@timaschew
Copy link

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

@timaschew
Copy link

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

@minhtranite
Copy link

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

@jackmoore
Copy link

Having the same problem as @timaschew and @vn38minhtran

@Coobaha
Copy link

Coobaha commented Jul 30, 2015

+1

@luisrudge
Copy link

any thouhgts on this?

@jackmoore
Copy link

@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.

timaschew referenced this issue Aug 6, 2015
this caused incorrect order of rules in extracted css
expose index and index2 to the stats
@luisrudge
Copy link

I'll try that

@luisrudge
Copy link

Still doesn't work for me :(

@luisrudge
Copy link

image

@vohaha
Copy link

vohaha commented Oct 7, 2018

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

@x-yuri
Copy link

x-yuri commented Oct 7, 2018

@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?

@egemon
Copy link

egemon commented Oct 19, 2018

@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?

@x-yuri
Copy link

x-yuri commented Oct 19, 2018

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).

@thomashibbard
Copy link

thomashibbard commented Oct 23, 2018

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.

@x-yuri
Copy link

x-yuri commented Oct 24, 2018

@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?

@davisriska
Copy link

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.

@alexander-akait
Copy link
Member

alexander-akait commented Feb 8, 2019

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?

@CoolGoose
Copy link

@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

@alexander-akait
Copy link
Member

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

@x-yuri
Copy link

x-yuri commented Feb 8, 2019

@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.

@alexander-akait
Copy link
Member

@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

@gabsprates
Copy link

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

@x-yuri
Copy link

x-yuri commented Jan 11, 2020

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
Copy link

x-yuri commented Jan 18, 2020

@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.

@kidzen
Copy link

kidzen commented Aug 24, 2020

+1

@maurisrx
Copy link

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.

@gabsprates
Copy link

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

@x-yuri
Copy link

x-yuri commented Oct 19, 2020

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.

@SUXUMI
Copy link

SUXUMI commented May 6, 2021

7 years has been passed since this ticket was submitted and the issue still exists.

The solution what I found is to use third party plugins .scss files OR .css files only, do not use mix of them! In this case importing order is OK. But if I mix third party plugins' .css and .scss files, then .css files always goes first.

@alexander-akait
Copy link
Member

We cannot guarantee CSS ordering between modules, because in some cases it is not possible, can you provide example the problem, I will say how to fix it/why you need to use other orders and say why it happens

@SUXUMI
Copy link

SUXUMI commented May 8, 2021

We cannot guarantee CSS ordering between modules, because in some cases it is not possible, can you provide example the problem, I will say how to fix it/why you need to use other orders and say why it happens

Dear Alexander,
Thank you for your reply

I've a very simple app.scss code:

@import '~bootstrap/scss/bootstrap';
@import '~third-party/sample.min.css';

in output, via mix, third-party styles goes first after compilation.

If sample is *.scss , then it's ok but sometimes such files are not provided.

What would be the way out in this case?

@alexander-akait
Copy link
Member

It is not webpack problem, try to compile scss without webpack, @import with CSS extensions keeping as is after SCSS compiler, then css-loader resolve them and import, https://sass-lang.com/documentation/at-rules/import#plain-css-imports, try to remove css extension

@SUXUMI
Copy link

SUXUMI commented May 10, 2021

Dear @alexander-akait thanks
but here laravel-mix/laravel-mix#429 (comment) was said the same.

anyway, thanks for your time. try to play around.

@alexander-akait
Copy link
Member

No webpack issue here, you have:

@import '~bootstrap/scss/bootstrap';
@import '~third-party/sample.min.css';

after sass (node-sass/sass (dart)) you will have

@import '~third-party/sample.min.css';

// Just example of code
.bootstrap-classes { color: red; }

After css-loader you will have:

// Just example of code
.bootstrap-classes { color: blue; }

// Just example of code
.bootstrap-classes { color: red; }

This is misleading, but in fact this is how sass works.

@johnnykrk
Copy link

In my case the styles in bootstrap.css was always at top of my custom styles scss.
To fix that I changed the loaders order in webpack.dev.config.js to have fisrt the test: /.scss$/:
{
test: /.scss$/,
use: [
'style-loader', 'css-loader', 'sass-loader'
]
},
{
test: /.css$/,
use: [
'style-loader', 'css-loader'
]
},

@alexander-akait
Copy link
Member

I think we can close it, if somebody have problems with order, please open an issue in https://github.com/webpack-contrib/css-loader with example of the problem, currently most of the problems are solved

@thoughtspile
Copy link

thoughtspile commented Sep 29, 2021

If you're seeing out-of-order CSS in production mode inside node_modules, head over here: #7094

I brought a repro!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests