Reputation: 1830
Angular.json snippet:
"root": "",
"sourceRoot": "src",
"prefix": "ra",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/assets",
"src/favicon.ico",
],
"styles": [
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["assets/scss"]
},
}
New to Angular and I think I have an easy problem but just don't understand the inner workings of how scss is compiled. I'm importing some scss in my root styles.scss component. Here's what's in the styles.scss:
@import './assets/scss/global';
Here's what's in the _global.scss:
@import './variables';
And here's the contents of that file:
$spacer-4: 0.25em; //4px
$spacer-6: 0.375em; //6px
$spacer-8: 0.5em; //8px
$spacer-10: 0.625em; //10px
$spacer-12: 0.75em; //12px
$spacer-16: 1em; //16px
$spacer-20: 1.25em; //20px
$spacer-24: 1.5em; //24px
$spacer-30: 1.875em; //30px
$spacer-32: 2em; //32px
$spacer-36: 2.25em; //36px
The problem is within a component's scss file that references one of the variables. The error is thrown from the component:
ERROR in ./src/navigation/app-navigation/app-navigation.component.scss
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
margin-top: $spacer-10;
^
Undefined variable.
If I'm not getting a compile time error that the file isn't found then I shouldn't be seeing this error, right?
Here's the file structure of the app:
-- src
-- app
-- navigation
--app-navigation
-- app-navigation.component.scss
-- assets
-- scss
-- _global.scss
-- _variables.scss
-- styles.scss
Upvotes: 0
Views: 3068
Reputation: 23290
Your problem is the order of inception. Your default styles.scss is the last in line in the order so your component doesn't have a reference to your variables/globals when it's inferred.
To fix it you just add an import reference to the component itself so it can receive those vars when it's needed. Which makes a good case for applying some presentation layer architecture rules to your uses. Such as with variables, I would suggest keeping it a file with ONLY vars since they will not transpile and then you can reference it where those vars are needed and not have any duplicated CSS as you would if you had any actual CSS in the globals file in the compiled assets.
I suggest if you haven't already add the stylePreprocessorOptions
to your build configuration in angular.json with a fixed ref path to your directory that holds files like global so you don't have to make absolute paths each time you use it (don't forget to also add the declaration to your "serve" configuration in angular.json) like;
"stylePreprocessorOptions": {
"includePaths": [
"assets/sass/"
]
},
Then in say your component scss file you only add @import 'variables'
and it will provide the var values as necessary. Alternatively you could do the whole path but that can make maintenance a pain but will work just make sure your path is correct @import '../../variables';
and with that in your component scss it will provide the vars also but I strongly recommend setting up the import paths in angular.json.
Hope this helps, cheers!
Upvotes: 3