Angular-cli: ng build/serve --prod ignores scss url imports if angular.json contains more than 1 style file

Created on 14 May 2018  Â·  42Comments  Â·  Source: angular/angular-cli

Versions

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / â–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 6.0.1
Node: 8.9.4
OS: win32 x64
Angular: 6.0.1
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, http, language-service, material
... material-moment-adapter, platform-browser
... platform-browser-dynamic, platform-server, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.1
@angular-devkit/build-angular     0.6.1
@angular-devkit/build-optimizer   0.6.1
@angular-devkit/core              0.6.1
@angular-devkit/schematics        0.6.1
@angular/flex-layout              5.0.0-beta.13
@ngtools/webpack                  6.0.1
@schematics/angular               0.6.1
@schematics/update                0.6.1
rxjs                              6.1.0
typescript                        2.7.2
webpack                           4.6.0

Repro steps

  • In the styles.scss file, import a file via url:
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); <- here
@import "styles/_var.scss";
@import 'styles/_tables.scss';
...
  • Run ng serve --prod

Observed behavior

The https://fonts.googleapis.com/icon?family=Material+Icons file contents are absent in the output bundles.

If we do the same thing on angular v 5.2.0, the file contents ARE in the bundle.
If we do the same thing, but run ng serve without --prod flag, the file contents ARE in the bundle

Desired behavior

The https://fonts.googleapis.com/icon?family=Material+Icons file contents should be present in the output bundle, just like it did in 5.2.0.

Mention any other details that might be useful (optional)

This issue appeared only after I updated angular from v5.2.0 to v6.0.1

devkibuild-angular browser medium broken triage #1 bufix

Most helpful comment

I'm having the same issue.

"styles": [
"src/styles.scss",
"src/theme.scss"
]
and I have the following imports in my theme.scss file
@import url('//fonts.googleapis.com/icon?family=Material+Icons');
@import url('//fonts.googleapis.com/css?family=Roboto:300,400,500');
@import url('//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800');

but none of them get loaded.

All 42 comments

I've managed to narrow the issue down. The issue only reproduces if we have more than one non-empty file in projects.architect.build.options.styles setting of angular.json.

In my case, it's:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "admin-web": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts",
            "assets": [
              "src/assets",
              "src/favicon.ico"
            ],
            "styles": [
              "node_modules/normalize.css/normalize.css", <- If I remove this line, or remove all the contents from normalize.css file, everything works as expected
              "src/styles.scss"
            ],
            "scripts": [
              "node_modules/moment/min/moment.min.js"
            ]
          },
          "configurations": {
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "admin-web:build",
            "port": 5670
          },
          "configurations": {
            "production": {
              "browserTarget": "admin-web:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "admin-web:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "karmaConfig": "./karma.conf.js",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "scripts": [
              "node_modules/moment/min/moment.min.js"
            ],
            "styles": [
              "node_modules/normalize.css/normalize.css",
              "src/styles.scss"
            ],
            "assets": [
              "src/assets",
              "src/favicon.ico"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": []
          }
        }
      }
    },
    "admin-web-e2e": {
      "root": "",
      "sourceRoot": "",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "./protractor.conf.js",
            "devServerTarget": "admin-web:serve"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "e2e/tsconfig.e2e.json"
            ],
            "exclude": []
          }
        }
      }
    }
  },
  "defaultProject": "admin-web",
  "schematics": {
    "@schematics/angular:component": {
      "prefix": "app",
      "styleext": "scss"
    },
    "@schematics/angular:directive": {
      "prefix": "app"
    }
  }
}

I'm having the same issue.

"styles": [
"src/styles.scss",
"src/theme.scss"
]
and I have the following imports in my theme.scss file
@import url('//fonts.googleapis.com/icon?family=Material+Icons');
@import url('//fonts.googleapis.com/css?family=Roboto:300,400,500');
@import url('//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800');

but none of them get loaded.

Same issue here trying to import google fonts to use with mat-typography.

My angular.json includes my styles as well as primeng.

I first saw this in our build (where we had the --prod flag). When I add --prod to ng serve I can reproduce the problem locally.

I worked around it by importing the primeng css in my styles.scss. 👎

Was just about to confirm that error - but it turned out I accidentely inserted the styles in the test section of the angular.js file instead of the build section above! Hope this might help someone in the future with the same problem.

Meet the issue too:

In styles.scss

@import url('https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500,500i,700,700i,900,900i');

In angular.json

(...)
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
(...)

Roboto font work with ng serve.
Roboto font does not work with ng build --prod.

I have the same issue:

@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
@import url('https://fonts.googleapis.com/css?family=Noto+Sans:400,700');
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,300');
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600');

None of these imports are working when using --prod.

...

"styles": [
    "node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss",
    "src/styles.scss"
]

...

I have the exact same issue. Multiple styles added in angular.json, and the google font import in my scss files are not in the output css.
It works if I don't use the --prod flag, on ng build / serve.

importing the css files of my package.json directly in my scss files, is not the recommended way to do this sass loader marks this as 'deprecated'.

I'm having the same issue.
And seems like after update Angular CLI to the latest version: 6.2.5 do not resolve the problem.

I'm having the same problem.

I am also having this issue, can anyone provide a way out of this.
Problem only arise when using the prod build.

same! anyone knows a temporary fix?

as suggested above in one of the comments moved the fonts imports to variables.scss to get it working!

Same here.

Angular: 7.2.4
Material: 7.3.1
Covalent: 2.0.0

The issue has been around for a year already :( Is it going to be fixed? :)

Having the same issue...
Angular: 7.2.2

The workaround and temporary is to import file-per-file the fonts Google. (home.scss, styles.scss, footer.scss...)

Obvious that is not right but for now it works

@tiagoboeing could you explain this better? Are you suggesting to download the font file and save it locally?

In every scss file that will use Google fonts, put the @import tag in the header ...

Unfortunately for now it's the only way I found to work around the problem, since adding the @import in global style does not work during the build.

@tiagoboeing Okay thanks that worked. I played around with a lot of different scenarios trying to get this to work:

@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
body {
    font-family: 'Open Sans', sans-serif;
}

Placing in a global SCSS file did NOT seem to work.
Placing in a global CSS file did NOT seem to work.
Importing global CSS into a global SCSS did NOT seem to work.
(untested) Importing global CSS into a component SCSS.

Placing in the root app component SCSS worked (with ::ng-deep body)

Hope there is a better solution soon!

Yes, it's a temporary workaround too hard. Let's wait. 😔

+1

I've added in my index.html the link for the CDNs css for while. It's working.

I'm having the same symptoms with Angular 7.3

Edit:
I actually had this issue because my @import statement pulling in the google font was not being rendered as the first line in my compiled css file. I recently upgraded my version of Angular. Not sure why this change happened, but I solved for my case by breaking my font imports into a scss partial file and imported THAT partial file before anything else. The result is that my font @imports are the first line of my styles.css.

@import statements have to be at the top of the compiled css file or they will be ignored.
Reference link

Same issue.

 _                      _                 ____ _     ___
/ \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|

/ â–³ \ | '_ \ / _| | | | |/ _ | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ __| |_|__, |__,_|_|__,_|_| ____|_____|___|
|___/

Angular CLI: 7.3.6
Node: 10.15.3
OS: win32 x64
Angular: 7.2.9
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package Version

@angular-devkit/architect 0.13.6
@angular-devkit/build-angular 0.13.6
@angular-devkit/build-optimizer 0.13.6
@angular-devkit/build-webpack 0.13.6
@angular-devkit/core 7.3.6
@angular-devkit/schematics 7.3.6
@angular/cli 7.3.6
@angular/http 7.2.10
@ngtools/webpack 7.3.6
@schematics/angular 7.3.6
@schematics/update 0.13.6
rxjs 6.3.3
typescript 3.2.4
webpack 4.29.0

I ran into this problem as well, for us using the bundle rename feature fixed it. Unsure why currenty.

"styles": [
              "src/theme.scss",
              "src/some-other-styles.scss"
              {
                "input": "src/styles.scss", // containes url imports to cdn
                "bundleName": "styles"
              }
            ],

I am using Angular v8.1.2 with SCSS as the style format, and found the global syles.scss is not working.

In my angular.json, it is:

    "styles": [
      "src/styles.scss",
      "node_modules/bootstrap/dist/css/bootstrap.min.css"
    ]

My solution:
Remove the "node_modules/bootstrap/dist/css/bootstrap.min.css" entry from the styles array, leaving "src/styles.scss" as the only file, and then open the styles.scss, add the following line at the top:

@import "node_modules/bootstrap/dist/css/bootstrap.min";
It works for me :)

I found out that if you extract the font import you need (only one for me) to a dedicated fonts.scss file and you add that one file in the first position of the styles array of the angular.json file then it works (at least for me...)

So here is a subset of my angular.json

            "styles": [
              "src/assets/fonts/fonts.scss",
              {
                "input": "node_modules/@progress/kendo-theme-default/dist/all.css"
              },
              "src/assets/vendor/some_vendor_things.min.css",
              "src/global.scss"
            ],

Previously the fonts.scss was imported from within the global.css.

HTH

This is workaround, worked for me.
I wrote a pipeline to download file from server and append into angular run pipeline,
step 1 ) Create getScssFile.js file with below code
const http = require("https");
const fs = require("fs");

const file = fs.createWriteStream("src/variables.scss");
const request = http.get(
"https://server-path",
function(response) {
response.pipe(file);
}
);

Step 2 : update package.json file with below script
"scripts": {
"ng": "ng",
"start": "node getScssFile.js && ng serve",
"build": "ng build --prod --base-href=\"./\"",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
Step 3 : import variables.scss where its required.
Step 4 : npm run start
Step 5 : Tada..... :)

This answer above is the real answer:
https://github.com/angular/angular-cli/issues/10855#issuecomment-480959538
It is not a bug with Angular, it is how CSS specs work. @imports that are not at the very top of resulting CSS are ignored and compiler removes them because they will not work. I believe this issue should be closed, it is not related to Angular. I don't think Angular team should spend resources on some workarounds like hoisting or separate CSS files.

@waterplea If that is the case, then I think there should at least be some kind of warning during the build, that the imports are stripped, because they wouldn't be emitted at the start of the css file.

It's taken me quite a while to find this thread.

I have created a staging environment

This works with the font I set on body
"configurations": {
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
],
}
}

this don't

_"configurations": {
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
},
}_

Please help

After tried, i found that it will import font only if

  • Your @import url('link font') is on top of your file css/scss (eg: A.css)
  • A.css is first element in array of styles config

A.css content =>

@import url('https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700');
.body {
   font-family: Poppins
}

styles config in angular.json

"styles": [
              "src/A.css",
              "other.scss"
            ],

Give a try

My env is

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / â–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.21
Node: 10.17.0
OS: darwin x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.21
@angular-devkit/build-angular     0.803.21
@angular-devkit/build-optimizer   0.803.21
@angular-devkit/build-webpack     0.803.21
@angular-devkit/core              8.3.21
@angular-devkit/schematics        8.3.21
@angular/cli                      8.3.21
@ngtools/webpack                  8.3.21
@schematics/angular               8.3.21
@schematics/update                0.803.21
rxjs                              6.4.0
typescript                        3.5.3
webpack                           4.39.2

I was able to replicate the issue as well.

I have a project which had two .scss in the styles array in the angular.json file, moving the second one and just leaving the src/styles.scss as mentioned above, did the trick.

Even though the font is being imported in another .scss in a separate angular project that I'm using in my web app, the issue was caused in the web app instead.

The final version of my angular.json's styles array looks like this:
"styles": ["src/styles.scss"],

This is my env setup:

c:\parrainc\dev\app>ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / â–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.9
Node: 10.15.3
OS: win32 x64
Angular: 8.2.9
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.803.9
@angular-devkit/build-angular      0.803.9
@angular-devkit/build-ng-packagr   0.803.9
@angular-devkit/build-optimizer    0.803.9
@angular-devkit/build-webpack      0.803.9
@angular-devkit/core               8.3.9
@angular-devkit/schematics         8.3.9
@angular/cdk                       8.2.3
@angular/cli                       8.3.9
@angular/http                      7.2.15
@ngtools/webpack                   8.3.9
@schematics/angular                8.3.9
@schematics/update                 0.803.9
ng-packagr                         5.6.1
rxjs                               6.5.3
typescript                         3.5.3
webpack                            4.39.2

Any updates on this.
I'm having same issue.

Any idea why this is not being fixed. Is this not considered to be an issue?

Simply include google fonts into index.html in <head> tag instead of any scss or css file.
It will also work for production build.
http://prntscr.com/qx71rf

Does this problem have a standard (no workaround) solution yet?

Pls refer to comment from @kwdiggs & https://stackoverflow.com/questions/9860763/css-import-and-the-order-of-it#answer-9860774

I managed to get this working by having the imports in a different file and placing it first in the angular.json file

"styles": [
"src/scss/imports.scss", <== only has font import statements
"src/scss/styles.scss"
],

angular 9, added link tag in the index.html and still doesn't work

Just in case anyone finds this page, like I did...

I had what appeared to be a similar issue (font working in development, but not when deployed). The difference for me was that it was working locally in a production build too - so, just a problem after deployment.

I am using Angular 9 and deploying to Amazon AWS using serverless. What fixed the issue for me was to ensure the correct font MIME type was listed in the binaryMimeTypes array in labda.js.

facing the same issue for angular 7, Any update on this one.

Hi all,

Embedding the contents of non local external stylesheets in other css files was an undesired side-effect which was removed in version 6.

In version 11, we added an optimization to inline Google fonts and icons as part of index.html This will improve improve the First Contentful Paint of the application.

See https://github.com/angular/angular-cli/pull/18926 for more context.

Was this page helpful?
0 / 5 - 0 ratings