matsuo

Babel と watchify で ES2016 のビルド環境を作る

JavaScript の新仕様である、ECMAScript 2016 (以下ES2016) がリリースされました。

ES2015 はもう普通にバリバリ使ってるよという方も多いと思いますが、まだ手を出していない、って人も結構いらっしゃるかと思います。ES2015 などを使ってコードを書きはじめるにあたり、まずはビルド環境を用意するのが最初のハードルかなと思いますので、今回は Babel と browserify, watchify などを使ったビルド方法を紹介します。

※ なお、今回のサンプルコードは GitHub のこちらにも置いています
https://github.com/tam-matsuo/gulp-watchify-es2016

ES2015, ES2016 とは

ES2015 は名前のとおり 2015年6月に公開された、JavaScript の言語仕様です。ES5 の次バージョンにあたるので ES6 とも呼ばれていましたが、今後毎年のように仕様が改訂されるため、ES2015, ES2016… と年号で呼ばれるようになりました。
ES2016 は2016年6月に公開された、2016年版の最新仕様です。

これまでの JavaScript との違いはググるとたくさん出てきますので、詳しくはそちらに譲りますが、たとえば

  • クラスと継承
  • import, export によるモジュール管理
  • アロー関数 (=> 記法)

などなど、ES5 からたくさんの機能追加が行われています。

とりあえず簡単なところでいうと、テンプレートリテラルだけでも便利です、文字列と変数の扱いが楽に書けます。こんな感じ。

// 従来の書き方 (+記号で接続する)
console.log(name + " さんのポイントは " + point + "点です");

// ES2015 の新機能、文字列内に変数を埋め込める
console.log(`${name} さんのポイントは ${point}点です`);

gulp と Babel で環境を作る

ES2015 や ES2016 についてはブラウザによって対応状況が異なっており、現時点では ES5 のコードに変換(トランスパイル)して動かすことになります。すごく大雑把にいうと、SCSS を CSS に変換するのに近いひと手間が必要というイメージです。

今回はみなさまお馴染みの gulp に、以下のようなパッケージを組み合わせて ES2016 のビルド環境を作ります。

  • browserify
    複数のJavaScriptファイルを1つにまとめてビルドするパッケージ
  • babelify
    Babel (ES2016などのコードを ES5 に変換するツール) の browserify対応版
  • watchify
    ファイルの更新を監視して、高速に再ビルドを行ってくれるパッケージ

まずは、ES2016 を ES5 に変換する gulpタスクを作ってみます。

パッケージのインストール

最初に npm を使って、必要なパッケージのインストールを行います。

npm init -y
npm install -D gulp browserify babelify babel-preset-es2016 vinyl-source-stream

Babel の設定ファイルを作る

Babel に「ES2016を使うよ〜」という設定が必要ですので、以下のような .babelrc というファイルを設置します。

.babelrc

{
  "presets": [
    "es2016"
  ]
}

gulpfile を作る

gulpfile にビルド用のタスクを記述します。
今までどおり ES5 の文法で gulpfile を書いてもよいのですが、今回はせっかくなので ES2015以降の文法を使ってみます。その際、ファイル名は gulpfile.babel.js としてください。

gulpfile.babel.js

import gulp from 'gulp';
import browserify from 'browserify';
import babelify from 'babelify';
import source from 'vinyl-source-stream';

gulp.task('build', () => {
  // `src/scripts/main.js` を `assets/scripts.js` にビルド
  browserify({
    entries: ['src/scripts/main.js'],
    transform: ['babelify']
  })
  .bundle()
  .pipe(source('scripts.js'))
  .pipe(gulp.dest('assets/'));
});

コードを書く

実際のコードを書きます。
以下の例は、単純に main.js から sample.js をインポートし、その中で console.log() で文字列を出力するだけのサンプルです。

src/scripts/main.js

import sample from './sample.js';
sample();

src/scripts/sample.js

export default () => {
  const name = 'ES2016';
  console.log(`hello ${name}!!!`);
};

ビルドする

以上で準備は整いましたので、ビルドしてみましょう。
ターミナルから gulp build と叩けば src/scripts/main.js のビルドが始まり、assets/scripts.js というファイルが生成されます。
出来上がった scripts.js を実行すると、コンソールに

hello ES2016!!!

と出力されました。
これで ES2016 のビルド環境の完成です。

※ ここまでのコードは、こちらに置いています。
https://github.com/tam-matsuo/gulp-watchify-es2016/tree/babel-browserify

watchify で、ファイルが変更されたら再ビルドさせる

実作業ではファイルの変更を監視して再ビルドしてもらいたいので、 watchify というパッケージを設定します (watchify は、差分だけを高速に再ビルドしてくれるものです)。さらに、sourcemap の出力や uglify も欲しいよね、ということでそちらも追加していきます。

追加パッケージのインストール

watchify, sourcemaps, uglify とその関連パッケージを追加。

npm install -D watchify gulp-sourcemaps gulp-uglify vinyl-buffer gulp-load-plugins

gulpfile を変更

以下のように watch するタスクを追加しました。
また、ビルド時には sourcemap の作成や uglify の処理も含めています。

gulpfile.babel.js

import gulp from 'gulp';
import browserify from 'browserify';
import babelify from 'babelify';
import watchify from 'watchify';
import buffer from 'vinyl-buffer';
import source from 'vinyl-source-stream';
import gulpLoadPlugins from 'gulp-load-plugins';
const $ = gulpLoadPlugins();

function bundle(watching = false) {
  // `src/scripts/main.js` を `assets/scripts.js` にビルド
  const b = browserify({
    entries: ['src/scripts/main.js'],
    transform: ['babelify'],
    debug: true,
    plugin: (watching) ? [watchify] : null
  })
  .on('update', () => {
    bundler();
    console.log('scripts rebuild');
  });

  function bundler() {
    return b.bundle()
      .on('error', (err) => {
        console.log(err.message);
      })
      .pipe(source('scripts.js'))
      .pipe(buffer())
      .pipe($.sourcemaps.init({loadMaps: true}))
      .pipe($.uglify())
      .pipe($.sourcemaps.write('./'))
      .pipe(gulp.dest('assets/'));
  }

  return bundler();
}

gulp.task('build', () => {
  bundle();
});

gulp.task('watch', () => {
  bundle(true);
});

ビルドする

以上で準備完了です。
gulp build がビルドで、 gulp watch が watch(監視)です。watch 時には、JavaScript ファイルが更新されると自動的に再ビルドが行われます。生成されたファイルは uglify されており、同じフォルダに scripts.js.map という名前で sourcemap も出力されているかと思います。

こんな感じで、ES2016 のコードを書いていける環境ができあがりました。

※ ここまでのコードは GitHub のこちら。
https://github.com/tam-matsuo/gulp-watchify-es2016/tree/babel-watchify

SCSSのビルドと browser-sync 機能も追加してみる

ついでに SCSS のビルドと、browser-sync 用のタスクを追加した gulpfile も用意しました。
特別な設定はしていませんし、長くなるので今回は説明を省きますが、こちらにサンプルコードを置いていますのでご参考になればと思います。

https://github.com/tam-matsuo/gulp-watchify-es2016

まとめ

ES2015以降で追加された機能はたくさんあり、すべてを一度に覚えるのは大変かもしれません。
ただ、テンプレートリテラルやアロー関数などは小規模のコーディングからでも便利に使えますし、まずは手軽なところから試して慣れていけると良いのではないでしょうか。
これらは JavaScript の標準仕様であり、今後も使う機会が増えていくことは間違いないでしょう。思い立った時にすぐに試せるよう、環境をひとつ用意しておくのも良いかと思います。

参考

新しいウェブ体験を作ろう TAMのPWA開発
お問い合わせはこちら