Gulpを使ってみたいけど使い方がよく分からない
本記事では、Gulpを使ってWeb制作を効率的に行う方法について解説します。
本記事の信頼性
30歳から異業種への転職をして、Shopify Experts企業で1年半ほどフルリモートで勤務していました。
現在は名古屋の自社開発企業のフロントエンドエンジニアしています。フリーランスとしても活動しています。
環境構築を行う
Node.jsをインストールするための準備
Gulpを使用するために、Node.js
が必要となります。
こちらからインストールしてください。
バージョンは推奨版の方をご使用ください。
ターミナルで確認します。
$ node -v
v19.0.1
これで下準備は完了です。
では、プロジェクトを作成します。今回はtestというフォルダを作成しました。
VSCodeでtestフォルダを開いてターミナルを開きます。command + j のショートカットで開くことができます。
次にターミナルに下記を入力します。
npm init -y
package.json
が作られました。
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
特に書き換える必要はないのでそのままで大丈夫です!
次に、 Gulpをインストールしていきます。
npm install --save-dev gulp
このコマンドを叩くと、node_modules
フォルダとpackage-lock.json
が作成されます。
node_modules
フォルダには、先程インストールしたGulpのパッケージが格納されています。
また、Gulpを動作させるのに必要な他のパッケージも合わせてインストールされます。
この状態になっていればOKです。
package-lock.jsonについて詳しく知りたい人はこちらどうぞ。
Gulpをつかってみる
Gulpの挙動を確認しよう!
まずは、Gulpの基本的に挙動を確認します。
gulpfile.js
を作成して、下記を記述します。
const helloGulp = (done) => {
console.log("Hello Gulp!!");
done();
};
exports.test = helloGulp;
helloGulpというタスクを登録するためには、exportsを使用します。
npx gulp test
とコマンドを入力して、Hello Gulp!!と表示されればOKです。
$ npx gulp test ✘ 130
[14:34:58] Using gulpfile ~/Local Sites/wordpressdevtemplate/app/public/wp-content/themes/wordpress-dev-template/dev/gulpfile.js
[14:34:58] Starting 'test'...
Heelo!!
[14:34:58] Finished 'test' after 726 μs
参考: Creating Tasks
GulpでSassをコンパイルしよう!
Sassを使用するためには、パッケージをインストールする必要があります。
npm install --save-dev gulp-sass sass
package.jsonも確認しておきます。
{
// 省略 ,
"devDependencies": {
"gulp": "^4.0.2",
// 追加されたパッケージ
"gulp-sass": "^5.1.0",
"sass": "^1.57.1"
}
}
では、gulpfile.js
に記述を追加していきます。
const { src, dest } = require("gulp");
const sass = require("gulp-sass")(require("sass"));
const compileSass = (done) => {
src("./src/scss/style.scss")
.pipe(sass())
.pipe(dest("./assets/css"));
done();
};
exports.compileSass = compileSass;
それではコードを見ていきます。
const { src, dest } = require("gulp");
const sass = require("gulp-sass")(require("sass"));
v3までは const gulp = require('gulp);'
と定義していたようですが、v4からは機能ごとに呼び出しておくようです。
sassの定義では、require("gulp-sass")(require("sass"));
と記述します。
参考: https://www.npmjs.com/package/gulp-sass
const compileSass = (done) => {
src("./src/scss/style.scss")
.pipe(sass())
.pipe(dest("./assets/css"));
done();
};
comipleSass関数を作成して、srcの部分にはstyle.scssのパスを記述します。.pipe(sass())でscssファイルからcssファイルにコンパイルする処理が行われて、destの部分でどこに出力するのかを明示しています。
上記の記述をした場合には下記のようなディレクトリ構成になります。
project
├ assets
│ └ css
│ └ style.css
└ src
└ scss
└ style.scss
また、引数にdoneがありますが、function内の処理でdone();が実行されています。
これは、callbackといってタスクの終了を示しています。
done()が呼ばれた時点でこのタスクは終了となります。
ちなみに、done()を実行しないとエラーが出力されるので試してみてください^^
それでは、解説はこれぐらいにして実際にコードを書いてみて、コンパイルされるのかを確認してみます。
<h1 class="c-title">This is Test for Gulp!!</h1>
.c-title {
color: red;
&:hover {
color: blue;
}
}
コマンドを叩いて確認します。
npx gulp compileSass
style.css
を確認すると。
.c-title {
color: red;
}
.c-title:hover {
color: blue;
}
良さそうです。ブラウザも確認します。
テキストにhoverすると色が変わるようになってますね!
Sassの醍醐味の分割はもう使えるのかな?
少しSassを勉強したことある人なら分かると思うのですが、Sassではファイルを分割して最終的に1つのstyle.css
に出力することができます。
1つのstyle.scss
に記述していくよりも管理が楽になるのでファイル分割で管理はするようにしたほうがいいと思います。
ここでも簡単なファイル分割を試してみます。
まずは下記のようなフォルダ構成を作ってみます。
scssフォルダ直下のstyle.scss
には下記を記述します。
@use "components";
componentsフォルダ直下のstyle.scssには下記を記述します。
@use "c-title";
@use "c-button";
合わせて作成した_c-title.scss
と_c-button.scss
をします。
.c-title {
color: red;
&:hover {
color: blue;
}
}
.c-button {
display: inline-block;
padding: 20px 50px;
background-color: #1c273e;
color: #efeeea;
}
コンパイルします。
npx gulp compileSass
出力されたのはstyle.cssのみで中身を確認すると別々のscssファイルが記述が1つにまとめられています。
.c-title {
color: red;
}
.c-title:hover {
color: blue;
}
.c-button {
display: inline-block;
padding: 20px 50px;
background-color: #1c273e;
color: #efeeea;
}
@use
とかファイルの分割方法だとか別途記事をあげようと思っています。
ここではGulpでできることに焦点をおいていますので割愛します。
Sassを便利にしよう!
ここからは更にSassを便利にするためのタスクをgulpfile.jsに追加していきます。
ソースマップを作成する
ソースマップを追加しておくことで、対象のクラスのscssファイルを教えてくれます。開発中にstyle.cssファイルを見ることはないのでこれは開発を非常に楽にしてくれるのでぜひ追加しておいてください。下記のように記述を追加すればOKです。
srcの第2引数とdestの第2引数に追加しています。
const compileSass = (done) => {
return gulp
.src("./src/scss/style.scss", { sourcemaps: true })
.pipe(sass())
.pipe(gulp.dest("./assets/css", { sourcemaps: "./sourcemaps" }));
};
出力されたあとのファイルには、sourcemapsフォルダの中にstyle.css.map
があるのが確認できます。
コンパイルされたメディアクエリをまとめる
現状メディアクエリを記述してコンパイルすると複数メディアクエの記述が発生します。
.c-title {
color: red;
&:hover {
color: blue;
}
@media screen and (min-width: 768px) {
color: yellow;
}
}
.c-button {
display: inline-block;
padding: 20px 50px;
background-color: #1c273e;
color: #efeeea;
@media screen and (min-width: 768px) {
color: yellow;
}
}
現状の出力結果
.c-title {
color: red;
}
.c-title:hover {
color: blue;
}
@media screen and (min-width: 768px) {
.c-title {
color: yellow;
}
}
.c-button {
display: inline-block;
padding: 20px 50px;
background-color: #1c273e;
color: #efeeea;
}
@media screen and (min-width: 768px) {
.c-button {
color: yellow;
}
}
@media screen and (min-width: 768px){}
を1つにまとめます。
下記のコマンドをターミナルでたたきます。
npm install --save-dev gulp-group-css-media-queries
const gcmq = require("gulp-group-css-media-queries");
const compileSass = (done) => {
src("./src/scss/style.scss", { sourcemaps: true })
.pipe(sass())
.pipe(gcmq()) // 追加
.pipe(dest("./assets/css", { sourcemaps: "./sourcemaps" }));
done();
};
これでタスクを実行します。
npx gulp compileSass
style.css
を確認すると
.c-button {
display: inline-block;
padding: 20px 50px;
background-color: #1c273e;
color: #efeeea;
}
.c-title {
color: red;
}
.c-title:hover {
color: blue;
}
@media screen and (min-width: 768px) {
.c-button {
color: yellow;
}
.c-title {
color: yellow;
}
}
/*# sourceMappingURL=sourcemaps/style.css.map */
無事にまとめてくれましたね…!
ファイルの変更を監視して、Sassの変更を反映させる
現在の状態だとscssファイルに変更を加えても自動でコンパイルがされません。
変更を検知して自動でコンパイルされるように変更します。
// watchを追加
const { src, dest, series, watch } = require("gulp");
const watchFiles = (done) => {
watch("./src/scss/**/*.scss", compileSass);
};
exports.watchFiles = watchFiles;
npx gulp watchFiles
これで自動でコンパイルされようになりました。
ローカルサーバーを立ち上げて自動リロードさせる
次に下記を行っていきます。
①Gulpを動かしたときに、ローカルサーバーを立ち上げる
②変更を検知したときに、自動リロードさせる
下記コマンドを入力します。
npm install --save-dev browser-sync
下記のようにコードを追加します。
const browserSync = require("browser-sync");
// 一部変更
const watchFiles = () => {
watch("./src/scss/**/*.scss", series(compileSass, browserReload));
};
// ローカルサーバーの起動
const browserInit = (done) => {
browserSync.init({
files: ["**/*"],
// 静的サイト
server: {
baseDir: "./",
},
// 動的サイト
// proxy: "http://XXXXXXXX.local/",
opne: true,
});
done();
};
// ローカルサーバーのリロード
const browserReload = (done) => {
browserSync.reload();
done();
};
exports.dev = gulp.parallel(browserInit, watch);
軽く解説です。
まずは、browserInitでは、ローカルサーバーを起動させます。
files: [“**/*”]の部分はどのファイルを監視対象にするのかを指定します。
すべてのファイルを監視対象にしています。
ポイントは静的サイトのときには
server: {
baseDir: "./",
}
と記述して、動的サイト(WordPress) では
proxy: "http://XXXXXXXX.local/"
と記述します。
次にファイルに変更が加わったときにリロードを行うようにします。
const browserReload = (done) => {
browserSync.reload();
done();
};
reload()の関数が用意されているのでこちらを使用します。
次に、watchのタスクに今回のリロードを追記します。
const watchFiles = () => {
watch("./src/scss/**/*.scss", series(compileSass, browserReload));
};
seriesと処理を直列で処理したいときに使用します。
なのでここでの記述だと、compileSassを実行後にブラウザをリロードすることになります。
最後に、タスクを登録します。
exports.dev = gulp.parallel(browserInit, watch);
下記のコマンドを実行することで、 watchされた状態でブラウザが自動で立ち上がってくれます。
npx gulp dev
画像を圧縮してサイト速度を改善しよう!
Gulpで画像を圧縮するときには、僕はこちらを使っています。
pacakgeをインストールする前に、TinyPng APIをする前に登録を行います。
マイページのAPI KEYをあとから使用します。
フリープランだと500回使用することができます。
次にパッケージを入れるために、下記をターミナルでたたきます。
npm install --save-dev gulp-tinypng-extended
gulpfile.js
に追記します。
const tinypng = require("gulp-tinypng-extended");
// copyImagesを追記
const watchFiles = () => {
watch("./src/scss/**/*.scss", series(compileSass, browserReload, copyImages));
};
// 画像を圧縮
const compressImages = (done) => {
src("./src/images/**/*.{jpg,jpeg,png}")
.pipe(
tinypng({
key: "API KEY", //ここにAPI KEYを入れる
sigFile: "./src/images/.tinypng-sigs",
log: true,
summarise: true,
})
.pipe(dest("./assets/images"))
);
done();
};
// 画像をコピー
const copyImages = (done) => {
src(["./src/images/**/*"])
.pipe(dest("./assets/images"));
done();
};
exports.compressImages = series(compressImages, copyImages);
exports.dev = parallel(browserInit, watchFiles);
compressImagesの関数を作成して、そこにAPIのKEYを入れます。
copyImagesでは、単純に開発用ディレクトリの画像をassetsフォルダにコピーしているだけですね。
通常の開発時に毎回画像の圧縮処理が入ると作業効率が悪くなるので、開発時には画像をコピーするだけにして、別途画像の圧縮用のタスクを作成しています。
【まとめ】気持ちの良い開発体験を手に入れよう!
制作する際には必ず使用するGulpです。
まだ書ききれていない部分が多々ありますので少しずつ更新していきますね^^