放課後のプログラミング部。部室でウェブサイト制作の課題に取り組んでいたOZくんは、ため息をつきながらパソコンの画面を見つめていました。
OZくん、どうしたんですか?なんだかため息が出るほど悩んでいるようですが、、
あ、プロ太先生…実は、ウェブサイトの制作をしているんですけど、毎回の更新作業が大変で…
具体的にはどんな作業が大変なんですか?
はい、CSSファイルの圧縮とか、画像ファイルの圧縮とか…毎回手作業でやるのが面倒で。しかも、作業を忘れたりミスしたりすることもあって…
なるほど!そんなOZくんにぴったりのツールがありますよ。
その名も『Gulp(ガルプ)』!
ガルプ…?なんですか、それ?
Gulpとは?
Gulpは、タスクランナーと呼ばれるツールなんです。タスクランナーって聞くと難しそうですが、要するに『面倒な作業を自動化してくれる便利な助手さん』だと思ってくれればいいですよ。
助手さん、、、ですか?
そうです。例えば、学校の掃除当番を想像してみてください。毎日、『ゴミ箱を空にする→床を掃く→雑巾がけ』って決まった手順でやりますよね?
はい、そうですね。
Gulpは、そういう『決まった手順の作業』を、君の代わりに自動でやってくれるです。しかも、人間より正確で、疲れ知らずですからね!
へぇ!それは便利そうですね!
Gulpでできること
じゃあ、Gulpでできることを具体的に見ていきましょう。主な機能をいくつか紹介しますね。
- ファイルの圧縮(Minification)
- CSSやJavaScriptファイルを圧縮して、サイズを小さくできる
- ファイルの結合(Concatenation)
- 複数のファイルを1つにまとめられる
- ブラウザの自動リロード(Browser Sync)
- ファイルを保存すると自動でブラウザをリフレッシュ
- Sassのコンパイル
- SassをCSSに変換
- 画像の最適化
- 画像ファイルを圧縮して軽量化
すごい!!こんなにたくさんのことができるんですね!!
Gulpの導入
じゃあ、実際にGulpを使えるようにするための準備をしていきましょう。
1.Node.jsのインストール
まずはNode.jsというソフトをインストールする必要があります。これは、お店でガルプ君(Gulp)を雇う前に、お店(パソコン)の経営許可を取るようなものですね。
- Node.jsの公式サイトにアクセス
→https://nodejs.org/ - LTS(Long Term Support)版をダウンロード
→「LTS」と書かれているボタンをクリック - ダウンロードしたインストーラーを実行
- 画面の指示に従ってインストール完了
インストールができたら、ターミナル(Windowsならコマンドプロンプト)で以下のコマンドを実行して、ちゃんとNode.jsがインストールされたか確認してみましょう。
# バージョンの確認
node -v
npm -v
両方のコマンドでバージョン番号が表示されればOKということですね!
2.Gulpのインストール
次は、いよいよ、Gulpをインストールしましょう!
# グローバルにGulpをインストール
npm install -g gulp-cli
# プロジェクトフォルダで以下のコマンドを実行
npm init -y
npm install --save-dev gulp
なんだか難しそうなコマンドがいっぱい出てきましたね…
大丈夫!これは最初の1回だけですから。お店の開店準備みたいなものですよ。念のため、それぞれのコマンドの意味を説明しておきますね。
Step 1: Gulpのコマンドラインツールをグローバルにインストール
npm install -g gulp-cli
npm install
: パッケージをインストールするコマンド-g
: グローバルフラグ。インストールしたPCのどこからでもgulpコマンドを使えるようにする
→例えば、スマホでアプリを入れて、どこでも使えるようにするイメージです
→このコマンドは、一度実行して、自分のPCにインストールが完了すれば2回目以降は不必要gulp-cli
: Gulpのコマンドラインインターフェース。gulpコマンドを使うために必要なツール
へぇ〜!グローバルでインストールしたら、どこでも使えるようになるんですね!
Step 2: プロジェクトの初期化
npm init -y
このコマンドは、プロジェクトの設定ファイルを作成しています。
npm init
: プロジェクトの初期化コマンド-y
: 全ての設定をデフォルトで「yes」にするオプション
→npm init と入力し、設定を入力してもOK!- 実行すると以下のような、
package.json
というファイルが作成される
{
"name": "プロジェクト名",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
ちなみに、このコマンドで作られるpackage.json
は、とても重要で便利なファイルなんです!
このファイルが便利なんですか??
そうなんです。これは単なる設定ファイルじゃなくて、『プロジェクトの設計図』みたいなものなんです。例えば、先程のコマンドで出来上がったpackage.json
のファイルの中身を以下のように書き換えてみてください。
{
"name": "gulp_test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build": "gulp build"
"watch": "gulp watch"
},
"author": "",
"license": "ISC",
"devDependencies": {
"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-clean-css": "^4.3.0",
"gulp-imagemin": "^7.1.0",
"gulp-dart-sass": "^1.0.2",
"browserify": "^17.0.0",
"vinyl-source-stream": "^2.0.0",
"browser-sync": "^2.27.7"
}
}
これは、私が開発で使っているpackage.json
ファイルの中身です。これがあれば、他の人も私と全く同じ開発環境が簡単に作れるんです!
開発環境の共有手順
- 共有する側がすること
- package.jsonを含むプロジェクトファイルを共有
- (注:node_modulesフォルダは共有不要!)
- 受け取った側がすること
# プロジェクトフォルダで以下のコマンドを実行するだけ!
npm install
こんな風に同じような開発環境を作りたい相手に、このpackage.jsonを渡して、渡された側は上のコマンドを入力するだけで、簡単に同じ開発環境が作れちゃいます!
なるほど!じゃあ、チームで開発するときも便利ですね!
その通り!特に以下のような場面で重宝します!!
package.jsonが特に役立つシーン
- チーム開発時
- 新しいメンバーが参加したとき
- 全員が同じバージョンのツールを使える
- 複数のパソコンで開発するとき
- 会社と自宅で開発する場合
- 新しいパソコンでの環境構築
- プロジェクトの引き継ぎ時
- 必要な開発環境の情報が全て残っている
- 引き継ぎ作業が格段に楽になる
すごい!!便利さが分かりました!!ありがとうございます!!
基本的なgulpfile.jsの書き方
次は、Gulpに『どんな作業をしてほしいか』を伝えるための指示書を作っていきます。『gulpfile.js』というファイルを作って、以下のような内容を書き込みます。
// パッケージの読み込み
const gulp = require("gulp");
const dartSass = require("gulp-dart-sass");
const cleanCSS = require("gulp-clean-css");
const changed = require("gulp-changed");
const imagemin = require("gulp-imagemin");
const browserify = require("browserify");
const source = require("vinyl-source-stream");
const browserSync = require("browser-sync").create();
// ファイルパスの設定
const paths = {
styles: {
src: "src/scss/**/*.scss",
dest: "dist/css",
},
images: {
src: "src/images/**/*",
dest: "dist/images",
},
scripts: {
entries: ["src/js/main.js"],
dest: "dist/js",
},
php: {
src: "./*.php",
dest: "dist/",
},
};
// Sassのコンパイル
function styles() {
return gulp
.src(paths.styles.src)
.pipe(changed(paths.styles.dest))
.pipe(
dartSass({
outputStyle: "compressed", // CSSを圧縮
}).on("error", dartSass.logError)
)
.pipe(cleanCSS())
.pipe(gulp.dest(paths.styles.dest))
.pipe(browserSync.stream()); // CSSの変更時にブラウザを更新
}
// 画像の最適化
function images() {
return gulp
.src(paths.images.src)
.pipe(changed(paths.images.dest))
.pipe(
imagemin([
imagemin.gifsicle({ interlaced: true }),
imagemin.mozjpeg({ quality: 75, progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({
plugins: [{ removeViewBox: true }, { cleanupIDs: false }],
}),
])
)
.pipe(gulp.dest(paths.images.dest));
}
// JavaScriptのバンドル
function scripts() {
return browserify({
entries: paths.scripts.entries,
debug: true,
})
.bundle()
.pipe(source("bundle.js"))
.pipe(gulp.dest(paths.scripts.dest))
.pipe(browserSync.stream()); // JavaScriptの変更時にブラウザを更新
}
// PHPファイルのコピー
function copyPhp() {
return gulp.src(paths.php.src).pipe(gulp.dest(paths.php.dest));
}
// BrowserSyncを起動するタスク
function serve() {
browserSync.init({
proxy: "localhost:8888/◯◯◯◯",
// MAMPのプロキシ設定(◯◯◯◯の部分はhtcocs内においたファイル名)
});
gulp.watch(paths.styles.src, styles);
gulp.watch(paths.images.src, images);
gulp.watch("src/js/**/*.js", scripts);
gulp.watch(paths.php.src, copyPhp).on("change", browserSync.reload);
}
// ビルドタスク
const build = gulp.parallel(styles, images, scripts, copyPhp);
// エクスポート
exports.styles = styles;
exports.images = images;
exports.scripts = scripts;
exports.copyPhp = copyPhp;
exports.build = build;
exports.watch = serve;
exports.default = gulp.series(build, serve);
うわぁ…これは何をしているんですか?
順番に説明していきますね!
1. パッケージの読み込みとパスの設定
// パッケージの読み込み
const gulp = require("gulp");
const dartSass = require("gulp-dart-sass");
const cleanCSS = require("gulp-clean-css");
const changed = require("gulp-changed");
const imagemin = require("gulp-imagemin");
const browserify = require("browserify");
const source = require("vinyl-source-stream");
const browserSync = require("browser-sync").create();
// ファイルパスの設定
const paths = {
styles: {
src: "src/scss/**/*.scss",
dest: "dist/css",
},
images: {
src: "src/images/**/*",
dest: "dist/images",
},
scripts: {
entries: ["src/js/main.js"],
dest: "dist/js",
},
php: {
src: "./*.php",
dest: "dist/",
},
};
最初の部分は、必要な道具を用意している部分です。お料理で言えば、包丁やまな板を準備するようなものですね。
gulp-dart-sass
: Sassをコンパイルするための道具gulp-clean-css
: CSSを圧縮する道具gulp-changed
: 変更があったファイルだけを処理する道具gulp-imagemin
: 画像を最適化する道具browserify
: JavaScriptファイルをまとめる道具browser-sync
: ブラウザを自動更新する道具
Gulpを使うときのファイルの配置って、どうすればいいんですか?
いい質問ですね!では、プロジェクトの構造を見てみましょう。基本的にこんな感じになります。
プロジェクトフォルダ/
├── src/ # 開発用のソースファイル
│ ├── scss/ # Sassファイル
│ │ ├── style.scss
│ │ └── _variables.scss
│ ├── images/ # 画像ファイル
│ │ ├── hero.jpg
│ │ └── logo.png
│ └── js/ # JavaScriptファイル
│ └── main.js
├── dist/ # コンパイル後のファイル
│ ├── css/ # コンパイル後のCSSファイル
│ ├── images/ # 最適化後の画像ファイル
│ └── js/ # バンドル後のJavaScriptファイル
├── package.json # プロジェクトの設定ファイル
├── gulpfile.js # Gulpの設定ファイル
└── index.php
おお!フォルダがきれいに分かれているんですね!!
src
は「素材置き場」、dist
は「完成品置き場」って考えるといいですよ。
2. Sassのコンパイルタスク
function styles() {
return gulp
.src(paths.styles.src)
.pipe(changed(paths.styles.dest))
.pipe(
dartSass({
outputStyle: "compressed", // CSSを圧縮
}).on("error", dartSass.logError)
)
.pipe(cleanCSS())
.pipe(gulp.dest(paths.styles.dest))
.pipe(browserSync.stream());
}
このpipe
って何度も出てきますけど…なんですか?
ああ、これは「作業の順番」を表しています。例えると、お弁当工場の生産ラインみたいなもので、以下のような手順で処理をしています。
- 材料を用意する(.src)
- 変更チェック(changed)
- Sassをコンパイル(dartSass)
- CSSを圧縮(cleanCSS)
- 保存(gulp.dest)
- ブラウザ更新(browserSync.stream) という流れで処理しています。
3. 画像の最適化処理
function images() {
return gulp
.src(paths.images.src)
.pipe(changed(paths.images.dest))
.pipe(
imagemin([
imagemin.gifsicle({ interlaced: true }),
imagemin.mozjpeg({ quality: 75, progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({
plugins: [{ removeViewBox: true }, { cleanupIDs: false }],
}),
])
)
.pipe(gulp.dest(paths.images.dest));
}
ここでは、画像の最適化をしていて、具体的に言うと、
- JPEGの画質を75%に設定(quality: 75)
- PNGの圧縮レベルを5に設定(optimizationLevel: 5)
- GIFをインターレース形式に
というように、それぞれの画像形式に最適な設定で圧縮しています。
4. JavaScriptのバンドル処理
function scripts() {
return browserify({
entries: paths.scripts.entries,
debug: true,
})
.bundle()
.pipe(source("bundle.js"))
.pipe(gulp.dest(paths.scripts.dest))
.pipe(browserSync.stream());
}
これは複数のJavaScriptファイルを1つにまとめる処理ですね。例えると、バラバラのレシピをまとめて1冊の料理本にするようなものです。
5.開発サーバーとファイル監視
function serve() {
browserSync.init({
proxy: "localhost:8888/◯◯◯◯",
});
gulp.watch(paths.styles.src, styles);
gulp.watch(paths.images.src, images);
gulp.watch("src/js/**/*.js", scripts);
gulp.watch(paths.php.src, copyPhp).on("change", browserSync.reload);
}
これは「自動監視システム」みたいなもので、
- ローカルサーバーを立ち上げて
- ファイルの変更を監視して
- 変更があったら自動で必要な処理を実行して
- ブラウザを更新する という一連の作業を自動でやってくれるんだ。
6. タスクのエクスポートと実行
const build = gulp.parallel(styles, images, scripts, copyPhp);
exports.styles = styles;
exports.images = images;
exports.scripts = scripts;
exports.copyPhp = copyPhp;
exports.build = build;
exports.watch = serve;
exports.default = gulp.series(build, serve);
これは「使える機能の登録」みたいなものだね。例えば、
npm run build
: 全ての処理を一度に実行npm run watch
: 監視モードを開始 というように使えるようになります。
Gulpの使い方
なるほど!!でも、実際にはどうやって使うんですか?
コマンドラインで以下のように入力するだけでOKです!
1.デフォルトタスクの実行:
gulp
このコマンドを実行すると、さっき書いた指示書(gulpfile.js)の最後のの方で書いたexports.default
で設定したタスクを実行します。今回の場合は、build
とserve
が順番に実行されますね。
えぇっ!?たったそれだけですか!?簡単ですね!
2.特定のタスクの実行:
gulp styles # Sassのコンパイルだけを実行
gulp images # 画像の最適化だけを実行
gulp scripts # JavaScriptのバンドルだけを実行
gulp build # 全てのビルドタスクを実行
gulp watch # ファイル監視を開始
特定のタスクだけ実行したい場合は、上記のようなコマンドの入力で大丈夫です。
あれ?先生、さっきはnpm run build
って言ってませんでした?
実は両方使えるんです。その違いを説明しますね。
npmコマンドとgulpコマンドの違い
1.gulp
コマンドを使う場合:
gulp build
- Gulpをグローバルにインストールしている必要がある
- シンプルで直接的
- プロジェクトによってコマンドが統一されない可能性がある
2.npm run
コマンドを使う場合:
npm run build
- package.jsonのscriptsに定義が必要(以下の部分参照)
- プロジェクト内のGulpを使用するので安全
- プロジェクト間でコマンドを統一しやすい
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build": "gulp build"
"watch": "gulp watch"
},
まとめ
どうですか?Gulpについて少しわかってきましたか?
はい!最初は難しそうに見えましたが、要するに:
- 面倒な作業を自動化してくれる
- ミスなく正確に作業をしてくれる
- 時間を大幅に節約できる ということですよね?
その通りです!特に大きなプロジェクトになればなるほど、Gulpの便利さは実感できるはずですよ!
早速、次のプロジェクトで使ってみます!ありがとうございました、先生!
このように、Gulpは現代のWeb開発において非常に重要なツールの1つとなっています。確かに最初の設定は少し手間がかかりますが、一度設定してしまえば、その後の開発効率は大きく向上します。
特に以下のような場合には、Gulpの導入を検討してみることをおすすめします:
- 複数のSassファイルやJavaScriptファイルを扱うプロジェクト
- チームで開発を行うプロジェクト
- 定期的なファイル更新が必要なプロジェクト
- 作業の自動化によって品質向上を図りたい場合
Gulpを使いこなすことで、より効率的で品質の高いWeb開発が可能になるはずです。