You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dynamically import a stylesheet depending on the environment #4685
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.
Reacted by agatsoh, Jonathan Grupp, Johannes Rudolph, Eduard Kolosovskyi, Matthew Marichiba, Rajkumar Pattnaik, Raship Shah, Rafael Tonholo, André Franciscato Paggi, Johannes Millan and 9 more
Similarly I want to know how to include .less stylesheet files in an angular2 cli project in the current scheme of things.
It would also be nice if you include in the Wiki in what order are CSS files loaded.
From angular-cli.json
From styles.css
styleUrls array inside the Component.
Which stylesheets are applied first and which ones last and which stylesheets would override the others ?
@agatsoh I believe you already posted the order correctly.
At start up it loads it from styles array in angular-cli.json which is where styles.css is loaded from lastly your specific stylesUrls within your components.
The problem I discovered is, I use Bootstrap and have in the angular-cli.json my variables defined.
I cannot override them in the app.component (require .scss)
You know maybe a solution for this?
I managed to fix it, but maybe there is abetter solution.
I fixed it by @import everything in that stylesheet.
so i require a stylesheet dynamically in the app.component.ts and in that stylesheet i import the other stylesheets. (so i have double code) for several apps. but it's working.
STILL HAVE THEN THE PROBLEM: That the variables inside the style file for components which are included like 'styleUrl' are not working anymore!!
(because 2 times require will not work. (cannot read variables from the other files).
That is because the instance of style-loader is different when called by the cli and when It's called by the require and thus you won't have access to variables from the cli instance and vice versa.
To be honest I think you are over complicating the logic to do this, A better approach for you in my opinion would be to have 2 different styles: styles.scss styles-dev.scss
Inside each of these just do the @import like you mentioned above requiring any other file you need to overwrite. Yes you will have change it in angular cli every time you want to switch between environments but realistically how often are you really switching between both of these.
If you wanted to change environments you would have to turn off the cli and re-run it with the new environment variable anyway with your current setup.
@RicardoVaranda true, but I have 1 code base and depending on the commando's I wanna be able to say deploy this version or deploy that version. You cannot add logic in the angular-cli json ;) So that's no option for me.
@RicardoVaranda Do you have any idea how we import .less stylesheets in angular2 ?
And I apologise I forgot to ask you, what about the stylesheets declared in index.html ? Do they override all other stylesheets? This is what I am observing.
Closing as this is now mostly a discussion question instead of an issue.
The CLI doesn't provide you with any preferred way out of the box to dynamically lazy load styles and apply then. You'll have to come up with a strategy yourself. Stack Overflow has great answers for this sort of question.
Approaches that intrinsically depend on webpack loader might work right now but are not officially supported, which means they can stop working at any time or might not work as expected.
@agatsoh Depends on where you want to import them and how. If you mean dynamically like what masaanli was trying to achieve you can use the same solution as I posted above I've tested it by refactoring styles2.scss to be styles2.less and the contents to be:
@green : green;
h1 {
color: @green;
}
This will load correctly but it's prune to the drawbacks I have posted above.
The priority in which it applies the css is as follows:
Component -> angular-cli styles [] -> index.html
This screenshot might clarify it for you:
Blue is the component styles, red is styles.css being loaded from angular-cli.json and finally green is a link tag from index.html.
I have used solution from this issue. However when isDevMode is undefined, it loads both scss files. When I console.log it only goes to the second block. Any idea why this happens?
I have the same question but different use case. My deploy page is https://username.gitlab.io/admin/ with /admin suffix while development mode is just localhost. I had to use route hash strategy because gitlab not support serve index.html with all route, then I had to create 2 same scss file in my home component, home.component.scss and home.prod.component.scss because the img url in dev mode is differ with prod mode (/assets/img/img.jpg and /admin/assets/img/img.jpg). I tried dynamic load with environment.production but when I run ng serve, it has an error not found home.component.scss. but it work in ng serve --aot and ng build -prod.
@matiishyn
You just need to add a Type for the require method, you can also add it to your Global Types if you have (maybe global.d.ts) or directly in your code like so
Activity
agatsoh commentedon Feb 14, 2017
Similarly I want to know how to include .less stylesheet files in an angular2 cli project in the current scheme of things.
It would also be nice if you include in the Wiki in what order are CSS files loaded.
Which stylesheets are applied first and which ones last and which stylesheets would override the others ?
RicardoVaranda commentedon Feb 14, 2017
@agatsoh I believe you already posted the order correctly.
At start up it loads it from styles array in angular-cli.json which is where styles.css is loaded from lastly your specific stylesUrls within your components.
RicardoVaranda commentedon Feb 14, 2017
@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:
Where styles2:
Styles:
While this may work it was brought to my attention by @filipesilva that there might be some drawbacks to using this solution such as:
masaanli commentedon Feb 14, 2017
@RicardoVaranda nice ! Something like this was what I searched for.
But then it's loading a css file. But is there maybe a option to do it when building or serving the project? So it's scss compiled together?
RicardoVaranda commentedon Feb 14, 2017
@masaanli Similar to how I have stated above
You can also do:
Where for example styles2.scss is:
But once again the same implications I stated above apply.
masaanli commentedon Feb 14, 2017
@RicardoVaranda
I tested it and it is working!
The problem I discovered is, I use Bootstrap and have in the angular-cli.json my variables defined.
I cannot override them in the app.component (require .scss)
You know maybe a solution for this?
I managed to fix it, but maybe there is abetter solution.
I fixed it by @import everything in that stylesheet.
so i require a stylesheet dynamically in the app.component.ts and in that stylesheet i import the other stylesheets. (so i have double code) for several apps. but it's working.
STILL HAVE THEN THE PROBLEM: That the variables inside the style file for components which are included like 'styleUrl' are not working anymore!!
(because 2 times require will not work. (cannot read variables from the other files).
RicardoVaranda commentedon Feb 15, 2017
That is because the instance of style-loader is different when called by the cli and when It's called by the require and thus you won't have access to variables from the cli instance and vice versa.
To be honest I think you are over complicating the logic to do this, A better approach for you in my opinion would be to have 2 different styles: styles.scss styles-dev.scss
Inside each of these just do the @import like you mentioned above requiring any other file you need to overwrite. Yes you will have change it in angular cli every time you want to switch between environments but realistically how often are you really switching between both of these.
If you wanted to change environments you would have to turn off the cli and re-run it with the new environment variable anyway with your current setup.
masaanli commentedon Feb 15, 2017
@RicardoVaranda true, but I have 1 code base and depending on the commando's I wanna be able to say deploy this version or deploy that version. You cannot add logic in the angular-cli json ;) So that's no option for me.
agatsoh commentedon Feb 15, 2017
@RicardoVaranda Do you have any idea how we import .less stylesheets in angular2 ?
And I apologise I forgot to ask you, what about the stylesheets declared in index.html ? Do they override all other stylesheets? This is what I am observing.
filipesilva commentedon Feb 15, 2017
Closing as this is now mostly a discussion question instead of an issue.
The CLI doesn't provide you with any preferred way out of the box to dynamically lazy load styles and apply then. You'll have to come up with a strategy yourself. Stack Overflow has great answers for this sort of question.
Functionality that we do have is a way to have a global style that isn't loaded by default in index.html, and instead are just outputted to dist. You can set a global style to be lazy, see https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/global-styles.md for more info. This has actually been around for a while but wasn't documented.
Here are a couple of random web results that show how you apply styles via javascript:
Approaches that intrinsically depend on webpack loader might work right now but are not officially supported, which means they can stop working at any time or might not work as expected.
RicardoVaranda commentedon Feb 15, 2017
@agatsoh Depends on where you want to import them and how. If you mean dynamically like what masaanli was trying to achieve you can use the same solution as I posted above I've tested it by refactoring styles2.scss to be styles2.less and the contents to be:
This will load correctly but it's prune to the drawbacks I have posted above.
The priority in which it applies the css is as follows:
Component -> angular-cli styles [] -> index.html
This screenshot might clarify it for you:

Blue is the component styles, red is styles.css being loaded from angular-cli.json and finally green is a link tag from index.html.
Hope this clarifies your queries.
kujma10-zz commentedon Jul 26, 2017
I have used solution from this issue. However when
isDevModeisundefined, it loads both scss files. When Iconsole.logit only goes to the second block. Any idea why this happens?yasiryc commentedon Jul 26, 2017
@kujma10 , did you import isDevMode from @angular/core? Also ensure that you are doing development build and not production.
sandangel commentedon Oct 12, 2017
I have the same question but different use case. My deploy page is https://username.gitlab.io/admin/ with /admin suffix while development mode is just localhost. I had to use route hash strategy because gitlab not support serve index.html with all route, then I had to create 2 same scss file in my home component, home.component.scss and home.prod.component.scss because the img url in dev mode is differ with prod mode (/assets/img/img.jpg and /admin/assets/img/img.jpg). I tried dynamic load with environment.production but when I run ng serve, it has an error not found home.component.scss. but it work in ng serve --aot and ng build -prod.
andre-f-paggi commentedon Oct 20, 2017
Any other workarounds or a solution for this?
matiishyn commentedon Nov 11, 2017
Trying to load SCSS file in my TS files gives me an error while build:
Cannot find name 'require'mousavidev commentedon Jan 26, 2018
I am looking for such a solution.
theme.ts
app.component.ts
app.component.theme.ts
ghiscoding commentedon Jul 26, 2019
@matiishyn
You just need to add a Type for the
requiremethod, you can also add it to your Global Types if you have (maybeglobal.d.ts) or directly in your code like soangular-automatic-lock-bot commentedon Sep 9, 2019
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.