今からでも遅くないGulpを使った開発環境の作り方

今回はGulpの導入から最低限の活用部分まで、どうやったら使えるのか・使えるようになるのかを紹介してみたいと思います。

僕は今までほぼ全ての案件においてPreprosを活用してきました。Preprosをご存知ない方は以下のリンクで見てもらうとわかりやすいと思いますが、簡単に言うとこれから紹介するGulpで出来ることを簡単にできるアプリケーションです。

では、「なんでPreprosからGulpに引っ越すの?」という疑問が当然出てくると思うのですが、複数人(チーム)でプロジェクトを動かす際に共有しやすいというメリットが大きいかと思います。残念ながら僕は複数人でマークアップを進めることは経験したことがありませんが。

まぁ、Preprosでも設定ファイルを共有すれば可能なんですが、チームで動ける人の多くはpreprosよりもgulpを使っている場合の方が多いと思いますので、自然とgulpへ傾くのではないかと勝手に予想しています。(チームで動くとgitとかもモリモリ使いますし、コマンドラインに慣れている方がほとんどだと思いますし、そういう要因もあるのかな?と推測)

個人的には、今までGrunt→Gulp→そんなだいそれたこと必要ないからpreprosと渡り歩いてきたので、全く触ったことがないという訳ではないのですが、改めて再導入してみて学んだことも多くあったので、そんな学びも含めてお伝えできればと思います。

Gulpとは

Node.jsのーどじぇいえすをベースにつくられたタスクランナーと呼ばれるものです。

タスクランナーというのは、なんとなくイメージ出来るとは思いますが、作業(タスク)を走らせてくれるものという意味になります。んじゃ、タスクってどんなことを言ってるの?って話になるんですが、例えばこんなことです。

  • Sass/pugをコンパイルする
  • 画像を圧縮する
  • JSファイルを圧縮する
  • オートリロードさせる
  • ファイルを監視させる

こんな作業をマークアップの際には行うのではないでしょうか。それぞれ様々なGUIや黒い画面を駆使すれば行えるタスクではありますが、それを自動的に簡単にやれるよにしてくれる仕組みがタスクランナーという解釈をしていただければ問題ないかと思います。

では、実際に触りながら良さそうなGulp環境を作っていきましょう。

最低限、黒い画面と呼ばれるターミナルなどを触る必要があります。出来るだけわかりやすく書いてみますが、わかりにくい部分があればコメントやTwitter(@Olein_jp)で教えてください!
黒い画面にはMac純正のターミナルアプリを使っています。

Node.jsを入れる

まずはNode.jsを入れます。

Node入ってるかも…?という方

「ん?前に入れたことあるかな?どうなのかな?」という方はターミナルで以下のように入れてみてください。

$ node -v

そこでバージョンナンバーが表示されれば入っています。最新にあげておいてもいいかもしれませんね。

$ npm install -g n

nというヘルパーコマンドをインストールして、

$ n latest

と入れると最新版にアップデートされます。もし、Error: sudo requiredとか言われたら、

$ sudo n latest

と入れてパスワード(パソコンをログインするときとかに使うパスワード)を入力してやってください。

Node.js入ってません!って方

こちらからダウンロードしましょう。

「最新版!」って書いてある方で大丈夫です。

インストーラーがダウンロードされますので、アプリをインストールするときと同じ要領でインストールします。

インストール作業が終わったら、ターミナルアプリを起動して以下のコマンドを打ってみてください。

以下、ターミナルアプリのことをターミナルと書きます。
$ node -v

これで何かしら数字が出てきたら、Node.jsのインストール完了です。

プロジェクトのフォルダを作る

まずは、プロジェクトのフォルダを作りましょう。デスクトップでもどこでも大丈夫なんで作りましょう。今回はデスクトップにmyprojectというフォルダを作って進めていきます。

そして、ターミナルで、作ったフォルダにアクセスしておきましょう。ここからは、基本こちらで作ったフォルダ内で作業しますので。

cdで移動先を指定するんですが、長いパスを入力するのは面倒なんで、該当フォルダをターミナルにドロップすると、パスを自動で入力してくれるので、こちらの方法の方が(特に初心者の方は)間違いがないです。

ちなみに、cdというコマンドは、Change Directoryという意味です。

npm initする

ターミナルでプロジェクトフォルダに移動していることを確認して、

$ npm init

を実行します。すると、色々と質問されると思うので、とりあえずエンター連打でOKです。

すると、myprojectフォルダ内にpackage.jsonというファイルが作られていることが確認出来るかと思います。

現状のpackage.jsonはこんな内容になっているはずです。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

これで初期設定は終わりです。次からGulpをインストールしていきます。

Gulpインストール

ではGulpをプロジェクトフォルダー以下で使えるようにインストールしていきましょう。

$ npm install gulp --save-dev

基本的に今後もこのnpm install [プラグイン名] --save-devというコマンドを使って各プラグインをインストールしながら、開発環境を作っていくことになりますので、覚えておきましょう。

上記コマンドを実行した後のpackage.jsonの中身はこのようになっているはずです。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

–saveパラメータについて

--saveをつけてインストールするパッケージは、package.json内のdependenciesという部分に記載されます。このdependenciesというのは依存関係というような意味になるのですが、そのプロジェクトが依存するパッケージは--saveコマンドをつけておくべきでしょう。

例えば、jQueryをウェブサイトで使う場合にはdependenciesに該当するかなと思います。

–save-devパラメータについて

--save-devをつけてインストールするパッケージは、package.json内のdevDependenciesという部分に記載されます。このdevDependenciesというのは開発に必要な依存関係というような意味にななります。

実際のウェブサイトにはgulpは必要ないので、--save-devをつけてインストールするということになります。

gulpfile.jsを作る

プロジェクト内にgulpfile.jsという空のJavaScriptのファイルを作ります。そして、以下のように書いておきましょう。

var gulp = require( 'gulp' );

タスクを設定していく

ここからは各タスクの設定をしていきます。黒い画面とエディタが必要になってくるのでよろしくお願いします。

今回作る環境としては、静的ウェブサイトのマークアップを想定しています。WordPress開発環境はディレクトリ構成などが少し変わってくるので、別途記事を書いた方がいいかなという気がしています。

今回作ってみるタスクは、

  • Sassのコンパイル
  • 画像ファイルの圧縮
  • JavaScriptの結合・圧縮
  • CSSの結合・圧縮
  • ブラウザシンク

こんな感じで進めていきます。

また、ディレクトリ構造はこんな感じで考えています。

本来であればdistディレクトリとかに書き出してまとめる方が良い場合も多いんですが、今回はWordPress開発環境構築へと話を続ける手前、このような形にしています。

ちょっと使ってみると、カスタマイズも簡単にしてもらえると思うでの、みなさんご自身の環境に合う構造に作り変えていただければ幸いです。

Sassのコンパイル

まずはSassのコンパイルしてくれる部分を作りましょう。使うプラグインは以下のような感じです。

  • gulp-plumber
  • gulp-sass
  • gulp-progeny
  • gulp-autoprefixer
  • gulp-sourcemaps
【追記】

  • gulp-progenyを追加しました。

gulp-plumberというのは、Sassのコンパイルに直接関係ありませんが、Gulpのタスクを作っていく上でよく使われます。役割としては、エラーが出た時にタスクを止めないための処理だと考えておいてください。

gulp-autoprefixerはプリフィックスをいい感じにつけてくれます。gulp-sourcemapsはソースマップを作ってくれるやつですね。Sassを使う時には入れておかないとデベロッパーツールとかで辛いやつです。

では、まずはプラグインをインストールしましょう。

$ npm install gulp-plumber gulp-sass gulp-progeny gulp-autoprefixer gulp-sourcemaps --save-dev

プラグインごとにnpm install [プラグイン名] --save-devを入力しても全然問題ないんですが、一度に上記のように書くことができます。

現時点でpackage.jsonの中身はこうなってますね。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-plumber": "^1.2.0",
    "gulp-progeny": "^0.4.1",
    "gulp-sass": "^4.0.1",
    "gulp-sourcemaps": "^2.6.4"
  }
}

devDependenciesの中にプラグインが追加されたことがわかるかと思います。

それでは、これらのプラグインを使ってタスクを作っていきましょう。gulpfile.jsにはこのように書いてみます。

var gulp         = require( 'gulp' );              // 1
var sass         = require( 'gulp-sass' );         // 1
var autoprefixer = require( 'gulp-autoprefixer' ); // 1
var plumber      = require( 'gulp-plumber' );      // 1
var sourcemaps   = require( 'gulp-sourcemaps' );   // 1

// Sass
gulp.task( 'sass', function(){ // 2
    gulp.src( './src/assets/sass/**/*.scss' ) // 3
        .pipe( plumber() ) // 4
        .pipe( progeny() ) // 4
        .pipe( sourcemaps.init() ) // 5
        .pipe( sass( { // 6
            outputStyle: 'expanded'
        } ) )
        .pipe( autoprefixer( { // 7
            browsers: ['last 2 version', 'iOS >= 8.1', 'Android >= 4.4'],
            cascade: false
        } ) )
        .pipe( sourcemaps.write() ) // 5
        .pipe( gulp.dest( './css/')) // 8
} );

// 1 – プラグインを変数に設定

まずは、varで変数を用意して、そこにインストールしたプラグインを割り当てていきます。

var ***の部分は好きな名前に変えてもらっても大丈夫ですが、それに伴ってタスク内の変数名も変更してくださいね。

// 2 – タスク名の設定

gulp.task( '***', function() {という書き方で、Gulpタスクの名前を設定しています。この場合だと、タスク名はsassになっていますね。

// 3 – 参照するコードの場所を指定

gulp.src( './src/assets/sass/**/*.scss' )で、参照するコードの場所を指定しています。

今回は.scssをコンパイルしたいので、その場所を./src/assets/sass/**/*.scssという感じで指定しています。

**というのは、ここで言うとsassディレクトリの中にある全てのファイル・ディレクトリを指します。そして、*.scss.scssファイルのどんなファイル名でも全部を指定することができるんですね。

// 4 – エラーが発生してもタスクを止めない

gulp-plumberで処理でエラーが発生してもタスクをストップさせないように入れてあります。おまじないみたいなものと考えてください。(黒い画面やMacデスクトップにエラー通知させることもできます)

また、gulp-progenyでパーシャルしたSCSSファイルを変更して保存した際にも親SCSSファイルをコンパイルするようにしています。

// 5 – sourcemapの書き出し

ここではソースマップの書き出し処理を組み込んでいます。

まずはinitで初期化して、writeで書き出しています。タスク内の処理をこれらで囲むイメージで使うと良いかと思います。色々と設定することができますが、ここではとりあえずシンプルにしておきたいと思います。

// 6 – Sassコンパイルを行う

ここでSassコンパイルを行なっています。

outputStyleでコンパイルした後の形式を設定することができます。

  • nested
  • expanded
  • compact
  • compressed

// 7 – プリフィックスを追加する

必要なプリフィックスを追加します。

browsers: ['last 2 version', 'iOS >= 8.1', 'Android >= 4.4']と見てわかるように、最新ブラウザ2バージョン、iOS8.1以上、Android4.4以上に必要なものをつけてもらうようにしています。

他にも設定出来る項目がたくさんあるので、こちらを参照すると良いでしょう。

// 8 – CSSを書き出し

処理が終了したCSSファイルを場所を指定して書き出します。


テストでコンパイルしてみましょう。

まずは、./src/assets/sass内に適当なscssファイルを作ります。今回はstyle.scssファイルを作って、以下のようなSassを書いてみました。(コンパイルとプリフィックスのテストだけなんで意味はありません)

.sass-parent {
  background: #000;
  & .sass-child {
    color: #fff;
    display: flex;
  }
}

そして、ターミナルで以下のコマンドを実行してみます。

$ gulp sass

これで、今作ったタスクを実行することができます。そして、こちらが正常にコンパイルされたCSSの中身になります。

.sass-parent {
  background: #000;
}

.sass-parent .sass-child {
  color: #fff;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGUuY3NzIiwic291cmNlcyI6WyJzdHlsZS5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi5zYXNzLXBhcmVudCB7XG4gIGJhY2tncm91bmQ6ICMwMDA7XG4gICYgLnNhc3MtY2hpbGQge1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gIH1cbn0iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFBQSxZQUFZLENBQUM7RUFDWCxVQUFVLEVBQUUsSUFBSTtDQUtqQjs7QUFORCxBQUVFLFlBRlUsQ0FFUixXQUFXLENBQUM7RUFDWixLQUFLLEVBQUUsSUFBSTtFQUNYLE9BQU8sRUFBRSxJQUFJO0NBQ2QifQ== */

/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLnNjc3MiLCJzdHlsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxpQkFBZ0I7Q0NLakI7O0FETkQ7RUNHSSxZQUFXO0VESGYscUJBRUk7RUFGSixzQkFFSTtFQUZKLHFCQUVJO0VBRkosY0FFSTtDQUNBOztBQ01KLHNmQUFzZiIsImZpbGUiOiJzdHlsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuc2Fzcy1wYXJlbnQge1xuICBiYWNrZ3JvdW5kOiAjMDAwO1xuICAmIC5zYXNzLWNoaWxkIHtcbiAgICBjb2xvcjogI2ZmZjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICB9XG59IiwiLnNhc3MtcGFyZW50IHtcbiAgYmFja2dyb3VuZDogIzAwMDtcbiAgJiAuc2Fzcy1jaGlsZCB7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgZGlzcGxheTogZmxleDtcbiAgfVxufSJdfQ== */

ちゃんとコンパイルされていますね。これでSassコンパイルのタスクは完成です。

画像ファイルの圧縮

画像ファイルの圧縮にはこちらのプラグインを使います。

  • gulp-imagemin
  • imagemin-jpeg-recompress
  • imagemin-pngquant
  • imagemin-gifsicle
  • gulp-svgmin
  • gulp-changed

インストールするコマンドはこんな感じになります。

$ npm install gulp-imagemin imagemin-jpeg-recompress imagemin-pngquant imagemin-gifsicle gulp-svgmin gulp-changed --save-dev

現段階のpackage.jsonはこんな感じです。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-changed": "^3.2.0",
    "gulp-imagemin": "^4.1.0",
    "gulp-plumber": "^1.2.0",
    "gulp-sass": "^4.0.1",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-svgmin": "^2.1.0",
    "imagemin-gifsicle": "^5.2.0",
    "imagemin-jpeg-recompress": "^5.1.0",
    "imagemin-pngquant": "^6.0.0"
  }
}

では、タスクを組んでいきましょう。

var changed      = require( 'gulp-changed' );
var imagemin     = require( 'gulp-imagemin' );
var imageminJpg  = require( 'imagemin-jpeg-recompress' );
var imageminPng  = require( 'imagemin-pngquant' );
var imageminGif  = require( 'imagemin-gifsicle' );
var svgmin       = require( 'gulp-svgmin' );

gulp.task( 'imagemin', function() {
    // jpeg,png,gif
   gulp.src( './src/assets/images/**/*.+(jpg|jpeg|png|gif)' ) // 1
       .pipe( changed( './images' ) ) // 2
       .pipe( imagemin( [ // 3
           imageminPng(),
           imageminJpg(),
           imageminGif({
               interlaced: false,
               optimizationLevel: 3,
               colors: 180
           } )
       ] ) )
       .pipe( gulp.dest( './images/' ) );
   // svg
   gulp.src( './src/assets/images/**/*.+(svg)' ) // 4
       .pipe( changed( './images' ) )
       .pipe( svgmin() ) // 5
       .pipe( gulp.dest( './images/' ) );
} );

少し中身を見てみましょう。

// 1 – Jpg,png,gifファイルを指定

画像ファイルは./src/assets/imagesの中に全て入れることを想定しています。ですので、そのフォルダの中の拡張子が.jpg .jpeg .png .gifのものを全て対象となるように指定しています。

// 2 – 書き出し先フォルダから変更があるかチェック

書き出しフォルダに既にある画像ファイルと比較して、変更があるかどうかをチェックしています。そして、変更があるファイルだけが次の処理へと回されます。なので、無駄に何度も同じファイルを圧縮して劣化していくようなことはありません。

// 3 – 画像の圧縮

インストールしたプラグインimageminだけでもできなくはないのですが、今回はjpegとpngとgifそれぞれにプラグインを別に当てています。それぞれのプラグインはimageminプラグインと一緒に使います。

interlaced: false,
optimizationLevel: 3,
colors: 180

オプション部分は他にも色々とできることがあるので確認してみてください。

// 4 – svgファイルを指定する

先ほどはjpeg png gif を指定していましたが、ここではSVGの圧縮をしたいのでSVGだけを指定しています。

// 5 – SVGファイルの圧縮

ここでSVGファイルの圧縮を行なっています。

設定できるオプションもたくさんあるので、こちらを参照してみると良いでしょう。


では実行してみます。

$ gulp imagemin

とコマンドを実行すると、ターミナルにこのように表示されます。

圧縮された情報をターミナルでも確認することができます。

また、ファイルはこのような感じになりました。各ファイルの容量を見てもらうと、圧縮されていることが確認出来るかと思います。

JavaScriptを結合・圧縮する

JavaScriptの結合と圧縮するタスクを作っていきましょう。

ファイルの結合・圧縮に使うプラグインはこちらです。

  • gulp-concat
  • gulp-jshint
  • gulp-uglify
  • gulp-rename

gulp-concatはファイルを結合するプラグインです。gulp-jshintはJavaScriptの構文をチェックしてくれるプラグインです。gulp-uglifyはファイルを圧縮してくれるプラグインですね。gulp-renameはファイル名を変更するプラグインになります。

あと、過去に壁にぶち当たったことがあるんですが、gulp-jshintプラグインを使いたいときに、gulp-jshintプラグインだけでは動きません。jshintの大元もインストールする必要があります。ですので、jshintというプラグインもインストールします。

では、これらのプラグインをインストールしていきましょう。

$ npm install gulp-concat jshint gulp-jshint gulp-uglify gulp-rename --save-dev

こちらを実行するとpackage.jsonはこのような内容になります。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-changed": "^3.2.0",
    "gulp-concat": "^2.6.1",
    "gulp-imagemin": "^4.1.0",
    "gulp-jshint": "^2.1.0",
    "gulp-plumber": "^1.2.0",
    "gulp-rename": "^1.4.0",
    "gulp-sass": "^4.0.1",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-svgmin": "^2.1.0",
    "gulp-uglify": "^3.0.1",
    "imagemin-gifsicle": "^5.2.0",
    "imagemin-jpeg-recompress": "^5.1.0",
    "imagemin-pngquant": "^6.0.0"
  }
}

では、実際にタスクを作ってみましょう。

var concat       = require( 'gulp-concat' );
var jshint       = require( 'gulp-jshint' );
var rename       = require( 'gulp-rename' );
var uglify       = require( 'gulp-uglify' );

// concat js file(s)
gulp.task( 'js.concat', function() {
    gulp.src( [
        './src/assets/js/sample.js' // 1
    ] )
        .pipe( plumber() )
        .pipe( jshint() ) // 2
        .pipe( jshint.reporter( 'default' ) ) // 2
        .pipe( concat( 'bundle.js' ) ) // 3
        .pipe( gulp.dest( './js' ) );
} );

// compress js file(s)
gulp.task( 'js.compress', function() {
    gulp.src( './js/bundle.js' )
        .pipe( plumber() )
        .pipe( uglify() ) // 4
        .pipe( rename( 'bundle.min.js' ) ) // 5
        .pipe( gulp.dest( './js' ) );
} );

では解説していきましょう。

// 1 – 対象ファイルを指定

結合するファイルを指定している部分なんで、今までとそれほど書き方もかわらないんですが、少し違うことにお気づきになりましたか?

本来であれば、./src/assets/js/**/*.jsのように、jsディレクトリにあるJSファイルをすべて結合してしまう形でも良いのですが、WordPress開発環境のことも考えて、今回は結合するファイル名を指定する形にしています。

// 2 – jshintで構文をチェック

jshintプラグインを使って、JavaScriptの構文チェックを行なっています。構文エラーがある場合にはターミナルに表示されるはずです。

例えば、sample.jsファイルに以下のように書いたファイルを用意しました。

jQuery(function($){
    $('.carousel').carousel({
        'interval': 5000,
    });
})

単純に、最後の最後にセミコロンが欠けているコードになります。このコードでファイル結合を行なってみましょう。

$ gulp js.concat

すると、ターミナルには以下のようなエラーが出力されるはずです。

src/assets/js/sample.js: line 5, col 3, Missing semicolon.

1 error

コードの行数もちゃんと教えてくれますし、Missing semicolonと言うような具合に、ちゃんと何が問題なのかも教えてくれます。素敵ですね。

// 3 – ファイルを結合

ファイルを結合して、結合後のファイル名も指定します。今回はbundle.jsというファイル名にしています。

// 4 – uglifyで圧縮

uglify()で圧縮しています。

// 5 – renameで名称を変更

rename()を利用して、ファイル名を変更しています。ここではもともと1つのファイルを圧縮しているだけなので、そのファイルに.minプレフィックスを付けて、bundle.min.jsというファイル名にして出力しています。

これでJavaScriptの結合と圧縮のタスクが完成しました。

オートリロードさせる

ファイルを保存した際に自動的にブラウザをリロード(更新)させてくれる仕組みを作りたいと思います。もう、これがないとマークアップ作業の効率が80%以上ダウンすることは明確です!と言い切れるくらい大切な機能となっています。

ここでは、以下のプラグインを使います。

  • browser-sync

インストールしていきましょう。

$ npm install browser-sync --save-dev

package.jsonの中身はこのようになっています。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.3",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-changed": "^3.2.0",
    "gulp-concat": "^2.6.1",
    "gulp-imagemin": "^4.1.0",
    "gulp-jshint": "^2.1.0",
    "gulp-plumber": "^1.2.0",
    "gulp-rename": "^1.4.0",
    "gulp-sass": "^4.0.1",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-svgmin": "^2.1.0",
    "gulp-uglify": "^3.0.1",
    "imagemin-gifsicle": "^5.2.0",
    "imagemin-jpeg-recompress": "^5.1.0",
    "imagemin-pngquant": "^6.0.0",
    "jshint": "^2.9.6"
  }
}

では、タスクを作ってみましょう。

var browserSync  = require( 'browser-sync' );

// Browser Sync
gulp.task('bs', function() {
    browserSync({
        server: { // 1
            baseDir: "./",
            index: "index.html"
        }
    });
});

// Reload Browser
gulp.task( 'bs-reload', function() {
    browserSync.reload(); // 2
});

// 1 – ローカルサーバー設定

ローカルサーバー設定で、基本となるディレクトリをbaseDirで指定します。今回はプロジェクトのルートを指定しています。例えば、distディレクトリとか、デプロイするデータをまとめたディレクトリなどを指定することもできますね。

indexには、基本となるファイルを指定してあげます。今回は普通の静的ウェブサイトのマークアップを想定しているので、index.htmlを指定しています。

こちらのタスクを動かして見ると、($ gulp bs

[Browsersync] Access URLs:
 --------------------------------------
       Local: http://localhost:3000
    External: http://192.168.10.11:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 --------------------------------------
[Browsersync] Serving files from: ./

という情報がターミナルの方に表示され、自動的にブラウザが立ち上がるはずです。

// 2 – ブラウザのリロード

ブラウザを更新するタスクを作成しておきます。

詳しくはこちらを見るとわかりやすいです。(英語だけど)


それぞれ、$ gulp bsとか$ gulp bs-reloadとかでも実行できますが、この後に書くファイルを監視させるという部分で、上手に使う方法を書きますので、このタスクを個別に使うことはほとんどないかと思います。

ファイルを監視させる

では次にファイルを監視させるタスクを作っていきましょう。ファイルを監視させるというのは、要するにファイルが変更されたかどうかを常に監視させるということです。そして、変更がされたと同時に上でSassのコンパイルブラウザのリロードをさせるような仕組みを作ります。

また、こちらはgulpに備わっている機能を使うので、新しくプラグインをインストールする必要はありません。

では、gulpfile.jsにこのようなコードを書いていきましょう。

//
// Default task
//
gulp.task( 'default', [ 'bs', 'sass', 'js.concat', 'js.compress', 'imagemin' ], function() { // 1
    gulp.watch("./**/*.html", ['bs-reload']); // 2
    gulp.watch("./src/assets/sass/**/*.scss", [ 'sass', 'bs-reload' ]); // 3
    gulp.watch("./src/assets/js/*.js", [ 'js.concat', 'js.compress', 'bs-reload' ]); // 4
    gulp.watch("./src/assets/image/*", [ 'imagemin', 'bs-reload' ]); // 5
});

// 1 – defaultタスクを作成

defaultという名前のタスクを作ります。しかし、このdefaultという名前で作られたタスクは、今までのように$ gulp defaultと入れなくても以下のように打つだけで動かすことができます。

$ gulp

とても短いですね。入力も楽だし、一番使うコマンドになるので、それをdefaultタスクに設定しておくと便利です。

そして、このdefaultタスクを実行した際にまず動くのが、bssassjs.concatjs.compressimageminと設定してあります。

これは、まずdefaultタスクを実行した際に、これら全てのタスクを一度実行させるために書いてあります。まずは現状のファイルを全てコンパイルしたり圧縮したりしてくれるということですね。

// 2 – htmlファイルに変更があればブラウザをリロードする

ルート直下とそのフォルダにあるhtmlファイルに変更が加えられた際には、bs-reloadタスクを実行してください、という命令が書いてあります。

このgulp.watchという部分が監視をさせる命令になります。以下、全て同じように書いてあることがわかると思います。

// 3 – Sassファイルに変更があればコンパイルしてブラウザをリロードする

./src/assets/sass/ディレクトリ以下にあるscssファイルに変更が加えられた際には、sassタスクとbs-reloadタスクが実行されます。

// 4 – JavaScriptファイルに変更があれば、結合・圧縮してブラウザをリロードする

./src/assets/js/ディレクトリ以下にあるjsファイルに変更が加えられた際には、js.concatタスクとjs.compressタスク、そしてbs-reloadタスクが実行されます。

// 5 – 画像ファイルに変更があれば、圧縮をしてブラウザをリロードする

./src/assets/images/ディレクトリ以下にあるjpeg, png, gif, svgファイルに変更が加えられば際には、imageminタスクが実行され、そしてbs-reloadタスクが実行されてブラウザがリロードされます。

完成コードと再利用方法

では、ここまでのgulpfile.jsを掲載しておきます。

var gulp         = require( 'gulp' );
var sass         = require( 'gulp-sass' );
var autoprefixer = require( 'gulp-autoprefixer' );
var plumber      = require( 'gulp-plumber' );
var sourcemaps   = require( 'gulp-sourcemaps' );
var changed      = require( 'gulp-changed' );
var imagemin     = require( 'gulp-imagemin' );
var imageminJpg  = require( 'imagemin-jpeg-recompress' );
var imageminPng  = require( 'imagemin-pngquant' );
var imageminGif  = require( 'imagemin-gifsicle' );
var svgmin       = require( 'gulp-svgmin' );
var concat       = require( 'gulp-concat' );
var jshint       = require( 'gulp-jshint' );
var rename       = require( 'gulp-rename' );
var uglify       = require( 'gulp-uglify' );
var browserSync  = require( 'browser-sync' );

// Sass
gulp.task( 'sass', function(){
    gulp.src( './src/assets/sass/**/*.scss' )
        .pipe( plumber() )
        .pipe( sourcemaps.init() )
        .pipe( sass( {
            outputStyle: 'expanded'
        } ) )
        .pipe( autoprefixer( {
            browsers: ['last 2 version', 'iOS >= 8.1', 'Android >= 4.4'],
            cascade: false
        } ) )
        .pipe( sourcemaps.write( './' ) )
        .pipe( gulp.dest( './css/'))
} );

// imagemin
gulp.task( 'imagemin', function() {
    // jpeg,png,gif
   gulp.src( './src/assets/images/**/*.+(jpg|jpeg|png|gif)' )
       .pipe( changed( './images' ) )
       .pipe( imagemin( [
           imageminPng(),
           imageminJpg(),
           imageminGif({
               interlaced: false,
               optimizationLevel: 3,
               colors: 180
           } )
       ] ) )
       .pipe( gulp.dest( './images/' ) );
   // svg
   gulp.src( './src/assets/images/**/*.+(svg)' )
       .pipe( changed( './images' ) )
       .pipe( svgmin() )
       .pipe( gulp.dest( './images/' ) );
} );

// concat js file(s)
gulp.task( 'js.concat', function() {
    gulp.src( [
        './src/assets/js/sample.js'
    ] )
        .pipe( plumber() )
        .pipe( jshint() )
        .pipe( jshint.reporter( 'default' ) )
        .pipe( concat( 'bundle.js' ) )
        .pipe( gulp.dest( './js' ) );
} );

// compress js file(s)
gulp.task( 'js.compress', function() {
    gulp.src( './js/bundle.js' )
        .pipe( plumber() )
        .pipe( uglify() )
        .pipe( rename( 'bundle.min.js' ) )
        .pipe( gulp.dest( './js' ) );
} );

// Browser Sync
gulp.task('bs', function() {
    browserSync({
        server: {
            baseDir: "./",
            index: "index.html"
        }
    });
});

// Reload Browser
gulp.task( 'bs-reload', function() {
    browserSync.reload();
});

//
// Default task
//
gulp.task( 'default', [ 'bs', 'sass', 'js.concat', 'js.compress', 'imagemin' ], function() {
    gulp.watch("./**/*.html", ['bs-reload']);
    gulp.watch("./src/assets/sass/**/*.scss", [ 'sass', 'bs-reload' ]);
    gulp.watch("./src/assets/js/*.js", [ 'js.concat', 'js.compress', 'bs-reload' ]);
    gulp.watch("./src/assets/image/*", [ 'imagemin', 'bs-reload' ]);
});

package.jsonはGitHubに上げておきますでの、よかったら使ってください。

再利用の方法ですが、とっても簡単です。

  1. プロジェクトディレクトリにpackage.jsongulpfile.jsを設置
  2. npm initでプロジェクト名など必要情報を変更
  3. npm installでpackage.jsonに書かれている必要なプラグインを一括でインストール

これで完了です。あとは、src/assetsディレクトリを作って、必要なファイルを作っていくだけです。

WordPress開発環境は、こちらの記事で作成したセットをベースに別途記事を書こうと思いますので、しばしお待ちください。

— 追記 —

WordPress開発環境記事はこちらになります。

書籍を出版しました!

WordPress デフォルトテーマ Twenty Twenty-Four を使って、シンプルなブログやポートフォリオサイト、そしてコーポレートサイトを作りながら、ブロックテーマやサイトエディターの基本を理解することができます。