こんにちはのせっち@nosecchi01です
Gulpを使ってSassのコンパイルをしていると、ついでにminifyしたいと考えるものです。
minify:JavaScriptやCSSなどの不要な改行、インデントを削除し、圧縮・軽量化すること。
また、minifyする際は下記のようだと便利です。
- 圧縮前のstyle.css、圧縮後のstyle.min.css両方が生成される。
- style.min.cssにもソースマップが付く
ソースマップ(sourcemaps)とは、デベロッパーツールで見たときに、cssではなくscssの該当行を教えてくれる機能です。
1に関しては、多分style.min.css
だけあれば事足りるはずなのですが、両方生成しているケースをよく見るので解説します。
2に関しては、style.min.css
の場所を教えられても圧縮されていて見にくいし、編集するのはscssファイルなので是非付けておきたいです。
最低限のGulpの知識はあるものとして進めます。
Gulpの知識が全く無い人は下記をどうぞ!
また、僕の全ての知識を集約したnoteを執筆していますのでもしよければどうぞ!
(絶対挫折しない設計にしており、好評ですのでレビューだけでも覗いてみてください!)
cssnanoをインストール
minifyにはcssnanoを使います。minify系のツールは他にもありますが、ドキュメントがしっかりしてそうなのでこちらを選びました。
cssnanoはかなり長いこと更新が止まっているので、不安な方は別のパッケージを選択してください。基本設定は大体同じです!
早速インストールしていきます。
npm i -D gulp postcss gulp-postcss cssnano gulp-rename
npm i -D
の後ろにパッケージ名を続けて書くことで一気にインストールできます。gulp
はインストールしてあれば省いてください。cssnano
を使うにはgulp-postcss
が必要で、gulp-postcss
を使うには、postcss
が必要です。css
をmin.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.css
とstyle.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
を使えばいいでしょうか?
series
の役割はタスクの順次実行なのでよさそうに思えます。
const { src, dest, series } = require("gulp"); // seriesを追加
// 省略
module.exports = {
sass: compileSass,
minify: minifyCss,
build: series(compileSass, minifyCss) // buildを追加
};
series
を使って、compileSass
、minifyCss
を順番に実行してもらうように指定しました。
では、タスクを実行してみます。
(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を連続実行する際は
series
とendイベント
を使う。