経緯
Scss で @import
, @use
, @forward
のような他のファイルを読み込む機能は、 @ディレクティブ 内では使用できないません。そのため、例えば以下のようなことができません。
$flag: true;
@if ($flag) {
@use "parts1.scss";
}
あるフラグ変数(ここでは $flag
ですが、実際はファイル中ではなく Gulp タスク内で管理)が true
のときのみ parts1.scss
を読み込む。
$flag: true;
@if ($flag) {
@use "parts1.scss";
}
@else {
@use "parts2.scss";
}
あるいは、フラグ変数の値によって読み込む Scss ファイルを切り替える。
この部分について、どうにかできないか(本当にやりたいのは最初の例ですが、代替案として2つ目の例でブランクの parts2.scss
をダミーとして用意する方法を考える)、と。
対処
色々検索した結果、 gulp-sass
の includePaths
オプションを使えばそれらしいことができそうだ、ということが分かりました。
今回はたまたま自分も gulp-sass
を使用している前提で、しかも Scss 本体の変数ではなく Gulp タスク内で管理しているフラグによって、というのが希望だったのでこの形はぴったりでした (この方法でなければ、上記スレの上の方にあるように、フラグをいったん Scss ファイルに変数として出力し、それを読み込むことで伝播させようと考えていました)。
const { src, dest } = require('gulp');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const sass = require('gulp-sass');
sass.compiler = require('sass');
const Fiber = require('fibers');
const autoprefixer = require('gulp-autoprefixer');
// dynamic import test
const flag = true;
// scssコンパイルタスク
const scss = () => {
let opt = {
fiber: Fiber,
outputStyle: 'compressed'
};
// dynamic import test
if (flag) {
opt.includePaths = [
`src/scss/parts/enable`
]
}
else {
opt.includePaths = [
`src/scss/parts/disable`
]
}
return src('src/scss/**/*.scss')
.pipe(plumber({
errorHandler: notify.onError({
message: 'Error: <%= error.message %>',
title: 'scss'
})
}))
.pipe(sass(opt).on('error', sass.logError))
.pipe(autoprefixer({
cascade: false
}))
.pipe(dest('dist/css'));
};
module.exports = scss;
Scss のコンパイルタスクはこのような感じで。
src/
└ scss/
├ .scssファイル やディレクトリ
├ import/
│ └ _index.scss
│
└ parts/
├ disable/
│ └ parts_hoge.scss
└ enable/
└ parts_hoge.scss
このようなディレクトリ構造で、 src/scss/import/_index.scss
から src/scss/parts
の中のenable
または disable
のどちらかの parts_hoge.scss
を読み込む、とした場合。
// dynamic import test
@use "parts_hoge";
src/scss/import/_index.scss
の記述はこれだけですが、 Scss のコンパイルタスクに記述されている変数 flag
によって読み込む元のディレクトリの候補が src/scss/parts/enable
または src/scss/parts/disable
のどちらかに切り替わる、ということです。
あとは src/scss/parts/disable/parts_hoge.scss
は中身のないブランクのファイルにしておけば、 flag
が true
の場合のみ css が当たる、ということになります。
出力される css の切り分けはできたので、とりあえずはこの方法でしょうかね。