Within an Angular application, I do D3 visuals through either plain D3 or Vega. There's also SCSS styling going on.
I'd like to be able to refer to the same global variables for styling from Javascript and from SCSS. JSON files do the trick very well for storing settings that I load into Typescript through a simple import
statement. But how does one go about doing the same from SCSS ?
node-sass-json-importer
seems like a good candidate but adding it to an Angular 9 CLI application isn't obvious to me.
This StackOverflow post brushed on the topic a while back, but it involved modifying resources under node_modules
which is hardly sustainable.
There are also some inputs in the orginal doc as to how one can go about tweaking webpack in a non-Angular app. I do not know how to relate this to an Angular app built through the CLI.
Webpack / sass-loader Blockquote
Webpack v1
import jsonImporter from 'node-sass-json-importer';
// Webpack config
export default {
module: {
loaders: [{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}],
},
// Apply the JSON importer via sass-loader's options.
sassLoader: {
importer: jsonImporter()
}
};
Webpack v2
import jsonImporter from 'node-sass-json-importer';
// Webpack config
export default {
module: {
rules: [
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
},
},
{
loader: 'sass-loader',
// Apply the JSON importer via sass-loader's options.
options: {
importer: jsonImporter(),
},
},
],
],
},
};
You can do it without changing any node_modules
files by using @angular-builders/custom-webpack
to setup custom Webpack rules and as you mention node-sass-json-importer
to import JSON files inside SCSS files.
You'll have to install node-sass
for the implementation
option because node-sass-json-importer
is compatible with node-sass
.
Install packages @angular-builders/custom-webpack
, node-sass-json-importer
and node-sass
:
npm i -D @angular-builders/custom-webpack node-sass-json-importer node-sass
Create Webpack config file (webpack.config.js
) to the project root directory with the following contents:
const jsonImporter = require('node-sass-json-importer');
module.exports = {
module: {
rules: [{
test: /\.scss$|\.sass$/,
use: [
{
loader: require.resolve('sass-loader'),
options: {
implementation: require('node-sass'),
sassOptions: {
// bootstrap-sass requires a minimum precision of 8
precision: 8,
importer: jsonImporter(),
outputStyle: 'expanded'
}
},
}
],
}],
},
}
Change builder
to @angular-builders/custom-webpack:[architect-target]
and add customWebpackConfig
option to build
, serve
and test
build targets inside angular.json
:
"projects": {
...
"[project]": {
...
"architect": {
"build": {
"builder: "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "webpack.config.js"
},
...
},
...
},
"serve": {
"builder: "@angular-builders/custom-webpack:dev-server",
"customWebpackConfig": {
"path": "webpack.config.js"
},
...
},
"test": {
"builder: "@angular-builders/custom-webpack:karma",
"customWebpackConfig": {
"path": "webpack.config.js"
},
...
},
},
...
},
...
}
Now you can include any .json
file inside any component .scss
file:
hello-world.component.scss
:@import 'hello-world.vars.json';
.hello-bg {
padding: 20px;
background-color: $bg-color;
border: 2px solid $border-color;
}
hello-world.vars.json
:{
"bg-color": "yellow",
"border-color": "red"
}
I have created a Github repository with all these working that you can clone and test from here: https://github.com/clytras/angular-json-scss
git clone https://github.com/clytras/angular-json-scss.git
cd angular-json-scss
npm install
ng serve
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With