Skip to content

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

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

Closed
Maximaximum opened this issue May 14, 2018 · 43 comments

Comments

@Maximaximum
Copy link

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

@Maximaximum
Copy link
Author

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"
    }
  }
}

@Maximaximum Maximaximum changed the title ng build/server --prod ignores scss url imports ng build/serve --prod ignores scss url imports if angular.json contains more than 1 style file May 15, 2018
@sainture
Copy link

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.

@alisa-duncan
Copy link

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

@blackcoffeerider
Copy link

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.

@Syam
Copy link

Syam commented Jul 6, 2018

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.

@alexandrin-rus
Copy link

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"
]

...

@thomassanders
Copy link

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

@marcosavila
Copy link

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.

@talesporto
Copy link

I'm having the same problem.

@DevDHera
Copy link

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

@mc-lovin
Copy link

same! anyone knows a temporary fix?

@mc-lovin
Copy link

mc-lovin commented Jan 13, 2019

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

@digows
Copy link

digows commented Feb 6, 2019

Same here.

Angular: 7.2.4
Material: 7.3.1
Covalent: 2.0.0

@Maximaximum
Copy link
Author

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

@Sara0710
Copy link

Having the same issue...
Angular: 7.2.2

@lbdorrou
Copy link

lbdorrou commented May 17, 2019

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"
              }
            ],

@johnwcb
Copy link

johnwcb commented Aug 9, 2019

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

@georgeslegros
Copy link

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

@Abhinay-g
Copy link

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

@waterplea
Copy link

This answer above is the real answer:
#10855 (comment)
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.

@InDieTasten
Copy link

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

@FelipeFelizardo
Copy link

FelipeFelizardo commented Dec 17, 2019

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

@hungcung2409
Copy link

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

@parrainc
Copy link

parrainc commented Jan 3, 2020

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

@amedriveroperez1984
Copy link

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

@evgenyfedorenko
Copy link

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

@tejas3006
Copy link

tejas3006 commented Feb 4, 2020

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

@Ajax30
Copy link

Ajax30 commented Feb 6, 2020

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

@pinto-arnold
Copy link

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"
],

@YosiLeibman
Copy link

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

jsfrocha added a commit to Tech4covid19/tools4edu-frontend that referenced this issue Apr 23, 2020
@dgp1130 dgp1130 added devkit/build-angular:browser needs: investigation Requires some digging to determine if action is needed triage #1 labels May 26, 2020
@Lez-Andrew
Copy link

Lez-Andrew commented Jun 4, 2020

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.

@ganeshjangam
Copy link

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

@alan-agius4 alan-agius4 added needs: discussion On the agenda for team meeting to determine next steps and removed help wanted needs: investigation Requires some digging to determine if action is needed labels Nov 5, 2020
@alan-agius4
Copy link
Collaborator

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 #18926 for more context.

@alan-agius4 alan-agius4 removed the needs: discussion On the agenda for team meeting to determine next steps label Nov 6, 2020
@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.