VSCodeでGulpを実行しJavaScriptとSassをビルドしてBrowserSyncでライブプレビューする方法


TOWN Advent Calendar 2018 1日目の記事です。

弊社は9割開発者の弊社においてなので、デザイナーがやっていること・出来ることを知らない人も多いと思います。

ならばデザイナーの自分から一発目をかましたろと思い、エンジニアとも共通の話題にしやすい自分のフロントコーディング環境について紹介します。フロント始める人の参考になれば。

※以下はGulp3の内容です。Gulp4に対応した内容を新たに書きました。

どんな環境?

  • Node.jsインストール済みの環境で
  • エディタにVSCode使って
  • タスクランナーにGulpを利用して
  • SassをCSSにコンパイルし
  • BrowserSyncでライブプレビューしています。

こんな環境で書いてます。

前提&用語

VSCode

みんな大好きVisual Studio Code.

VSCodeに限らずAtomなどターミナルを内包したエディタなら何でも良いです。Gulpはターミナルで実行するので、別にターミナルを起動するより楽なためです。

Node.js & npm

サーバサイドで動作するJavaScriptです。
ググれば質の高い情報がゴロゴロあるのでNode.jsについて説明は省きます。

npmはNode.jsで動作するアプリケーションのパッケージ管理サービスです。
Node.jsをインストールしてnpmが使える状態が前提になります。

Gulp

GulpとはNode.jsベースで動作するタスクランナーです。

タスクランナーとはフロントエンドコーディングで頻発する様々な細かいタスクを自動化してくれるナイスガイです。例えば以下のようなことができます。

  • sass、babelなどのコンパイラ実行
  • 各種コードのLint
  • コードの圧縮、整形
  • 画像変換
  • ライブプレビュー
  • その他色々

タスクランナーにはいくつかの種類があり、自分はGruntから使い始めましたがGulpの方が設定しやすく移行しました。

Sass

SassとはCSSを簡単に書くためのメタ言語です。

SassにはCSSコーディングの時間を短縮できる様々な機能があります。最も分かりやすい例だと、CSSで頻発する以下のようなネスト構造を簡単に書くことができる点です。

.hoge {width:100px}
.hoge p {margin:20px}
.hoge a {color:#f00}

↓Sassの書き方

.hoge {
  width:100px;
  p {margin:20px}
  a {color:#f00}
}

Sassの他の機能にも興味があればググってください。

Sass記法のままではブラウザでは読まれないため、GulpでSassをCSSにコンパイルします。

少し補足ですが、Sassで使われるファイルは.scssファイルになります。.sass形式もありますが少し記法が異なり、素のCSSと共存できる.scssの方がメジャーなためこちらを使います。

ディレクトリ構成

以下のディレクトリ構成を前提にします。

project(名前自由)
├dist/
│ ├css/
│ └js/
└src/
  ├js/
  └scss/
  • dist : 公開用フォルダ、基本いじらない
  • src : 編集用フォルダ、こちらをいじる

src以下のファイルを編集したらGulpでdist以下に出力する流れです。

では環境を作っていきます。

プロジェクトの初期化

VSCodeで project フォルダを開きます。ターミナルの起点が project になるので、ターミナルで以下のように打ちます。

npm init -y

これでプロジェクトに package.json というファイルが作られます。

package.json にはプロジェクト情報やインストールしたnpmのパッケージ情報が記録されます。内容は今はまだ気にしなくて良いです。

Gulpと各種モジュールのインストール

次にGulpをインストールします。

npm i gulp -D

これでプロジェクトにgulpがインストールされました。

Gulp単体では何もできないので用途に応じてモジュールを入れていきます。

npm i gulp-notify -D        //Gulpのエラー通知をしてくれるモジュール
npm i gulp-plumber -D       //Gulpで実行エラーが起きてもプロセスを落とさず続けてくれるモジュール
npm i gulp-sass -D          //GulpでSassを扱えるようになるモジュール
npm i gulp-autoprefixer -D  //CSSに自動でベンダープレフィックスを入れてくれるモジュール
npm i gulp-uglify -D        //JavaScriptを難読化&Minifyしてくれるモジュール
npm i browser-sync -D       //ライブプレビューできるようになるモジュール

インストールしたモジュールは project フォルダ直下の node_modules フォルダにインストールされています。

ここで一旦 node_modules フォルダをまるごと削除してから以下のコマンドを打ってください。

npm install

モジュールが再インストールされ node_modules フォルダが元に戻ったと思います。

インストール時に付けた -D のオプションで package.json にインストール情報が記録されていたため install コマンド一つで全てのモジュールが再インストールできます。 package.json さえ残していればnpmで構築した環境をいつでもどこでも復元できます。

gulpfile.js の作成

gulpfile.js とはGulpに実行させる内容をまとめた設定ファイルです。
project フォルダ直下に gulpfile.js を作り以下のように打ちます。

gulpfile.js
var gulp         = require('gulp');
var notify       = require("gulp-notify");
var plumber      = require("gulp-plumber");
var sass         = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var uglify       = require('gulp-uglify');
var browserSync  = require("browser-sync");

まず利用するモジュールを読み込みます。

それではタスク別にgulpfile.jsへ追記していきます。

パスの記述

パスの記述を多用するため変数に入れておきます。

gulpfile.js
//パス設定
var paths = {
  'html'   : './dist/',
  'scss'   : './src/scss/',
  'css'    : './dist/css/',
  'jsSrc'  : './src/js/',
  'jsDist' : './dist/js/'
}

単に自分の書き方のクセなのでコード内で逐一パスをハードコーディングしても問題ありませんが、このように設定しておいた方が楽だと思います。

Sassのタスク記述

Sassを使えるようにするためのタスクを追記します。

gulpfile.js
//Sass
var sassOptions = {
  outputStyle: 'compressed'//圧縮設定 nested, expanded, compact, compressed
}
gulp.task('sass', function () {
  gulp.src(paths.scss + '**/*.scss')
    .pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") }))
    .pipe(sass(sassOptions))
    .pipe(autoprefixer())
    .pipe(gulp.dest(paths.css))
});
  • /src/scss/以下で*.scssファイルが更新されたら
  • Gulpエラーチェックを通して
  • Sass変換を通して
  • 自動ベンダープレフィックスを通して
  • /dist/css/フォルダに書き出す

といった流れです。
pipeでモジュールを繋げていくだけなので何をしているのか読みやすいですね。

なお処理の頭でsassOptionsにSass変換時のオプションを入れています。自分的にはMinifyするだけで十分なので、さらに凝ったオプションを試したい方はググってください。

JavaScript圧縮のタスク記述

JSを圧縮するためのタスクを追記します。

gulpfile.js
//JS圧縮
gulp.task('js', function () {
  gulp.src(paths.jsSrc + '**/*.js')
    .pipe(plumber())
    .pipe(uglify())
    .pipe(gulp.dest(paths.jsDist));
});

このJS圧縮もなかなか有能で、コードの短縮、Minify、難読化を同時にやってくれます。

BrowserSyncのタスク記述

ライブプレビューできるようにするタスクを追記します。

gulpfile.js
//BrowserSync
gulp.task('browser-sync', () => {
  browserSync({
    server: {
      baseDir: paths.html
    }
  });
  gulp.watch(paths.html + "**/*.html", ['reload']);
  gulp.watch(paths.css + "**/*.css", ['reload']);
  gulp.watch(paths.jsDist + "**/*.js", ['reload']);
});
gulp.task('reload', () => {
  browserSync.reload();
});

srcフォルダのファイルを監視し、更新されたらブラウザがリフレッシュされる仕組みです。

タスク自動実行の記述

ここまで作ったタスクを自動的に実行するためのタスクを作ります。

これまでのコードでSassやJS圧縮用のsass jsというタスクを作っていましたが、これらを実行するには

gulp sass
gulp js

と、Sassをコンパイルしたい時、JSを圧縮したい時に毎度打つ必要があり猛烈に面倒です。

そこで以下のコードを最後に書きます。

gulpfile.js
//watch
gulp.task('watch', function () {
  gulp.watch(paths.scss + '**/*.scss', ['scss']);
  gulp.watch(paths.jsSrc + '**/*.js', ['js']);
});

gulp.task('default', ['browser-sync', 'watch']);

watchdefault のタスクを追加します。

コンソールで以下のように打つことで default のタスクが実行されます。

gulp

default は同時にbrowser-syncwatch も実行するので、今回やりたい事をこれ一つで実行できるようになりました。

以上でgulpfile.js全体は以下のようになります。

gulpfile.js
var gulp         = require('gulp');
var notify       = require("gulp-notify");
var plumber      = require("gulp-plumber");
var sass         = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var uglify       = require('gulp-uglify');
var browserSync  = require("browser-sync");

//パス設定
var paths = {
  'html'   : './dist/',
  'scss'   : './src/sass/',
  'css'    : './dist/css/',
  'jsSrc'  : './src/js/',
  'jsDist' : './dist/js/'
}

//Sass
var sassOptions = {
  outputStyle: 'compressed'
}
gulp.task('scss', function () {
  gulp.src(paths.scss + '**/*.scss')
    .pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") }))
    .pipe(sass(sassOptions))
    .pipe(autoprefixer())
    .pipe(gulp.dest(paths.css))
});

//JS圧縮
gulp.task('js', function () {
  gulp.src(paths.jsSrc + '**/*.js')
    .pipe(plumber())
    .pipe(uglify())
    .pipe(gulp.dest(paths.jsDist));
});

//BrowserSync
gulp.task('browser-sync', () => {
  browserSync({
    server: {
      baseDir: paths.html
    }
  });
  gulp.watch(paths.html + "**/*.html", ['reload']);
  gulp.watch(paths.css + "**/*.css", ['reload']);
  gulp.watch(paths.jsDist + "**/*.js", ['reload']);
});
gulp.task('reload', () => {
  browserSync.reload();
});

//BrowserSync
gulp.task('browser-sync', () => {
  browserSync({
    server: {
      baseDir: paths.html
    }
  });
  gulp.watch(paths.html + "**/*.html", ['reload']);
  gulp.watch(paths.css + "**/*.css", ['reload']);
  gulp.watch(paths.jsDist + "**/*.js", ['reload']);
});
gulp.task('reload', () => {
  browserSync.reload();
});

//watch
gulp.task('watch', function () {
  gulp.watch(paths.scss + '**/*.scss', ['scss']);
  gulp.watch(paths.jsSrc + '**/*.js', ['js']);
});

gulp.task('default', ['browser-sync', 'watch']);

Gulpの実行

ターミナルで以下のように打ちます。

gulp

すでに書いた通りですが、これでdefaultに指定したタスクが実行され、Gulpが監視状態に入ります。Browser Syncも起動し、ブラウザの新規タブでdistフォルダ直下のindexが表示されます。

あとはsrcフォルダ以下のscssファイルやjsファイルを編集することでdist以下にモリモリ出力され、Browser Syncで起動したブラウザのタブでライブプレビューが動くという寸法です。


近頃はそもそもフロントのコードを書くこと自体が忌避されがちですが、何だかんだ細かい調整は必要だしGulp対応しているフロントエンドのフレームワークも多いので、Gulpで楽しくコード書いていきましょう。