Sassのimportについて
Sassでコーディングしている時、使い回しできる部分は他のファイルにしておいて、必要なときにimportで呼び出しをすることがあると思います。
しかし、importで呼び出すときに相対パスを使おうとすると下記のような記述になったりするケースがあります。
例:@import ‘../../../../module/sample.scss’;
「../」はいくつ必要だったっけ?と悩んでしまったことはないでしょうか。
本記事では上記のような記述を「@import ‘module/sample.scss’;」と記述できるやり方をご説明します。
結論はこちらです。
結論:gulp-sassのオプションにincludePathsを指定して相対パスの起点を追加する
importの例
今回は下記のようなフォルダ構成を例とします。
scss ├── module │ ├── _module.scss (呼び出し先) ├── page ├── front_page ├── front_page.scss (呼び出し元)
front_page.scssから_module.scssをimportする場合、相対パスを使用すると下記のようになります。
@import ‘../../module/module.scss’;
かなりシンプルなフォルダ構成ですが、相対パスで記述をしますと「../」を2回記述する必要があり、それだけでも少し煩わしい感じがします。
includePathsの使い方
includePathsの使い方を説明していきます。gulpfile.jsの内容を示しますので御覧ください。(ここでは説明のため必要最低限の記述のみしておりますのでご了承ください。)
const path = require('path');
const sass = require('gulp-sass');
var option_sass = {
outputStyle: 'expanded',
includePaths: [path.resolve(__dirname, 'scss')] //パスの指定
};
const cssSass = () => {
return src('./scss/**/*.scss') //コンパイル元
.pipe(sass(option_sass))
.pipe(dest('./css/')) //コンパイル先
}
exports.sass = series(cssSass);
gulp-sassのオプションにパスを指定することによって、相対パスの起点を追加することができます。
これで「/scss/」が相対パスの起点に追加されましたので、どれだけ深い階層からimportする場合でも、「@import ‘module/_module.scss’」とすれば、「@import ‘/scss/module/_module.scss’」と解釈してくれます。
1.記述の仕方
gulp-sass(上記ではrequire後に「sass」としています)のオプションに指定をします。オプションはオブジェクト(連想配列)で指定します。
オブジェクトのキー名を「includePaths」とすることで、パスを指定することができます。
次にオブジェクトの値ですがこれは配列で指定します。従いまして追加したいパスが1つの場合でも、[‘パス名’]と配列で指定をしてください。2つ以上の場合は[‘パス名1’ , ‘パス名2’]と配列の要素を増やしていけばOKです。
パス名は絶対パスで指定します。そのため「__dirname」で現在のディレクトリパスを取得して、「path.resolve」で2つのパスを結合しています。
2.importの記述
パスの追加ですが、「相対パスの起点」の追加となっております。従いましてimportするときは相対パスで記述をします。(baseディレクトリの記述でルートパスを変更するパッケージもありますが、includePathsはそれとは異なりますのでご注意ください。)
@import 'module/module.scss'; → 相対パス指定はOK @import '/module/module.scss'; → ルートパス指定は「/scss/module」でなく「/module」となってしまいNG
パスの優先順位について
パスの追加が「相対パスの起点」なので、むやみにパスを追加するとバッティングするのでは?と思われるかもしれませんが、優先順位がありますのでご安心ください。
- 本来の相対パス
- 追加された相対パス
- 配列のインデックス番号が小さいパス
- 配列のインデックス番号が大きいパス
先程のフォルダ構成が下記ように変更になったとします。front_page.scssから「@import ‘module/module.scss」と指定しますと本来の相対パスが優先されて、front_pageディレクトリの下にあるmoduleディレクトリから「module.scss」がimportされます。
scss ├── module │ ├── _module.scss →importされない ├── page ├── front_page ├── front_page.scss (呼び出し元) ├── module ├── _module.scss →こちらがimportされる
本来の相対パスにファイルが無ければ、追加したパスを起点とした相対パスのファイルを参照しにいきます。
どこにもファイルがない場合はコンパイルエラーになってくれますが、むやみにパスを追加してしまいますと意図しないファイルが読み込まれる可能性もでてきます。パスを追加する時はディレクトリ名を重複しないように管理したほうが無難かと思います。
(参考)PUGのパスについて
参考までにPUGのパスについても記しておきます。PUGもファイルをincludeするときに相対パスを使うと「include ../../module/_module.pug」のようになることがあります。
ただしSassと違ってこちらは相対パスの追加でなく、ルートパスの変更で対応する形となりますのでご注意ください。
フォルダ構成の例とgulpfile.jsは下記の通りです。
pug ├── module │ ├── _module.pug (呼び出し先) ├── page ├── front_page ├── front_page.pug (呼び出し元)
const path = require('path');
const pug = require('gulp-pug');
var option_pug = {
pretty: true,
basedir: path.resolve(__dirname, 'pug'), //ルートパスの指定
};
const htmlPug = () => {
return src('./pug/**/*.pug') //コンパイル元
.pipe(pug(option_pug))
.pipe(dest('./')) //コンパイル先
}
exports.pug = series(htmlPug);
これでルートパスが変更となりましたので、「include /module/_module.pug」と指定することができます。ただし元のルートパス「include /pug/module/_module.pug」で指定しますとエラーになりますのでご注意ください。相対パスはそのまま使用できます。
SassのincludePathsと異なる点は下記の通りです。
- オプションに指定するオブジェクトのキー名が「basedir」となる
- オブジェクトの値は配列ではなく文字列となる。
- includeの指定はルートパスで指定する。 「include /module/_module.pug」
まとめ
Gulp-Sassにおけるimportのパス追加のやり方についてまとめてみました。
Gulp-sassのオプションにincludePathsを設定するだけでimportの記述が楽になると思いますので、ぜひ試してみてください。