葉っぱのメモ帳

フリーランスなフロントエンドエンジニアの備忘録

【Windows】GulpでDartSassのコンパイル【実践編2022】

2022.08.13

前回、Gulpを導入してDartSassをコンパイルするところまでやってみました。

前回はただコンパイルをしただけですので、ここに色々とプラグインを足してSassのコンパイルを便利にする+watchを使ってファイルに変更があれば自動でコンパイルができるようにしていきたいと思います。

前回のおさらい

gulpでSassをコンパイルするためのプロジェクトフォルダをVS Codeで開き、ターミナルを表示させておきます。
今回もこのターミナルで必要なプラグインを足していきます。

Dart Sass おすすめプラグインと設定

gulp-sass-glob-use-forward

glob機能を使って@useや@forwardを省略する(まとめる?)プラグイン。

npm install --save-dev gulp-sass-glob-use-forward

gulp-autoprefixer

ベンダープレフィックスを自動で付けてくれるプラグイン。

npm install --save-dev gulp-autoprefixer

gulp-plumber

watch時にエラーが出ても止まらないようにするためのプラグイン。

npm install --save-dev gulp-plumber

gulp-group-css-media-queries

バラバラに書かれたメディアクエリをまとめてくれるプラグイン。

npm install --save-dev gulp-group-css-media-queries

sourcemaps

ソースマップを作ってくれるプラグイン。

npm install --save-dev gulp-sourcemaps

すべて –save-debv でローカルにインストールします。

gulpfile.jsを編集する

前回作ったgulpfile.jsを編集していきます。

// ----------------------------------------------------------------------
"use strict";

// モジュール読み込み
//----------------------------------------------------------------------
/* gulp */
const gulp = require('gulp');
const { src, dest, watch, series, parallel } = require('gulp');

/* sass */
const gulpDartSass  = require('gulp-dart-sass');
const sassGlob      = require('gulp-sass-glob-use-forward');
const autoprefixer  = require('gulp-autoprefixer');
const plumber       = require('gulp-plumber');
const gcmq          = require('gulp-group-css-media-queries');
const sourcemaps    = require('gulp-sourcemaps');

// タスク定義
//----------------------------------------------------------------------
const sass = () => {
  return gulp
    .src('src/sass/**/*.scss')
    // 強制停止を防止
    .pipe(plumber({
      errorHandler: function (err) {
        console.log(err.messageFormatted);
        this.emit('end');
      }
    }))
    // ソースマップを初期化
    .pipe(sourcemaps.init())
    // glob
    .pipe(sassGlob())
    // scssをコンパイル
    .pipe(gulpDartSass({
      includePaths: ['src/sass'],
      outputStyle: 'expanded'
    }))
    // ベンダープレフィックスを付ける
    .pipe(autoprefixer({cascade: false,}))
    // メディアクエリをまとめる
    .pipe(gcmq())
    // ソースマップを出力する
    .pipe(sourcemaps.write('./'))
    // できあがったcssを書き出す
    .pipe(gulp.dest('dist/css'))
}

// タスクの実行
//----------------------------------------------------------------------
exports.sass = sass

前回作ったものと比べても、出力までに処理する内容が足されただけなので、行数は増えたように見えて実はそんなに難しくありません。

gulp-plumber

この段階でまだwatchを実装していないのでplumberはまだ活躍できないですのですが、後ほどwatchを実装するので先に入れておきました。
watch時にエラーが起こるとターミナルの方にエラーの内容が表示されます。

gulp-dart-sass

includePaths: ['src/sass']と入れることでパスを通しています。

package.jsonに対応ブラウザの記述をする

autoprefixerなどの対応ブラウザの範囲をpackage.jsonの方にします。
package.jsonは前回の記事の方で最初に作ったファイルですね。プロジェクトフォルダの中にあります。

"browserslist": [
  "last 2 versions",
  "ie >= 11",
  "Android >= 4"
]

こちらをpackage.jsonに追加します。
書き方は色々あるかと思いますが、私は今はこんな感じです…という例です。ieはもうアレなんですが一応ね…。
どこに追加するか分からん…となると大変なので一応現時点の全体も載せておきます。

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-autoprefixer": "^8.0.0",
    "gulp-dart-sass": "^1.0.2",
    "gulp-group-css-media-queries": "^1.2.2",
    "gulp-plumber": "^1.2.1",
    "gulp-sass-glob-use-forward": "^0.1.3",
    "gulp-sourcemaps": "^3.0.0"
  },
  "browserslist": [
    "last 2 versions",
    "ie >= 11",
    "Android >= 4"
  ]
}

記事通りに進めて行けばこんな感じです。
devDependenciesという項目内に追加したプラグインがたくさん増えているのが分かるかと思います。
その項目の下にbrowserslistを追加します。devDependenciesの閉じのところにカンマを入れるのをお忘れなく!

}, ←これね。

Sassをコンパイルしてみる

scssファイルを作成

前回同様srcフォルダの中にsassフォルダを作ってその中にscssファイルが入っている状態です。

今回もscssの構成についてはちょっと省略させていただいて、style.scssのみに実験的にsassを書いていきます。

@charset "UTF-8";

/* ボタン
-------------------------------------- */
.c-button {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 200px;
  height: 50px;
  color: #fff;
  background: #000;
  border: 1px solid #000;
  border-radius: 10px;
  &:hover {
    background: #fff;
    color: #000
  }
  @media screen and (max-width: 767px) {
    width: 160px;
    height: 40px;
  }
}

.c-button--big {
  width: 300px;
  height: 60px;
  font-size: 1.2em;
  @media screen and (max-width: 767px) {
    width: 200px;
    height: 50px;
  }
}

classが2つ、ベンダープレフィックスが必要なflexを使ってみたり、メディアクエリをそれぞれに記載してみたりしました。こちらを保存して、前回と同じコマンドをターミナルに打ちます。

npx gulp sass

dist/cssフォルダにstyle.cssとstyle.mapが作成され、出力されたstyle.cssの中身はこうなりました。

@charset "UTF-8";

/* ボタン
-------------------------------------- */

.c-button {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  width: 200px;
  height: 50px;
  color: #fff;
  background: #000;
  border: 1px solid #000;
  border-radius: 10px;
}

.c-button:hover {
  background: #fff;
  color: #000;
}

.c-button--big {
  width: 300px;
  height: 60px;
  font-size: 1.2em;
}

@media screen and (max-width: 767px) {
  .c-button {
    width: 160px;
    height: 40px;
  }

  .c-button--big {
    width: 200px;
    height: 50px;
  }
}
/*# sourceMappingURL=style.css.map */

ベンダープレフィックスが付いている、メディアクエリがまとめられているのが分かるかと思います。
これでSassの構築環境ができました!

Watch機能でファイルを監視しよう

このままでは、保存しただけでcssへのコンパイルは行われず、コンパイルしたいタイミングでnpxのコマンドを打つ必要があります。ちょっとそれはめんどくさい。保存されたらcssになって欲しい。というときに出てくるのがwatchです。

Watchのタスク定義と実行

// ----------------------------------------------------------------------
"use strict";

// モジュール読み込み
//----------------------------------------------------------------------
/* gulp */
const gulp = require('gulp');
const { src, dest, watch, series, parallel } = require('gulp');

/* sass */
const gulpDartSass  = require('gulp-dart-sass');
const sassGlob      = require('gulp-sass-glob-use-forward');
const autoprefixer  = require('gulp-autoprefixer');
const plumber       = require('gulp-plumber');
const gcmq          = require('gulp-group-css-media-queries');
const sourcemaps    = require('gulp-sourcemaps');

// タスク定義
//----------------------------------------------------------------------
const sass = () => {
  return gulp
    .src('src/sass/**/*.scss')
    // 強制停止を防止
    .pipe(plumber({
      errorHandler: function (err) {
        console.log(err.messageFormatted);
        this.emit('end');
      }
    }))
    // ソースマップを初期化
    .pipe(sourcemaps.init())
    // glob
    .pipe(sassGlob())
    // scssをコンパイル
    .pipe(gulpDartSass({
      includePaths: ['src/sass'],
      outputStyle:'expanded',
    }))
    // ベンダープレフィックスを付ける
    .pipe(autoprefixer({cascade: false,}))
    // メディアクエリをまとめる
    .pipe(gcmq())

    // ソースマップを出力する
    .pipe(sourcemaps.write('./'))
    // できあがったcssを書き出す
    .pipe(gulp.dest('dist/css'))
}

//  Watch
//----------------------------------------------------------------------
const watchFiles = () => {
  gulp.watch('./src/sass/**/*.scss', sass);
}

// タスクの実行
//----------------------------------------------------------------------
exports.sass = sass;
exports.watch = watchFiles;
gulp.watch('./src/sass/**/*.scss', sass);

というところでwatchFilesで監視対象のファイル、そしてそれが変更されたときに実行されるタスクを指定しています。

タスクの実行の所にwatchというコマンドを追加したのでターミナルで

npx gulp watch

と実行してみると次のような表示になるはずです。

[23:59:26] Using gulpfile ~\Desktop\test\gulpfile.js
[23:59:26] Starting 'watch'...

これでscssの監視が始まりました。
先ほどのstyle.scssに何か変更を加えて保存をすると

[00:00:42] Starting 'sass'...
[00:00:42] Finished 'sass' after 285 ms


と出て、style.cssの内容が変わっているはずです。
これでwatchもできました!

コンパイル時にエラーが出た場合

さきほどのstyle.scssにわざと宣言していない変数を入れてみました。

src\sass\style.scss
Error: Undefined variable.
  ╷
9 │   width: $hoge;
  │          ^^^^^
  ╵
  src\sass\style.scss 9:10  root stylesheet
[00:15:55] Finished 'sass' after 174 ms

このようにどこでエラーが出たのかターミナルに出力されましたが、watchは止まっていません。先ほどインストールしたgulp-plumberがうまく動作していることの確認もできました。

watchを終了させたい場合

watchを終了させたいときはターミナルにCtrl+Cバッチ ジョブを終了しますか (Y/N)? と出るので 、「y」を入力して終了です。

Gulpのデフォルトにwatchを指定する

今まではnpx gulp sassnpx gulp watchなど、自分でタスクを指定して実行してきました。これをnpx gulpというコマンドを実行した時、watchが実行されるようにします。

先ほどのgulpfile.jsに追加したexports.watch = watchFiles;という部分を変更します。

// default
//----------------------------------------------------------------------
exports.default = watchFiles;

デフォルトにwatchFilesのタスクを指定しました。これで

npx gulp

と入力するだけでwatchが始まり、scssの変更があれば自動でなんやかんしてcssへ出力してくれるようになりました!
お疲れ様でした!!

まとめ

今回も長くなってしましました…。その割に大雑把だなぁと思うなど。今回このお盆期間中にgulpgfile.jsの内容の確認がしたいなぁと思って始めたのですが、いい復習になっています。
あと1回…次回はブラウザシンクに行きたいです。ファイル更新したらブラウザもリロードしてくれるというやつです。お盆期間中も若干仕事があるので果たしてブログを書けるのか??

今回も読んでいただきありがとうございました!

参考にさせていただきました

サポートよろしくお願いします

この記事を気に入って下さった方、応援してもいいという方、サポートしていただけると嬉しいです。

Amazonほしいものリスト Amazonギフト券をメールで送る

※受取人のEメールアドレスに とご入力ください。
※上記のアドレスはギフト受け取り専用です。

書いた人

トップへ