Solvedangular cli Dynamically import a stylesheet depending on the environment

Please provide us with the following information:

I'm having a question about how to dynamically import 'scss' files based on the environment which is serving or building.

Example.

I have a /styles/app/app-1.scss.
I have a /styles/app/app-2.scss.

Now i have also 2 environments called app-1 and app-2
I want to be able to say if it's served/builded environment is app-2 for example that it's loading the /styles/app/app-2.scss stylesheet.

This so I can develop 1 website and depending on how I build it's including the stylesheet for overwriting some parts of the application, style the application.

OS?

Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)
Mac OSX Sierra

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here:
cli c30 and node v 7.5.0

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

The log given by the failure.

Normally this include a stack trace and some more information.

Mention any other details that might be useful.


Thanks! We'll be in touch soon.

20 Answers

✔️Accepted Answer

@agatsoh @masaanli I have found a solution for this, keep in mind this isn't exactly supported by the cli but rather a feature of Webpack.

Example of app.component.ts:

import {Component, OnInit, isDevMode} from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<h1>Testing :)</h1>',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  ngOnInit(){
    if(isDevMode()) {
      require("style-loader!./../styles2.css");
    } else {
      require("style-loader!./../styles.css");
    }
  }
}

Where styles2:

h1 {
  color: red;
}

Styles:

h1 {
  color: green;
}

While this may work it was brought to my attention by @filipesilva that there might be some drawbacks to using this solution such as:

  • Your code not being as portable
  • Styles may not be processed correctly
  • Might break if cli changes its loaders

Other Answers:

Trying to load SCSS file in my TS files gives me an error while build:
Cannot find name 'require'

I am looking for such a solution.

theme.ts

interface Theme {
  url: string;
  rel: string;
  media: string;
}

app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  theme: AppComponentThemeProvider
})
export class AppComponent {
  constructor() {
  }
}

app.component.theme.ts

export class AppComponentThemeProvider {
  constructor(@Inject(LOCALE_ID) private localeId) {
  }

  getThemes() {
    let themes = [<Theme>{url:'./app.component.css'}];

    if(this.localeId == 'fa-IR') {
      themes.push(<Theme>{url: './app.component.rtl.css'})
    }

    return themes;
  }
}

@masaanli Similar to how I have stated above

if(isDevMode()) {
      require("style-loader!./../styles2.css");
    } else {
      require("style-loader!./../styles.css");
    }

You can also do:

if(isDevMode()) {
      require("style-loader!./../styles2.scss");
    } else {
      require("style-loader!./../styles.scss");
    }

Where for example styles2.scss is:

$green : green;

h1 {
  color: $green;
}

But once again the same implications I stated above apply.

More Issues: