テンプレートに含まれるSCSSに対してカスタマイズの余地を作りたい場合に、変数定義のファイルを直接編集しても良いが、出来るだけ簡単にプログラムから変数を上書きしたいことがある。
そのような場合にはSCSSの@importを使えばグローバル変数を書き換えるのはそれほど難しくないが、@importは将来的に廃止される可能性があるため@useで同様のことができないか試してみた。
dart-sassパッケージの文字列からSCSSを生成するAPIを使うことで自由にグローバル変数を変更できる程の自由度はないものの実用上問題ないレベルで実現可能と言える。
ポイントは既存のSCSSファイルを@useするSCSSを新たに生成し、withブロックで変数を上書きしてしまうことである。
ソフトウェア | バージョン |
---|---|
macOS | 10.15.7 |
node.js | 14.14.13 |
TypeScript | 4.1.3 |
sass(dart-sass) | 1.30.0 |
variables.scss
// 変更可能な変数には !defaultを付ける
$width: 0 !default;
$height: 0 !default;
sub_style_1.scss
@use 'variables' as v;
div.a {
background-color: red;
width: v.$width;
height: v.$height;
}
sub_style_2.scss
@use 'variables' as v;
div.b {
background-color:green;
width: v.$width;
height: v.$height;
}
トップになるSCSSファイルでは、変数ファイルを先頭に全てのSCSSファイルを@forwardする。
style.scss
@forward "variables";
@forward "sub_style_1";
@forward "sub_style_2";
上記のSCSSファイルを用意した上で、以下のTypeScriptを実行すると
index.ts
import * as fs from 'fs';
const sass = require('sass');
const result = sass.renderSync({
data: "@use 'style.scss' with ($width: 200px, $height:300px);",
outputStyle: 'expanded',
outFile: 'style.css'
});
fs.writeFileSync("style.css",result.css);
次のCSSファイルが生成される
style.css
div.a {
background-color: red;
width: 200;
height: 300;
}
div.b {
background-color: green;
width: 200;
height: 300;
}
dart-sassで生成する文字列中の変数を変更すれば、renderSyncで生成されるCSSの内容も変化することが確認できた。