When I check bundle after ng build --prod --aot false
I found that css files order was modified by the build process.
angular-cli.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "performance"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.css",
"../node_modules/font-awesome/css/font-awesome.css",
"../node_modules/animate.css/animate.min.css",
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
"styles.scss"
],
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/metismenu/dist/metisMenu.js",
"../node_modules/jquery-sparkline/jquery.sparkline.js",
"../vendor/pace/pace.min.js"
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}
package.json
{
"name": "performance",
"version": "1.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --host 0.0.0.0",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^4.0.1",
"@angular/common": "^4.0.1",
"@angular/compiler": "^4.0.1",
"@angular/compiler-cli": "^4.0.1",
"@angular/core": "^4.0.1",
"@angular/forms": "^4.0.1",
"@angular/http": "^4.0.1",
"@angular/platform-browser": "^4.0.1",
"@angular/platform-browser-dynamic": "^4.0.1",
"@angular/platform-server": "^4.0.1",
"@angular/router": "^4.0.1",
"@ngui/auto-complete": "^0.16.0",
"@swimlane/ngx-charts": "^6.1.0",
"angular-autofocus-fix": "^0.1.0",
"angular2-image-upload": "^1.0.0-rc.0",
"angular2-masonry": "^0.4.0",
"angular2-moment": "^1.7.0",
"animate.css": "3.1.1",
"bootstrap": "^3.3.7",
"chart.js": "^2.7.1",
"core-js": "^2.4.1",
"d3": "^4.11.0",
"font-awesome": "^4.7.0",
"jquery": "^3.1.0",
"jquery-slimscroll": "^1.3.8",
"jquery-sparkline": "^2.4.0",
"jvectormap": "1.2.2",
"metismenu": "^2.5.0",
"ng2-charts": "^1.5.0",
"ng2-completer": "^1.6.3",
"ng2-file-upload": "^1.2.1",
"ng2-smart-table": "^1.2.2",
"ng2-toastr": "^4.1.2",
"ngx-bootstrap": "^1.6.6",
"ngx-slimscroll": "^3.4.1",
"ngx-ui-switch": "1.4.4",
"ngx-webstorage": "^1.8.0",
"peity": "^3.2.1",
"rxjs": "^5.1.0",
"zone.js": "^0.8.4"
},
"devDependencies": {
"@angular/cli": "^1.0.0",
"@angular/compiler-cli": "^2.4.0",
"@types/jasmine": "2.5.38",
"@types/node": "~6.0.60",
"codelyzer": "~2.0.0",
"jasmine-core": "~2.5.2",
"jasmine-spec-reporter": "~3.2.0",
"karma": "~1.4.1",
"karma-chrome-launcher": "~2.0.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^0.2.0",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.0",
"ts-node": "~2.0.0",
"tslint": "~4.5.0",
"typescript": "~2.4"
}
}
Please provide the output of ng --version
.
A minimal reproduction would also be very useful to aid in further investigate of the issue.
ng --version:
Your global Angular CLI version (1.6.7) is greater than your local
version (1.6.5). The local Angular CLI version is used.
To disable this warning use "ng set --global warnings.versionMismatch=false".
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 1.6.5
Node: 9.4.0
OS: linux x64
Angular: 4.4.6
... animations, common, compiler, compiler-cli, core, forms
... http, platform-browser, platform-browser-dynamic
... platform-server, router, tsc-wrapped
@angular/cli: 1.6.5
@angular-devkit/build-optimizer: 0.0.42
@angular-devkit/core: 0.0.29
@angular-devkit/schematics: 0.0.52
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.5
@schematics/angular: 0.1.17
typescript: 2.4.2
webpack: 3.10.0
When I open xxxxbundle.css
I find the order of css injections different than the order specified in angular-cli.json
I have the same issue starting cli 1.6.4 (does not occurs on 1.7.0-beta3).
I can confirm this issue exists in angular-cli 1.65, 1.6.6 and 1.6.7. If you reverse the order of your styles
array in angular-cli.json, you can preview the bug in 'serve' mode, to a degree
@clydin on 1.6.7, when I build with a styles array like below:
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/angular-calendar/dist/css/angular-calendar.css",
"../node_modules/nouislider/distribute/nouislider.min.css",
"styles.scss"
],
The CSS files are bundled with styles.scss
at the top. The rest follow the correct order. (In my screenshoot, nouislider is after angular-calendar on the same line; it's in there, but not in the screenshot).
Reverting to 1.6.3 (and then installing @angular-devkit/[email protected]
manually via NPM) was the only solution I could find.
ng build --prod -extract-css false
solved the problem until finding final solution
@clydin I'm experiencing this issue with the Angular CLI v1.7.1 too. The styles array looks like this:
"styles": [
"./app/shared/styles/material-theming.css",
"./app/shared/styles/styles.css"
],
Yet, the CSS of material-theming.css
is inserted _below_ the rules of styles.css
.
This issue is marked with the label "need: more info". What other info can we provide that would help you debug this?
I had the same problem while adding third-party CSS framework I wanted to extend. Finaly I just imported it through src/styles.(sass/css/scss)
and it works great. As styles you insert into .angular-cli.json
are intended to be global, using src/styles.(sass/css/scss)
you reach the same goal. I think it's a nice work around.
I had the same problem with 1.6.4 and switching to cli 1.7.4 fixed it.
Did a clean npm i
with the latest everything, including cli 1.7.4 — the problem is still there.
I’m afraid “need: more info” label diverts attention away from this issue while ng --version
was provided back in February.
Strangely, I notice that the styles are in the desired order when I run in dev mode, but in the wrong order when I run in production.
Any update on this?
@andresmgsl Not sure which version fixed this, but it's not present in 1.7.1, at least.
I already reverted CLI twice because of this issue.
1.71 > 1.68
1.74 > 1.68
Same problem with 6.03 version now.
Dev build is fine, prod build still not good.
Related: https://github.com/angular/angular-cli/issues/10579
I solved this issue by placing the css I wanted to import on top of styles.css instead of in the json file like recomended...
This issue is still present in 6.0.5. Or at least in some form. I'm migrating an existing project to Angular CLI, and when disabling extractCss, it works as intended, while with extractCss enabled, the styles are broken.
@nicolasfoisy can you please explain what you did there to solve it?
what do you by placing the css... where did you place it? copied it into styles.css?
Still present in 6.0.7. Setting extractCss to false fixes it for me too.
Indeed issue is still present:
styles.css
is the last style in the array but when extractCss
is enabled, the bootstrap css file overwrites the styles.css
rules because it's added under it in the bundle.
Angular CLI: 6.0.8
Node: 10.4.0
OS: win32 x64
Angular: 6.0.4
@ErazerBrecht I am using a .scss file with the imports of the third party style instead of the style.css and I am having the same issue, every time I run the command ng build --prod it create the dist folder but the style.css is like corrupted because all classes are together in 1 line and are not taking effect, same happens to the main.js file.😓😭
do you think I should change it back to the style.css?
@clydin I also see a similar problem, but I build my application with custom webpack config. And CSS selectors is reorder when I have AngularCompilerPlugin in my pipeline.
I'm created repository for showing this problem. In it you will see 2 directories (dist-dev
and dist-prod
) with different ordering CSS selectors.
I'm using:
Angular CLI: 6.0.8
Node: 9.10.1
OS: MacOS 10.13.4
Angular: 6.0.9
It turned out to fix the problem by transferring the import common.scss
from the app.module.ts
to the browser.module.ts
. But I'm sure that this is really the right decision.
I'm uploaded this fix in fix-reorder branch
Anyone else have a workaround for this issue? Setting extractCss doesn't seem to work for me either... Angular CLI 6.1.5.
@Trojaan i fixed this issue with this
issue #13948
adding this line in the index
<script>document.write('<base href="' + document.location + '" />');</script>
https://github.com/angular/angular/issues/13948
@oneal1801 Thanks! This fixed it! :)
Very strange bug. My temporary solution:
moved all css
files from angular.json
to styles.scss
using @import
Any update on this bug.
I face the same issue. I did the same workaround as fedotxxl but this is not the proper way and I receive depreciation warning:
"Including .css files with @import is non-standard behaviour which will be removed in future versions of LibSass.
Use a custom importer to maintain this behaviour. Check your implementations documentation on how to create a custom importer."
Thanks for the feedback
The problem is with your @import like you are importing some google font. So Angular transpile that stylesheet on priority basis and gets loaded before the said order. Let see this example:
"styles": ["node_modules/bootstrap/dist/css/bootstrap.min.css", "src/assets/css/new-age.css" ],
Just look at this new-age.css file:
@import url('https://fonts.googleapis.com/css?family=Lato|Oswald');
html,
body {
width: 100%;
height: 100%;
background: #edf1f5;
}
......
Solution is to make a separate css file for these imports and then mention it angular.json like this:
"styles": ["node_modules/bootstrap/dist/css/bootstrap.min.css", "src/assets/css/new-age.css", "src/assets/css/imp.css" ],
What's the point to prioritize CSS files with @import?
As a develloper I should handle my priority or at least I should be able to tell that I don't want priority manager by Angular.
I put stuff in specific order. This shouldn't be altered.
More the worst thing is that we are only facing this in "build mode" not in serve. That's another stuff that is in my opinion is bad. That's the type of stuff you don't want to face when you deliver your app in QA environment.
thanks
As a develloper I should handle my priority or at least I should be able to tell that I don't want priority manager by Angular.
I put stuff in specific order. This shouldn't be altered.
More the worst thing is that we are only facing this in "build mode" not in serve. That's another stuff that is in my opinion is bad. That's the type of stuff you don't want to face when you deliver your app in QA environment.thanks
You need not to change the order or anything, All you need to do is to keep @import in a separate css file and add that too in angular.json and it will start working. I had exactly the same issue which I tried and it worked like charm for me.
What's the point to prioritize CSS files with @import?
When Angular bundles multiple css files, it keep content of those files with @import prior to other no matter whatever order you put in angular.json.
@jaykhatri Maybe this behavior has some good reason, but it is often very inconvenient. For example, one can use some third-party library with a stylesheet using an import. There's no simple way to put the import in a separate file.
@jaykhatri Maybe this behavior has some good reason, but it is often very inconvenient. For example, one can use some third-party library with a stylesheet using an import. There's no simple way to put the import in a separate file.
That's the bug for sure. All I shared was my experience in case if someone have simple @imports that can be handled.
Third party library is the key point here. I don't want to recreate/split all library css. I think we need to have a bool in the compiler to choose or not to apply the Css @import ordering.
As we said, the worst part in this also is that Prod Build & Serve don't behave the same.
Any news on this? Thanks,
@alan-agius4 @clydin
Do you need more information to track this?
Hi, I have tried this using @angular-devkit/build-angular
version 0.10.0
and @angular/cli
version @angular/cli
and was unable to reproduce.
When having the below;
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.scss"
],
The bootstrap
css files was emitted on top of the contentes of styles.scss
Can you setup a minimal repro please? A good way to make a minimal repro is to create a new app via ng new repro-app
and adding the minimum possible code to show the problem. Then you can push this repository to github and link it here.
@alan-agius4
Hi,
Sorry for the late answer, but now here is a repro:
https://github.com/elvince/AngularCSSReproBug
You can see that in angular.json I set:
"styles": [
"src/styles2.css",
"src/styles.scss",
"src/style.css"
]
And if you do:
ng server --prod=true
or
ng build --prod
The content of the last Style.css is put at the beginning of the final style file.
I hope this will allow you to repro properly the bug and find the root cause.
If you need more input, plz ask
@elvince, in css the @import
rule must be at the top of the stylesheet, thus this sheetsheet which contains @import
is taking priority over others. See https://developer.mozilla.org/en-US/docs/Web/CSS/@import
If the @import
rule is removed the order is retained properly.
Closing as it's working as expected.
I don't understand why this has been closed. This is apparently a bug in cli, because it behaves differently in development and production mode. It should either behave consistently, or produce an error if there is some syntax error in the inputs.
@alan-agius4
Thanks for the feedback. While I understand that you are folowing the @import rules.
I was just wondering if we can smartly solve this case.
I mean Angular is awesome because we have a lot of module available to us and sometime we can have @import statement in the css files that are in those external modules and we need to keep depency loading.
Let's say a module A depends on BootStrap but add a import statement how can we deal with this?
Here are my proposal:
1 - in case an @import is detected in a file, just push the statement at the top of the css but keep the rest at the same position (file ordering)
2 - Have a set of recommandation for "Modules css" to add import in seperated files so we can add them safely and the current reordering will work.
3 - ?? any other options?
Following what @sebek64 is saying, in all case Dev and Prod must behave the same so we don't discover css bugs later on in our dev workflow.
Thanks
@chaouiy
ng build --prod -extract-css false
solved the problem until finding final solution
Thank you, it is working for me as well! Can you explain me why this options works?
Yikes, just ran into this. This seems like a much higher-priority issue than the attention it's currently being given would indicate. This bug eliminates the benefits of a testing environment. (Ask me how I know.)
The current workaround (to turn off extractCss) has the effect of applying styles from JavaScript instead of letting the browser handle it natively. This is a pretty bad compromise from a performance standpoint.
I am having issues with this too. Hope it can be addressed
So it's been more than 2 years, 1 after marked as "broken", but we still have no news about it at this day in 2020...
what a mess, consitency is very important, the fact that I have to use a workaround after years of the original discovery of such important aspect of large web site development that requires integration of third party overrides, bootstrap overrides, complex component overrides at the very least there should be a defined structure / hierarchy that is logical and sound for accurately applying css and managment of it long term. I hope this gets addressed soon!
Lately I've been asked to create demos and prototypes and it makes it very complicated for me to have to document specific build instructions and explain perf issues to the third parties I support and that will be evaluating the prototypes to use in thier environments! Really puts a shadow of doubt in thier minds about the apps and what else might be funky.
Facing same issue.
Angular CLI: 8.3.25
Node: 12.13.1
OS: win32 x64
Angular: 8.2.14
Confirmed that this behavior still exists in Angular 9.
Angular CLI: 9.0.5
Node: 10.15.3
OS: win32 x64
Angular: 9.0.5
Ivy Workspace: Yes
Confirmed in Angular 9.
Switching "extractCss"
to false
solves the issue for me.
Angular CLI: 9.1.0
Node: 12.14.0
OS: linux x64
Angular: 9.1.1
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.901.0
@angular-devkit/build-angular 0.901.0
@angular-devkit/core 9.1.0
@angular-devkit/schematics 9.1.0
@angular/cdk 9.2.0
@angular/cli 9.1.0
@angular/material 9.2.0
@angular/pwa 0.901.0
@schematics/angular 9.1.0
@schematics/update 0.901.0
rxjs 6.5.5
typescript 3.8.3
Hi all,
Apologies for the delay in addressing this.
The fix will be part of the the next patch release (9.1.2).
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
ng build --prod -extract-css false
solved the problem until finding final solution