JavaScriptの新基準であるES6(ES2015=ECMAScript2015)を利用する方法として、Babelによるトランスパイルがあります。
今回の記事ではこのBabelの入門的な使い方やブラウザの対応状況などをまとめました。また、インストールの流れ&設定や、Gulp、AtomなどからBabelを介して自動的にコンパイルする方法もご紹介します。
なぜBabelが必要なのか?
まず、なぜBabel(=トランスコンパイラ)が必要なのか?という疑問がありますが、一言で言うと「全てのブラウザがES6に対応していないから」になります。
普通にES6でJavaScriptを書いて、そのまま実行できれば何の問題もないのですが、現状ではブラウザが完全にES6に対応していません。そのため、ES6で書いたJavaScriptをES5に変換してから利用する必要があります。
この辺りはES6のブラウザ対応状況をチェックすると納得できます。(執筆時点で100%対応しているブラウザはsafari10以降とiOS10くらいです。まだまだですね…)
それなら「最初からES5で書けばいいのでは?」とも思いますが…現状ではES6によるメリットもデメリットもあります。
- 最終的に何を作るのか?(アプリ?Webサイト?)
- 使用するフレームワークやプラグイン
- 開発環境やチーム(プロジェクト)の規模
などによって、ES6やBabelを利用すべきかどうかは変わってくると思います。
Node.jsやReactを使っていて「Babelは必須だよ」という人もいれば、Webサイト作成で簡単なJavaScript(jQuery)しか使わないから、学習コストが…という人もいると思います。
とりあえずBabelを試してみたい
何はともあれ、とりあえずBabelってどんな感じになるのか試したいという方は、Babelの公式サイト上でコンパイルすることができます。
下記のように左側にES6で書いたコードを入力すれば、右側にトランスパイルされます。
// before
const hoge = (name) => {
console.log(name);
};
hoge('taro');
// after
'use strict';
var hoge = function hoge(name) {
console.log(name);
};
hoge('taro');
変数宣言のconst
がvar
に変換されていたり、アロー関数がfunction
に変換されているのが分かるかと思います。
開発環境でコンパイルせずに、クライアント側(ブラウザ)でコンパイルする方法
前置きが長くなってすみませんが、本題(Babelをインストールして使う方法)の前にもう一つだけ。
基本的には、
- Babelをインストール
- ES6をコンパイル
- コンパイルしたコードを読み込む
という流れなのですが、Webサイトの場合ですとブラウザから直接Babelを読み込む方法もあります。ES6のコードをそのまま記述しておき、クライアント側(ブラウザ)で読み込まれる時にコンパイルしてもらおう、ということですね。
やり方は簡単で、下記のようにCDNなどからbabel-standaloneを読み込むだけです。
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
const hoge = (name) => {
alert(name);
};
hoge('taro');
</script>
ただし、普通に考えてブラウザの負荷が増えるのは・・と思うので、特殊な場合(※1)を除いては開発環境(ローカル)でコンパイルしておくことをお勧めします。
※1:ユーザーが入力したコードをリアルタイムでコンパイルしたい等
【本題】Babelの使い方
さて、やっと本題に入ります。これからBabelをインストールしてES6をコンパイルするまでの流れを順番に追っていきます。
環境としては、
- OS:Mac
- node.jsとnpm がインストールされている
という状態を想定しています。
babel-cliをインストール
// プロジェクトフォルダへ移動
cd myproject
// package.jsonを作成
npm init
(色々聞かれるので全てEnter)
// babel-cliをインストール
npm install --save-dev babel-cli
babel-cli
のインストール先として、グローバル(-g
)が良いのかローカル(--save-dev
)が良いのか、という論点がありますが、とりあえず今回はローカルにインストールしています。ちなみに公式サイトではローカルが推奨されています。
.babelrcを作成
プロジェクトフォルダのルートにBabelの設定ファイルである.babelrc
を作成します。
利用するPresetをインストールし、.babelrcで設定
ES6からES5にコンパイルしたい場合は、babel-preset-es2015というPresetをインストールし.babelrc
へ記述します。
// babel-preset-es2015をインストール
npm install --save-dev babel-preset-es2015
// 下記を.babelrcへ記述
{
"presets": ["es2015"]
}
また、ブラウザのバージョンなどを指定してコンパイルしたいという場合は、babel-preset-es2015ではなくbabel-preset-envというPresetをインストールし.babelrc
へ記述します。
// babel-preset-envをインストール
npm install --save-dev babel-preset-env
// ブラウザやバージョンの指定内容を.babelrcへ記述
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
}]
]
}
コンパイルしてみる
では実際にコンパイルできるか試してみましょう。テスト用にes6.js
というファイルを作って、その中に下記を記述します。
const hoge = (name) => {
console.log(name);
};
hoge('taro');
そしてターミナルで、
./node_modules/.bin/babel es6.js
と入力すると、ターミナルにコンパイルされた結果(下記)が出力されるはずです。
// 出力結果
'use strict';
var hoge = function hoge(name) {
console.log(name);
};
hoge('taro');
また、コンパイルされた結果を別ファイルとして保存したい場合は、-o
を付けて出力先のファイル名を指定します。
// es6.js → main.js にコンパイル
./node_modules/.bin/babel es6.js -o main.js
ソースファイルの変更を常にウォッチして、変更があれば自動的にコンパイルしたい場合は-w
を付けます。
// es6.js → main.js にコンパイル(ウォッチ)
./node_modules/.bin/babel es6.js -w -o main.js
終わりじゃなかった…
無事にコンパイルされて完了!と思ったら、まだ終わりじゃありませんでした…
ES6の機能をフル活用するためには、どうもコンパイルするだけでは不十分とのことです。例えばPromise
などを利用する場合、別途Polyfill
というライブラリも読み込む必要があります。詳しくは公式ドキュメントを。
ということでPolyfillを読み込む
// babel-polyfillをインストール
npm install --save babel-polyfill
上記をインストールすると/node_modules/
にPolyfillのライブラリがインストールされます。その中の/node_modules/babel-polyfill/dist/polyfill.min.js
を読み込むようにすればOKです。コンパイルしたjsよりも先に読み込まれるようにしてください。
なお、Polyfillは絶対に必要なファイルではありません。公式ドキュメントにも記載されている通り、Promise
, WeakMap
のような新しい関数を利用する場合に必要とされます。そのため、コンパイルするscriptの内容によっては無駄な読み込みになる(無くてもエラーにならない)場合もあります。
transform-runtime について
Polyfillを読み込む代わりに、transform-runtimeを利用する方法もあります。transform-runtime
を利用すればコンパイル時にscriptの内容に合わせて必要なライブラリだけを自動的に読み込んでくれます。(長くなるので使い方は次の機会に…)
Gulp編
Gulp(タスクランナー)でBabelを使う方法です。
関連ファイルをインストール
まず、もちろんのことながらgulp
をインストールする必要があります。その他gulp-babel
と、利用するPreset(今回はbabel-preset-es2015
を利用してみる)もインストールします。
// プロジェクトフォルダへ移動
cd myproject
// package.jsonを作成
npm init
(色々聞かれるので全てEnter)
// gulpやgulp-babelをインストール
npm install --save-dev gulp
npm install --save-dev gulp-babel
npm install --save-dev babel-preset-es2015
gulpfile.jsを作成
Gulpの設定ファイル(gulpfile.js
)を作成してタスクを記述します。下記は/src/es6.js
をES5にコンパイルして/lib/
に書き出す、という内容です。
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('babel', function() {
gulp.src('src/es6.js')
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('lib'));
});
コンパイル
ES6で書いたjsを/src/es6.js
に用意し、コンパイルを実行してみます。
// gulp-babelでコンパイル
gulp babel
コンパイルされたJavaScriptが/lib/es6.js
に書き出されたら成功です。
Atom編
Atom(エディタ)でBabelを使う方法です。
パッケージ(language-babel)のインストール・設定
- Atomの設定画面から「language-babel」というパッケージを検索してインストール
- language-babelのSettingで「Allow Local Override」にチェックを入れる
関連ファイルをインストール
// プロジェクトフォルダへ移動
cd myproject
// package.jsonを作成
npm init
(色々聞かれるので全てEnter)
// babel-cliなどをインストール
npm install --save-dev babel-cli
npm install --save-dev babel-preset-es2015
.babelrcを作成し、Presetを記述
{
"presets": ["es2015"]
}
.languagebabelを作成し、設定を記述
language-babelの設定ファイルである.languagebabel
を作成し、設定を記述します。
// 例
{
"babelMapsPath": "lib",
"babelMapsAddUrl": false,
"babelSourcePath": "src",
"babelTranspilePath": "lib",
"createMap": false,
"createTargetDirectories": true,
"createTranspiledCode": true,
"disableWhenNoBabelrcFileInPath": true,
"projectRoot": true,
"suppressSourcePathMessages": false,
"suppressTranspileOnSaveMessages": true,
"transpileOnSave": true
}
コンパイル
上記の設定が上手くいっていれば、ES6で書いたjsを/src/es6.js
に用意し保存することで、コンパイルされたJavaScriptが/lib/es6.js
に書き出されます。(watchされている状態です。保存する度に自動的にコンパイルされます。)
雑感
個人的な意見としては、「フロントエンドエンジニア辛い・・」の一言です(-_-;)