【Gulp】minifyでcssとmin.cssを両方生成して、ソースマップも作る方法

こんにちはのせっち@nosecchi01です

Gulpを使ってSassのコンパイルをしていると、ついでにminifyしたいと考えるものです。

minify:JavaScriptやCSSなどの不要な改行、インデントを削除し、圧縮・軽量化すること。

また、minifyする際は下記のようだと便利です。

  1. 圧縮前のstyle.css、圧縮後のstyle.min.css両方が生成される。
  2. style.min.cssにもソースマップが付く

ソースマップ(sourcemaps)とは、デベロッパーツールで見たときに、cssではなくscssの該当行を教えてくれる機能です。

1に関しては、多分style.min.cssだけあれば事足りるはずなのですが、両方生成しているケースをよく見るので解説します。

2に関しては、style.min.cssの場所を教えられても圧縮されていて見にくいし、編集するのはscssファイルなので是非付けておきたいです。

最低限のGulpの知識はあるものとして進めます。

Gulpの知識が全く無い人は下記をどうぞ!

また、僕の全ての知識を集約したnoteを執筆していますのでもしよければどうぞ!
(絶対挫折しない設計にしており、好評ですのでレビューだけでも覗いてみてください!)

cssnanoをインストール

minifyにはcssnanoを使います。minify系のツールは他にもありますが、ドキュメントがしっかりしてそうなのでこちらを選びました。

cssnanoの公式ページ

cssnanoはかなり長いこと更新が止まっているので、不安な方は別のパッケージを選択してください。基本設定は大体同じです!

早速インストールしていきます。

npm i -D gulp postcss gulp-postcss cssnano gulp-rename
  • npm i -Dの後ろにパッケージ名を続けて書くことで一気にインストールできます。
  • gulpはインストールしてあれば省いてください。
  • cssnanoを使うにはgulp-postcssが必要で、gulp-postcssを使うには、postcssが必要です。
  • cssmin.cssに変更するためにgulp-renameを使います。
  • sourcemapsはGulp4でデフォルト実装になったのでgulp-sourcemapsは不要です。

gulpfile.jsの編集

const { src, dest } = require("gulp");
const postcss = require("gulp-postcss");
const cssnano = require("cssnano");
const rename = require("gulp-rename");

const minifyCss = (done) => {
  src(["./dist/css/**.css", "!./dist/css/**.min.css"], { sourcemaps: true })
    .pipe(postcss(cssnano))
    .pipe(
      rename({
        suffix: ".min",
      })
    )
    .pipe(dest("./dist/css", { sourcemaps: "sourcemaps" }));

  done();
};

module.exports = {
  minify: minifyCss
};

dist/cssディレクトリ内に**.css(style.cssなど)がある前提です。

こちらが用意できたら、下記を実行します。

npx gulp minify

これでminifyが実行され、**.min.css(style.min.cssなど)ができます。

gulpfile.jsの解説

書いてある通りなのですが、ポイントだけ補足します。

const minifyCss = (done) => {
  src(["./dist/css/**.css", "!./dist/css/**.min.css"], { sourcemaps: true })
    .pipe(postcss(cssnano))
    // 省略
    .pipe(dest("./dist/css", { sourcemaps: "sourcemaps" }));

  done();
};

srcで元ファイルを指定です。("./dist/css/**.css"を指定。)
sassからコンパイル後のcssファイルがdistフォルダに入っている想定です。

""!./dist/css/**.min.css"を書いておかないと、タスクを実行するたびに、style.min.min.cssというように無限に増えていくので、!を付けてminが付いたファイルは除外します。

おまけ:scssから一気にminifyまでする際の注意点

今回はstyle.cssstyle.min.cssを両方生成する約束なので、scssコンパイルと、minifyで別々のタスクを組みます。

この場合、scssからcssへのコンパイル → cssのminifyを順番に行う必要があります。

gulpfile.jsは下記のようになっているはずです。

const { src, dest } = require("gulp");
const sass = require("gulp-sass")(require("sass"));
const postcss = require("gulp-postcss");
const cssnano = require("cssnano");
const rename = require("gulp-rename");

// scssコンパイル(解説外なので最低限の記述)
const compileSass = (done) => {
  src("./src/scss/**/*.scss")
    .pipe(sass())
    .pipe(dest("./dist/css"));
  done();
};

// minify
const minifyCss = (done) => {
  src(["./dist/css/**.css", "!./dist/css/**.min.css"], { sourcemaps: true })
    .pipe(postcss(cssnano))
    .pipe(
      rename({
        suffix: ".min",
      })
    )
    .pipe(dest("./dist/css", { sourcemaps: "sourcemaps" }));

  done();
};

module.exports = {
  sass: compileSass,
  minify: minifyCss
};

このタスクを順番通りに、連続で行うにはどうすればいいでしょうか?

seriesを使う?(不十分です)

Gulpに標準実装されているseriesを使えばいいでしょうか?

gulpjs.comよりseriesに関する記述

seriesの役割はタスクの順次実行なのでよさそうに思えます。

const { src, dest, series } = require("gulp"); // seriesを追加

// 省略

module.exports = {
  sass: compileSass,
  minify: minifyCss,
  build: series(compileSass, minifyCss) // buildを追加
};

seriesを使って、compileSassminifyCssを順番に実行してもらうように指定しました。

では、タスクを実行してみます。
(dist/css内は一旦削除してください)

npx gulp build

上記を実行すると、style.cssはできるけど、style.min.cssはできません。

seriesというのは、実行順は指定できるのですが、前のタスクが終了するまで待ってはくれません。

style.cssがないと、style.min.cssは作れないので、scssのコンパイルが終わるまでminifyの実行開始は待っておていもらわないと困りますね。

惜しいです。

endイベントを使う

タスクの終了まで次の処理を行わないようにするにはendイベントを使ってあげます。

const { src, dest, series } = require("gulp");  // seriesを追加
// 省略

const compileSass = (done) => {
  src("./src/scss/**/*.scss", { sourcemaps: true })
    .pipe(sass())
    .pipe(dest("./dist/css", { sourcemaps: "sourcemaps" })) // ←セミコロン消す
    .on("end", done); // 追加
};

// 省略

module.exports = {
  sass: compileSass,
  minify: minifyCss,
  build: series(compileSass, minifyCss) // buildを追加
};

これでタスクを実行してあげます。

npx gulp build

compileSassにendイベントを書いたことで、compileSassの処理が終わるまで次の処理の開始を待ってくれるようになりました!

これで、sassのコンパイル → minifyを順番通り、連続で行ってもらうことができます!

まとめ

  • cssのminifyを簡単に行うことができる。
  • ソースマップも付けることもできる。
  • scssのコンパイルと、cssのminifyを連続実行する際はseriesendイベントを使う。

この記事を書いた人

のせっち

福岡県出身。早稲田大学卒。創業100年の鉄鋼商社でバンコク駐在最年少抜擢。毎日擦り切れるまで働かなくても幸せに生きている人々を見てフリーランスになりました。
- WordPressが得意!
- 初心者向けGulp教材は購入者100部以上!