最近業務でReactなどを使う機会が多くなり、BabelやWebpackなどを使うことも多くなってきました。

Babel7の情報はまだ少ない感じなので備忘録的なメモとして残します。

Babel7だけを利用してJavaScriptをトランスパイルしてみました。

Webpackなどは一切使っておらず、Babel7だけの利用なので業務で使う機会は少ないかも。

Babelとは

JavaScriptの変換ツール(トランスコンパイラ)です。

ES7やES6で書かれたJavaScriptを現在の標準ブラウザで動作するES5に変換してくれます。

まだブラウザに実装されていない新しい機能でJavaScriptを書いてもちゃんと動作するように変換してくれます。

constやlet、Promiseやアロー演算子などを使用して書いても変換してくれます。

特にIE野郎を気にせずChromeでデバックしながらコードを書いても大丈夫ってことです!

Babelをインストール

npmを使ってbabelをインストールします。

Babel7からパッケージの指定方法が@babel/~に変更になりました。(Scoped Packages方式)

>npm i -D @babel/core @babel/cli @babel/preset-env
@babel/core
babelのコア、babelの本体です。
@babel/cli
babelをコマンドで利用できるようになります。
@babel/preset-env
指定しているブラウザ環境によって動作するように変換してくるプラグイン

インストール後のpackage.jsonのdevDependenciesは下記のようになります。

"devDependencies": {
  "@babel/cli": "^7.2.3",
  "@babel/core": "^7.4.0",
  "@babel/preset-env": "^7.4.2"
},

Babel7でトランスパイルするのに必要なのはこの3つだけです。

webpackとbabelを合わせて使う記事が多いですが、babelだけならこれだけです。

設定ファイルbabel.config.js

babel用の設定ファイルbabel.config.jsを作成します。

const presets = [
  ["@babel/preset-env", {
    "targets": {
      "ie": 10
    },
    "useBuiltIns":"usage"
  }]
];

module.exports = { presets }

targetsでとりあえずIE10向けにトランスパイルするようにします。

useBuiltInsをusageにすると必要なpolyfillだけ自動でrequireしてくれます。

@babel/polyfillは必要ありません。

JavaScriptを用意

動作確認用のJavaScriptファイルindex.jsを用意します。

const message = "Promise Test.";
Promise.resolve().then(res => console.log(message));

ただコンソールに”Promise Test.”を表示するだけのjsです。

ES6から追加された、constやPromise、アロー関数を使用して書いています。

これをBabelでトランスパイルしてES5に変換します。

ディレクトリ構成

今回のテストのディレクトリ構成です。

babel_test
├node_modules
├public_html
│└js
├src
│└index.js
├babel.config.js
├package-lock.json
└package.json

src/index.jsをトランスパイルしてpublic_html/jsフォルダに保存します。

Babel実行スクリプト追記

package.jsonにBabel実行用のコマンドを追記します。

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "babel-build": "babel src --out-dir public_html/js"
},

これで「npm run babel-build」とコマンドを打てば変換されます。

Babel実行

プロジェクトのトップディレクトリ(babel_test)で実行します。

>npm run babel-build
WARNING: We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default
version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.

You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:

  npm install --save core-js@2    npm install --save core-js@3
  yarn add core-js@2              yarn add core-js@3

Successfully compiled 1 file with Babel.

しかし、この時点ではWARNING(警告)がでます。

トランスパイルしてpublic_html/js/にindex.jsが保存されますが、実行できません。

Babelでトランスパイルしたjsはcore-jsが必要と言った趣旨の警告です。

まだインストールしてなければ「npm install –save core-js@2」を実行しろてきな。

警告への対応

どうせなら最新のバージョンのcoer-jsを使用したいのでv3をインストールします。

>npm install --save core-js@3

Babelはcore-jsのバージョンが指定されていなければcore-js@2.xをデフォルトとして想定しています。

core-js@3を使用るにはbabel.config.jsにcorejsオプションを追記します。

const presets = [
  ["@babel/preset-env", {
    "targets": {
      "ie": 10
    },
    "corejs":3,
    "useBuiltIns":"usage"
  }]
];

module.exports = { presets }

再びbabelを実行

>npm run babel-build
Successfully compiled 1 file with Babel.

今度はサクッと完了します。

public_html/js/index.jsとして保存されています。

requireもcore-js@3を読み込むようになっています。

トランスパイル後のjsを実行

"use strict";

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

var message = "Promise Test.";
Promise.resolve().then(function (res) {
  return console.log(message);
});

Babelでのトランスパイルでconstがvarに変わったり、Promise用のファイルがrequireされたりと変換されています。

これをnodeを使って実行します。

プロジェクトのトップディレクトリ(babel_test)でnodeコマンドを実行します。

>node .\public_html\js\index.js
Promise Test.

無事に「Promise Test.」と表示されれば成功です。

まとめ

Babel7を利用したJavaScriptの変換(トランスパイル)方法を記載しました。

ただ、正直使い道はわかりません。

変換しないでも「nodeはES6実行できるのでは?」と思います。

「IEなどでpromise使えるじゃん!」と思うかもしれませんが、そもそもブラウザではrequireは使えません。

自分でJavaScriptをES6やES7でゴリゴリ書いて、BabelでトランスパイルしてIEに対応させるにはこの方法では無理です。

ブラウザで使用できるjsにするにはもうひと手間必要です。

時間が取れればブラウザで実行する方法を記載します。