Angular-cli: Non uglified CSS returned when using server side rendering

Created on 10 Oct 2018  路  7Comments  路  Source: angular/angular-cli

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Command (mark with an x)

- [ ] new
- [ ] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [x] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc

Versions

Node: v9.4.0
NPM: 5.6.0

Angular CLI

Angular CLI: 6.2.3
Node: 9.4.0
OS: linux x64
Angular: 6.1.9
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.8.3
@angular-devkit/build-angular     0.8.3
@angular-devkit/build-optimizer   0.8.3
@angular-devkit/build-webpack     0.8.3
@angular-devkit/core              0.8.3
@angular-devkit/schematics        0.8.3
@angular/cdk                      6.4.7
@angular/cli                      6.2.3
@angular/flex-layout              6.0.0-beta.18
@ngtools/webpack                  6.2.3
@schematics/angular               0.8.3
@schematics/update                0.8.3
rxjs                              6.2.2
typescript                        2.9.2
webpack                           4.20.2

Repro steps

I have an universal application. I package it using the following commands:

$ ng run myapp:build --output-path dist/browser/en --i18n-locale=en --configuration=staging --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf
$ ng run myapp:server --output-path dist/server/en --i18n-locale=en --configuration=staging --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf

I use the following configuration in angular.json:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "myapp": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/myapp",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": true,
              "buildOptimizer": true
            },
            "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": true,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "myapp:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "myapp:build:production"
            },
            "staging": {
              "browserTarget": "myapp:build:staging"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "myapp:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.scss"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/myapp-server",
            "main": "src/main.server.ts",
            "tsConfig": "src/tsconfig.server.json"
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },
            "staging": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.staging.ts"
                }
              ],
            }
          }
        }
      }
    },
    "myapp-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "myapp:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "myapp:serve:production"
            },
            "staging": {
              "devServerTarget": "myapp:serve:staging"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "myapp",
  "cli": {
    "defaultCollection": "@ngrx/schematics"
  }
}

The application builds fine and everything is uglified.

The problem is when accessing the application using server rendering some additional non-uglified CSS is added in the html file. Here is a sample:

<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>Tripigo</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.dbc64a6116337be295dd.css"><style ng-transition="serverApp">nav[_ngcontent-sc0], article[_ngcontent-sc0], aside[_ngcontent-sc0] {
  height: 100px; }</style><style ng-transition="serverApp">.navbar[_ngcontent-sc1] {
  font-size: 18px;
  background-color: #000;
  padding-bottom: 10px; }
...
   color: white; } }</style><style class="flex-layout-ssr">@media all { ... }</style></head>
<body>
  <app-root _nghost-sc0="" ng-version="6.1.9"><div _ngcontent-sc0="" fxlayout="column" gdauto="" class="flex-layout-10"><header _ngcontent-sc0=""><app-header _ngcontent-sc0="" _nghost-sc1=""><nav _ngcontent-sc1="" class="navbar"><span _ngcontent-sc1="" class="navbar-toggle"><i _ngcontent-sc1="" class="fas fa-bars"></i> test </span><a _ngcontent-sc1="" class="logo" href="#">logo</a><ul _ngcontent-sc1="" class="main-nav"><li _ngcontent-sc1="" class="active"><a _ngcontent-sc1="" class="nav-links" href="#">Discover</a></li><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">Create</a></li><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">Contribute</a></li><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">How it works</a></li><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">Our blog</a></li></ul><ul _ngcontent-sc1="" class="main-nav"><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">Sign in</a></li><li _ngcontent-sc1=""><a _ngcontent-sc1="" class="nav-links" href="#">Sign up</a></li></ul></nav></app-header></header><div _ngcontent-sc0="" fxflex="" fxlayout="row" fxlayout.sm="column" fxlayout.xs="column" class="flex-layout-11"><nav _ngcontent-sc0="" fxflex="1 6 20%" fxflexorder="" fxflexorder.sm="2" fxflexorder.xs="2" class="flex-layout-12">Nav</nav><article _ngcontent-sc0="" fxflex="3 1 60%" fxflexorder="" fxflexorder.sm="1" fxflexorder.xs="1" class="flex-layout-13"><router-outlet _ngcontent-sc0=""></router-outlet></article><aside _ngcontent-sc0="" fxflex="1 6 20%" fxflexorder="" fxflexorder.sm="3" fxflexorder.xs="3" class="flex-layout-14">Aside</aside></div><footer _ngcontent-sc0="">Footer</footer></div></app-root>
<script type="text/javascript" src="runtime.fd5bb849b09656915c63.js"></script><script type="text/javascript" src="polyfills.f6ae3e8b63939c618130.js"></script><script type="text/javascript" src="vendor.8affe9e370c717fe8d86.js"></script><script type="text/javascript" src="main.72a83169baca3448611c.js"></script>

<script id="serverApp-state" type="application/json">{}</script></body></html>

I can't find any way to remove the <style ng-transition="serverApp">...</style> block...

The log given by the failure

Desired functionality

I would like to have uglified code when rendering with universal.

Mention any other details that might be useful

devkibuild-angular feature

Most helpful comment

Hi all, CSS minification in Universal is something which is already supported. You need to add "optimization": true, in theserver section of your angular.json.

"server": {
  "builder": "@angular-devkit/build-angular:server",
  "options": {
    "outputPath": "dist/server",
    "main": "src/main.server.ts",
    "tsConfig": "src/tsconfig.server.json"
  },
  "configurations": {
    "production": {
      "optimization": true,
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ]
    }
  }
}

All 7 comments

@vikerman is the <style ng-transition="serverApp">...</style> added by server side rendering automatically? Should it be minimized?

This is a big feature request. The uglification would have to plugged into the Angular compiler because the CSS is embedded in the JS generated from the Angular templates

@filipesilva @vikerman thanks very much your answer?

@vikerman okay I understand. Is it something planned for an Angular version? Is there some known workarounds? Thanks!

Hi all, CSS minification in Universal is something which is already supported. You need to add "optimization": true, in theserver section of your angular.json.

"server": {
  "builder": "@angular-devkit/build-angular:server",
  "options": {
    "outputPath": "dist/server",
    "main": "src/main.server.ts",
    "tsConfig": "src/tsconfig.server.json"
  },
  "configurations": {
    "production": {
      "optimization": true,
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ]
    }
  }
}

Let's add a separate flag for minifying CSS on the server builder.

@alan-agius4 works for me! thanks!

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NCC1701M picture NCC1701M  路  3Comments

rajjejosefsson picture rajjejosefsson  路  3Comments

sysmat picture sysmat  路  3Comments

IngvarKofoed picture IngvarKofoed  路  3Comments

daBishMan picture daBishMan  路  3Comments