Jecelyn Yeen
In a typical Angular project, you’ll have many components. Each components has it own stylesheet (css, scss, less, etc). It’s quite often that you might need to include global styling files (especially variables file) in your component.
We’ve talked on this a bit in our other Angular styles article: Using Sass with the Angular CLI
Let’s explore another option for importing style files:
Let’s say you have a _variables.scss
in your src/stylings
folder:
// your folder structure
- src
- app
- app.component.ts
- hello
- hello.component.html
- hello.component.scss
- hello.component.ts
- ...
- stylings
- _variables.scss
// your _variables.scss file
$brand-color: #800000;
Below is our hello.component.html
file, let’s style the header with our brand-color
.
<!-- hello.component.html -->
<h1>
Hello World!
</h1>
The $brand-color
variable is in stylings/_variables.scss
file. We need to import the file in order to use it:
// hello.component.scss
@import "../../../stylings/variables"; // this is not cool!
h1 {
color: $brand-color;
}
See the ../../../stylings/
syntax? Do you like it?
Imagine you need to repeat this ../../../stylings/
in another tens or hundreds of components and you need to remember the relative path. This is not cool. Let’s fix this!
If your project is generated with Angular CLI, you can add a configuration stylePreprocessorOptions > includePaths
in .angular.cli.json
file. This configuration allows you to add extra base paths that will be checked for imports. It tells Angular CLI to look for styling files in the mentioned paths before processing each component style file.
For example, in our case, let’s add ./stylings
in the paths. Since the configuration accept an array, you can add multiple paths.
{
...
"apps": [{
"root": "src",
...
"stylePreprocessorOptions": {
"includePaths": [
"./stylings"
]
}
}]
}
With this, we can update our hello.component.scss
to just @import "variables"
. Sweet!
// hello.component.scss
@import "variables"; // change to just variables, say goodbye to ../../../stylings/
h1 {
color: $brand-color;
}
Imagine you included two styling paths in .angular.cli.json
, both have _variables.scss
file. Guess what will happen? Will the CLI pick up both files or throw errors?
Let’s test it out together!
// your folder structure
- src
- ...
- stylings
- _variables.scss
- stylings2 // add this
- _variables.scss
In stylings2/_variables.scss
, you have the following styles,
// stylings2/_variables.scss
$brand-color: blue;
$font-size-large: 40px;
Update your .angular.cli.json
configurations, to include styling2
folder path.
{
...
"apps": [{
"root": "src",
...
"stylePreprocessorOptions": {
"includePaths": [
"./stylings",
"./stylings2"
]
}
}]
}
Update your hello.component.scss
file,
// hello.component.scss
@import "variables";
h1 {
color: $brand-color;
font-size: $font-size-large;
}
Restart your dev server. Wait for a while, and you should expect… Error!
Turn out, if there are multiple files with same name, Angular CLI will pick only the first file that match the name. In this case, it will pick the stylings/_variables.scss
file. That’s why it could not get the variable $font-size-large
, because it’s in styling2/_variables.scss
file.
Well, there are cases where you have multiple files with the same name and you really need it, and you would like to have shortcuts as well. The workaround would be including the parent path. For example, in our case, both stylings
and stylings2
folders parent are src
.
We can update the .angular.cli.json
configuration to the following:
{
...
"apps": [{
"root": "src",
...
"stylePreprocessorOptions": {
"includePaths": [
"."
]
}
}]
}
Then, in your hello.component.scss
, you can refer to both variables file like the following,
// hello.component.scss
@import "stylings/variables";
@import "stylings2/variables";
h1 {
color: $brand-color;
font-size: $font-size-large;
}
Well, it’s not perfect, slightly more words to type, but better than ../../../
right? Also, it might be rare scenario that you have multiple style files with same name in the same project, I guess?
Another shorter workaround would be including parent path and one styling path:
{
...
"apps": [{
"root": "src",
...
"stylePreprocessorOptions": {
"includePaths": [
".",
"./stylings"
]
}
}]
}
You can save a few lines in your hello.component.scss
.
// hello.component.scss
@import "variables"; // shorter, don't need styling/ as it's one of the configured paths
@import "stylings2/variables";
h1 {
color: $brand-color;
font-size: $font-size-large;
}
The Angular CLI configuration is applicable to files in node_modules
as well. Let’s say you are using your custom styling npm package, for example bootstrap-sass
module.
npm install bootstrap-sass --save
Here is the folder structure of bootstrap-sass:
- node_modules
- bootstrap-sass
- assets
- stylesheets
- bootstrap
- ...
- _grid.scss
- _variables.scss
Let’s say you would like to use the bootstrap’s _variables.scss
, you can update your .angular.cli.json
file to include bootstrap path,
{
...
"apps": [{
"root": "src",
...
"stylePreprocessorOptions": {
"includePaths": [
".",
"./stylings",
"../node_modules/bootstrap-sass/assets/stylesheets"
]
}
}]
}
Then, in your hello.component.scss
, you can refer to the bootstrap variables file like the following,
// hello.component.scss
@import "variables";
@import "stylings2/variables";
@impoer "bootstrap/variables";
h1 {
color: $brand-color;
font-size: $font-size-large;
font-family: $font-family-serif;
}
Let’s remove the relative path hell (../../../
) with this useful Angular CLI configuration!
That’s it. Happy coding!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Thank you for this information. I have not tried this out yet, but a thought did occur to me while reading the “duplicate name” problem…
If the goal is less code, why not import the duplicates into a single file, and then import the “combined” file into the Components?
For example…
Is there a reason this would not work?
the path should be “.src/styles” or wherever you put the files, but you need to add the src as the folder is in that folder.
can you show all the angular.json?. I did your instruction but it dosen’t work