こんにちは、デザイナーの kanna です。
この記事はWEB制作の環境構築に初挑戦して学んだことをまとめています。
__Gulp4__についての内容になります。
バージョンの違いによって書き方が変わる部分があるのでご注意ください。
【環境】
・macOS Big Sur v11.4
・VScode v1.59.0
・zsh
#そもそもGulpって何?
gulpはNode.jsをベースとしたタスクランナーの一つです。タスクランナーとは、Webサイト構築に必要な処理をタスクとして自動化してくれるプログラムのことで、「どのファイルを」「どのように加工して」「どこに出力するか」などをタスクとして設定できるツール全般のことを指します。
#gulpで実現したいこと
- Sassのコンパイル(scssをcssへ)
- EJSをhtmlファイルに変換
- 画像(jpeg, png, gif)の圧縮
- ブラウザの自動更新
今回はこの4つの処理を自動化したいので、これらを中心に解説していきます。
#Node.jsインストールまでの流れを確認
Gulpを動かすためにはNode.jsが必要です。
Node.jsをインストールしたい場合、公式サイトから直接インストールしても問題ありません。
ただし、複数のプロジェクトで異なるバージョンを使う場合には、__公式のインストーラとHomebrew経由では複数のバージョンをインストールできない__のでおすすめしません。
プロジェクトごとにNode.jsのバージョンを管理できる__anyenv__というツールが便利だと教えてもらったので、anyenv経由でnode.jsをインストールすることにしました。
__Homebrew 経由の anyenv 経由の nodenv 経由で Node.js をインストール__する。
いや、経由しすぎ..!!!(ゴールが遠く感じる瞬間…笑)
- Homebrewのインストール
- anyenvのインストール
- nodenvのインストール
- Node.jsのインストール
精神的なダメージをくらいつつも順番が分かったので、実際にインストールをしてみる。
#Homebrewをインストール
Macでターミナルを立ち上げて、Homebrew 公式サイト から記載されているインストールコマンド(シェルスクリプト)をターミナル画面にペーストし実行(Enter)します。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
HomebrewはmacOS用のパッケージマネージャーです
macOS Catalinaからデフォルトシェルが bash から zsh に変更されています
#anyenvをインストール
anyenvでインストール手順を確認
zshの場合だと、コマンド入力の出だしが $
ではなく %
になっている
####anyenvをインストール
brew install anyenv
####シェルにanyenvを設定する
anyenv install --init
####pathを通す
インストールしただけではコマンドを打っても動かないので、コマンドがたたけるようにpath
を通します。PATHを通すってなんぞや?という方は下記の記事がオススメです。
PATHを通すとは? (Mac OS X)
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
####シェルを再起動する
pathを通したらログインシェルを再起動して新しい設定ファイルを読ませる。
exec $SHELL -l
####下記のコマンド実行すればpathが通るようになる
eval “$(anyenv init -)”
####インストールしたバージョンを確認する
コマンドを実行した後に anyenv X.X.X
と出ればインストール成功です。
anyenv -v
####anyenv-update プラグイン をインストールする
mkdir -p $(anyenv root)/plugins
git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
####インストールできる○○envを確認する
下記のコマンドを打つと、インストールできる一覧がズラッとでます。
その中に目的の nodenv
が入っていることが確認できます。
anyenv install --list
#nodenvをインストール(anyenv経由)
####anyenvから nodenv をインストールする
anyenv install nodenv
####シェルを再起動する
exec $SHELL -l
####nodenv-default-packagesを設定する
touch $(nodenv root)/default-packages
#ターミナルでプロジェクトフォルダに移動する
node.jsはプロジェクトごとにバージョンを管理するので、必ずプロジェクトフォルダに移動してからインストールを行ってください。
cd
コマンドで移動するか、VScode内でターミナルを立ち上げるかどちらでも大丈夫です。
VScode上でフォルダを開いた状態でターミナルを立ち上げると、そのフォルダに移動した状態で立ち上がるので移動の手間がないのでオススメです。
例えば「GULP-TEST」というフォルダをVScodeで開く。
VScodeの上のメニューから「ターミナル」を押すか、下記のショートカットで起動できます。
ctrl + Shift + @
#nodenvでnode.jsをインストール
いよいよnode.jsのインストールです…
####インストール可能な node.js のバージョンを確認
nodenv install --list
インストールするバージョンは、最新の一つ前のメジャーバージョンの最新がバグなども少なくておすすめだそうです。例えば、v16.6.1
が最新の場合、v15.14.0
をインストールすると良いとのこと。
####バージョンを指定してnode.js をインストール
nodenv install 15.14.0
####グローバルの node.js を特定バージョンで有効化
nodenv global 14.12.0
特定のディレクトリだけNodeバージョンを切り替えたい場合は、切り替えたいプロジェクトディレクトリにいってから nodenv local x.x.x
を実行すると、.node-version
という隠しファイルが作成されます。これでnodenvがバージョンを自動で切り替えてくれます。
####インストール後にリハッシュする
nodenv rehash
nodenvからnodeやグローバルnpmパッケージを見えるようにするためにrehashします。
新しいnodeのバージョンやnpm install -gなどを行ったときに実行する必要があります。
####インストールしたnode.jsのバージョンを確認
node -v
バージョン番号が正しく表示されればインストール成功です。
#プロジェクトフォルダのディレクトリ構成
GULP-TEST
というプロジェクトフォルダを作ったとして、配置はこんな感じ。
#package.jsonファイルを作成
移動したGULP-TEST
フォルダで以下のコマンドを打ちます。
npm init -y
フォルダの直下に__pakage.json
__というファイルが自動生成されます。
#Gulpをローカルにインストールする
npm install -D gulp
-D
はローカルの--save-dev
の略 。
最近ではGulpはローカルにインストールするのが主流のようです。
グローバルインストール = PC上のどこからでも利用できる
ローカルインストール = プロジェクトのフォルダ内でのみ利用できる
コマンドの実行が完了すると、__node_modules
とpakage-lock.json
__が自動生成されます。
インストールしたバージョンも確認しましょう。
gulp -v
local version : ○.○.○
と出ていればOK!
#Gulpのプラグインをインストールする
Gulpプラグイン にたくさんのプラグインがあります。
よく使用されているものをインストールします。
- gulp-sass
- gulp-plumber
- gulp-notify
- gulp-sass-glob
- browser-sync
- gulp-postcss
- autoprefixer
- css-declaration-sorter
- gulp-imagemin
- imagemin-optipng
- imagemin-mozjpeg
- gulp-ejs
- gulp-rename
####上記のプラグインを一括でローカルインストールする
npm install gulp-sass gulp-plumber gulp-notify gulp-sass-glob browser-sync gulp-postcss autoprefixer css-declaration-sorter gulp-imagemin imagemin-optipng imagemin-mozjpeg gulp-ejs gulp-rename --save-dev
インストールが完了したらpackage.json
ファイルを開いて、devDependencies
にインストールしたプラグインたちが追加されているか確認します。
もしdevDependencies
ではなくdependencies
に追記されていたらグローバルインストールしたことになります。その場合はグローバルにいれたものをアンインストールして、もう一度ローカルにインストールしなおしてください。
自分の場合、参照したサイトが多すぎて最初にグローバルインストールしてしまってgulp実行でエラー吐きまくりになったので要注意です。
#gulpfile.jsを作成する
package.jsonファイルと同じ階層に手動でgulpfile.js
ファイルを作成します。
(+)のファイルアイコンから新規作成で追加できます。
作成したgulpfile.jsの中身を書いていきます。
スーパー初心者なので、コード元は参考にさせていただいた下記のサイト様からお借りしてちょこっと編集しております。主にエラー部分と参照元ファイルのパス、出力先パスを変更しました。
var gulp = require('gulp');
var sass = require('gulp-sass')(require('sass')); //Sassコンパイル
var plumber = require('gulp-plumber'); //エラー時の強制終了を防止
var notify = require('gulp-notify'); //エラー発生時にデスクトップ通知する
var sassGlob = require('gulp-sass-glob'); //@importの記述を簡潔にする
var browserSync = require('browser-sync'); //ブラウザ反映
var postcss = require('gulp-postcss'); //autoprefixerとセット
var autoprefixer = require('autoprefixer'); //ベンダープレフィックス付与
var cssdeclsort = require('css-declaration-sorter'); //css並べ替え
var imagemin = require('gulp-imagemin');//画像を自動圧縮する
var optipng = require('imagemin-optipng');//pngの圧縮
var mozjpeg = require('imagemin-mozjpeg');//jpegの圧縮
var ejs = require("gulp-ejs");//htmlに変換
var rename = require("gulp-rename"); //.ejsの拡張子を変更
// scssのコンパイル
gulp.task('sass', function () {
return gulp
.src('./src/scss/**/*.scss', gulp.task('sass'))
.pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") }))//エラーチェック
.pipe(sassGlob())//importの読み込みを簡潔にする
.pipe(sass({
outputStyle: 'expanded' //expanded, nested, campact, compressedから選択
}))
.pipe(postcss([autoprefixer(
{
// ☆IEは11以上、Androidは5以上
// その他は最新2バージョンで必要なベンダープレフィックスを付与する
"overrideBrowserslist": ["last 2 versions", "ie >= 11", "Android >= 5"],
cascade: false
}
)]))
.pipe(postcss([cssdeclsort({ order: 'alphabetical' })]))//プロパティをソートし直す(アルファベット順)
.pipe(gulp.dest('./dest/css'));//コンパイル後の出力先
});
// 保存時のリロード
gulp.task('browser-sync', function (done) {
browserSync.init({
//ローカル開発
server: {
baseDir: "./",
index: "index.html"
}
});
done();
});
gulp.task('bs-reload', function (done) {
browserSync.reload();
done();
});
var browserSync = require('browser-sync'); //再度ブラウザ反映
gulp.task("ejs", (done) => {
gulp
.src(["ejs/**/*.ejs", "!" + "ejs/**/_*.ejs"])
.pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") }))//エラーチェック
.pipe(ejs())
.pipe(rename({ extname: ".html" })) //拡張子をhtmlに
.pipe(gulp.dest("./dest/html")); //出力先
done();
});
// 監視
gulp.task('watch', function (done) {
gulp.watch('./src/scss/**/*.scss', gulp.task('sass')); //sassが更新されたらgulp sassを実行
gulp.watch('./src/scss/**/*.scss', gulp.task('bs-reload')); //sassが更新されたらbs-reloadを実行
gulp.watch('./src/js/*.js', gulp.task('bs-reload')); //jsが更新されたらbs-relaodを実行
gulp.watch('./ejs/**/*.ejs', gulp.task('ejs')); //ejsが更新されたらgulp-ejsを実行
gulp.watch('./ejs/**/*.ejs', gulp.task('bs-reload')); //ejsが更新されたらbs-reloadを実行
});
// default
gulp.task('default', gulp.series(gulp.parallel('browser-sync', 'watch')));
//圧縮率の定義
var imageminOption = [
optipng({ optimizationLevel: 5 }),
mozjpeg({ quality: 85 }),
imagemin.gifsicle({
interlaced: false,
optimizationLevel: 1,
colors: 256
}),
imagemin.mozjpeg(),
imagemin.optipng(),
imagemin.svgo()
];
// 画像の圧縮
// $ gulp imageminで./src/img/base/フォルダ内の画像を圧縮し./src/img/フォルダへ
// .gifが入っているとエラーが出る
gulp.task('imagemin', function () {
return gulp
.src('./src/img/base/*.{png,jpg,gif,svg}')
.pipe(imagemin(imageminOption))
.pipe(gulp.dest('./src/img'));
});
#タスクの書き方を簡単に解説
var plumber = require('gulp-plumber'); //エラー時の強制終了を防止
var notify = require('gulp-notify'); //エラー発生時にデスクトップ通知する
var ejs = require("gulp-ejs");//htmlに変換
var rename = require("gulp-rename"); //.ejsの拡張子を変更
gulp.task("ejs", (done) => {
gulp
.src(["ejs/**/*.ejs", "!" + "ejs/**/_*.ejs"])
.pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") }))//エラーチェック
.pipe(ejs())
.pipe(rename({ extname: ".html" })) //拡張子をhtmlに
.pipe(gulp.dest("./dest/html")); //出力先
done();
});
var ○○○○ = require("gulp-○○○○");
で宣言をして、下にタスクを追加していきます。
タスクは.pipe()
を使うことで複数の処理を簡潔にまとめて書くことができます。
新しく処理を追加したい場合は.pipe()
を増やして中身を追記し、プラグインが必要であればインストールして宣言文も追加してください。
処理の流れは、ejs
フォルダにある.ejs
形式のファイルに対してエラーチェック>コンパイル>拡張子の変換 の順で処理を行い、最後にgulp.dest()
というメソッドによってファイルを書き出します。gulp.dest()
のカッコの中に出力先のパスを指定します。
書き方はざっとこんな感じです。
#テスト用のファイルを準備する
index.ejsとstyle.scssを作成して処理が実行できるかをテストします。
./ejs
フォルダにindex.ejs
を置いて./src/scss
の下にstyle.scss
を置いています。ファイルの置き場所とgulpfile.jsに記載した参照元が一致していないと動かないので、パスがあっているかしっかり確認します。
適当なコードを用意する
//サンプルです
#main {
width: 600px;
p {
margin-bottom: 20px;
padding-top: 10px;
}
span {
font-size: 16px;
color: #c53b3b;
}
}
<!DOCTYPE html>
<html lang="ja">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<meta charset="UTF-8">
<title><%= (typeof title != "undefined" ? title : "") %></title>
</head>
<body>
</body>
</html>
#タスクを実行して動作確認をする
ターミナルで以下のコマンドを入力して実行すると、destフォルダ内のhtmlフォルダ内にindex.htmlが生成される。
gulp ejs
同様にsassコマンドを実行すればstyle.cssファイルが生成される。
gulp sass
画像圧縮コマンド
gulp imagemin
npx gulp
でタスクを一括実行することもできます。sassとejsの変換、ブラウザのリロードが実行されます。
npx gulp
\(^o^)/完成!!!!!
#おわりに
知識ほぼ0からのスタートなので、いろんな情報をインプットするのが大変でした。
いろんなエラーを解消するのに3日くらい悩みましたが、おかげでgulpfile.jsの中身が大分理解できるようになりました。自分にとっては結構ハードルがありましたが、出来たときの喜びも半端なかったです。
この記事が少しでも誰かのお役に立てれば嬉しいです😊
#おまけ:エラー解消
大量のエラーに遭遇しましたが、その中でも特に苦しんだものをピックアップします…。
gulp: command not found
> パスが通っていない可能性
https://dezanari.com/gulp-error-matome/
https://masahiro.me/2019/06/post-2246/
https://qiita.com/sugurutakahashi12345/items/b814a09b65d8852226ad
Error: Cannot find module 'date'
> インストール失敗orパスが通ってない可能性
https://techacademy.jp/magazine/16113
https://wordpress.ideacompo.com/?p=12299
https://teratail.com/questions/167950
gulp-notify: [Error running Gulp] Error: Invalid built-in order 'alphabetically' provided. Available built-in orders are: alphabetical,concentric-css,smacss
> gulpfile内の文字を修正
https://teratail.com/questions/258845
#参考サイト
https://ics.media/entry/3290/