8

I would like to load different global css styles for different environments. In angular-cli.json it is "hardcoded" to "styles.css". Is there a way to load different css file - based on some property defined in environment?

0

4 Answers 4

9

Based on user1964629's answer I came up with the following solution

I have a white label web-app that I wanted to apply a different themes to based on which client it was for.

First I made two different apps in the angular-cli-json file. I basically duplicated the one that was there and added an name property to each one:

"apps": [{
  "name": "client1",
  ...
},
{
  "name": "client2",
  ...
}]

Client specific SCSS

In the app directory I created a folder named scss and added some files and subdirectories like so:

enter image description here

As you can see there is a client specific folder for each client containing a _theme.scss file. This file has client specific scss variables.There are also some general .scss files in the root of the scss directory.

I then added this to the client 1 app in angular-cli.json:

"stylePreprocessorOptions": {
    "includePaths": [
       "scss/client.client1",
       "scss"
    ]
  },

and this to client 2:

"stylePreprocessorOptions": {
    "includePaths": [
       "scss/client.client2",
       "scss"
    ]
  },

Adding the includePaths meant I could import scss files without specifiying the full path to the file, and at the same time only load the theme file relevant to the client. I changed my styles.scss to look like this:

@import 'theme';  // <--- this would be different based on which client app is running.
@import 'global'; // <--- this would be the same for both apps

It also meant I could @import 'theme' into any other .scss file in my project to access theme specific variables.


Client specific environments

I went a little further from here and created client specific environment files too. Like this:

enter image description here

I updated the angular-cli.json for client 1 like this:

  "environmentSource": "environments/environment.ts",
  "environments": {
    "dev": "environments/environment.client1.ts",
    "prod": "environments/environment.client1.prod.ts"
  }

And for client 2 like this:

  "environmentSource": "environments/environment.ts",
  "environments": {
    "dev": "environments/environment.client2.ts",
    "prod": "environments/environment.client2.prod.ts"
  }

Then added a 'client' property for each environment. This allowed me to make decisions in my scripts based on which client app was running. This is, for instance, what the environment.client1.prod.ts file looks like:

export const environment = {
  production: true,
  client: 'client1'
};

Finally running everything

I could then run both client apps at the same time client like so:

ng serve --app client1 --port 4201
ng serve --app client2 --port 4202
Sign up to request clarification or add additional context in comments.

Comments

1

I would suggest there could be a way to do so by passing in a string of the environment from the environment.ts file into the app component and then you could load a specific environment component which has the CSS listed in its styles array? But I'm not sure if this is 'best practice'?

Here's a link explaining the process of passing a string to a component from the environment files: https://www.google.co.uk/amp/tattoocoder.com/angular-cli-using-the-environment-option/amp/

3 Comments

Thanks for your suggestion, unfortunately this doesn't help. I am familiar how to use environment variables inside my components, but in this case I would need to use environment variable in "higher level", since I want to change global styles, not component specific styles. If angular-cli.json would allow usage of environment variables, solution would be easy, but it doesn't AFAIK.
Yeah I get you wanted to use a 'global' style so what I was trying to say was that you could wrap each "version of application" within a global component which has these specific styles?
I see what you mean, maybe I could just wrap everything inside one div in app component. That was my first thought but this solution doesn't fit best since I need to style page body tag. (css provided by client) If I don't find the another way I guess I 'll have to use root component styling instead of page body styling. Thanks again.
1

According to this issue: https://github.com/angular/angular-cli/issues/4685 There is no way to achieve this with environments. But You can do this by creating multiple apps in angular-cli.json with different "styles" property.

"apps": [
{
  "name": "app1",
  "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": [
      "styles-app1.css"
  ],
  "scripts": [],
  "environmentSource": "environments/environment.ts",
  "environments": {
    "dev": "environments/environment.ts",
    "prod": "environments/environment.prod.ts"
  }
},
{
  "name": "app2",
  "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": [
    "styles-app2.css"
  ],
  "scripts": [],
  "environmentSource": "environments/environment.ts",
  "environments": {
    "dev": "environments/environment.ts",
    "prod": "environments/environment.prod.ts"
  }
}

And then run ng with --app option e.g. ng build --prod --aot --app app1

Comments

0

You can add as may css file globally you want for your project you just need to add it in styles in angular-cli.json file like this:

 "styles": [ 
        "listing.css",
        "styles.css"
      ],

create listing.css file and it will be available globally same as styles.css

1 Comment

Thanks for your effort, Shailesh, but this is not what I want. I want to switch between different styles depending on environment, not just use all of them at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.