はじめに
自分のNodeプロジェクトでbabelを入れてみる事にしました。minifyはgulpでやっていたのですが、babelで出来る事が分かったので切り替えました。その過程でいくつか躓いたのでメモを残しておきます。
環境
Debian 9.3
node v8.9.4
npm 5.6.0
ちなみにwindowsでも確認してあります。
前準備
まずプロジェクトとテストに使うjsファイルを作成します。
$ mkdir babel-test
$ cd babel-test
$ mkdir js
$ echo '[1, 2, 3].map((n) => n + 1);' > ./js/example.js
これで次のようなファイルが出来ました。プログラムは公式の例を参考にしています。
[1, 2, 3].map((n) => n + 1);
次に必要なモジュールを入れていきます。
$ npm init -y
$ npm install babel-cli babel-preset-env babel-minify babel-preset-minify rimraf -D
なお、既存のプロジェクトに追加した時は、Cannot find module core-js/library/fn/object/key
のようなエラーが出て動きませんでした。この時はnode_modulesを全て消して、モジュールを新しくインストールし直したら解決しました。
babel-cliを試す
トランスコンパイルするコマンドがbabel-cli
です。次のように実行出来ます。
$ ./node_modules/.bin/babel ./js/ -d ./jsts
js/example.js -> jsts/example.js
成功したっぽいのでファイルを確認しましょう。
[1, 2, 3].map(n => n + 1);
、、、変わってません。
公式にも書いてありますが、ちゃんとトランスコンパイルするようには、.babelrc
でbabel-preset-env
を使うように設定する必要があります。
$ touch .babelrc
次のように編集します。
{
"presets": ["env"],
}
これで試してみます。
$ ./node_modules/.bin/babel ./js/ -d ./jsts
js/example.js -> jsts/example.js
次のようにアロー関数が普通の関数になっています。
"use strict";
[1, 2, 3].map(function (n) {
return n + 1;
})
Production環境でminifyする
さて、次にminifyですが、出来たらproduction環境だけでminifyしたいですよね。(デバッグが面倒すぎるので)
.babelrcを次のように設定します。
{
"presets": ["env"],
"env": {
"production": {
"presets": ["minify"]
}
}
}
"env"はpresetsのenvと混合しそうですが別物で、環境変数によって設定を変える時に使います。環境変数の設定方法は公式ドキュメントに書いてあります。今回はexportでBABEL_ENVの設定を変えます。なお、Windowsの場合はSET BABEL_ENV=production
です。
$ export BABEL_ENV=production
$ ./node_modules/.bin/babel ./js/ -d ./jsts
Error: Cannot read property 'contexts' of null
何故かエラーになりました。試しに次のようにコマンドを直接実行してみます。
$ ./node_modules/.bin/minify ./js/ -d ./jsts
Error: Cannot read property 'contexts' of null
これ以外にもError: Couldn't find intersection
などのエラーが出る事もありました。色々とググって解決法を見つけたので、試してみました。
{
"presets": [
"env"
],
"ignore": [],
"env": {
"production": {
"presets": [
[
"minify",
{
"builtIns": false,
"evaluate": false,
"mangle": false
}
]
]
}
}
}
$ ./node_modules/.bin/babel ./js/ -d ./jsts
js/example.js -> jsts/example.js
"use strict";[1,2,3].map(function(a){return a+1});
出来た \(^^)/
presets
について
さて、.babelrcの"env"は環境変数によって処理を切り替える、、、と書きましたが、これは少し間違いです。例えば次の例を見て下さい。
{
"presets": ["env"],
"env": {
"production": {
"presets": ["minify"]
}
}
}
上記の設定でbabelコマンドを実行すると、production環境ではbabel-preset-env
の処理を行った後に、babel-preset-minify
が処理されます。つまりパイプされています。上記の書き方だとpresets
が上書きされているわけではない事に注意して下さい。試しに一行目の"presets": ["env"]
を削除して実行すると、次のようにminifyだけされたファイルが出力されます。
コンパイルを簡単にする
上記のコマンドを毎回入れるのは面倒ですので、npm run buildでコンパイル出来るようにしましょう。 "script"の所に次の一行を追加します。
"scripts": {
"build": "./node_modules/.bin/rimraf ./jstc && ./node_modules/.bin/babel ./js/ -d ./jsts",
},
rimrafはフォルダを消すコマンドです。一旦クリーンアップしてから新たに作るようにしています。
なお、Windowsの場合は".\\node_modules\\.bin\\babel"
のようなパスの書き方でないと動きませんでした。
さてコマンドを実行しましょう。
$ npm run build
> babel-test@1.0.0 build ~/babel-test
> babel ./js/ -d ./jsts
js/example.js -> jsts/example.js
出来た v(^^)v
まとめ
今回はひとまずminifyまで試したかったのでここまでですが。まだ色々とやる事はありそうなので、順次更新しようと思います。