Babelを使ってみる
Babel、どんなツールか知っていたけれど使ったことなかったので試してみます。
webpack + Babelで使うのをよく見ますが、とりあえずBabelだけコマンドラインから使ってみます。
Babelとはなにか
簡単に言うと、新しいJavaScriptの書き方で書いたコードを古い書き方のコードへ変換するツールです。
なぜせっかく新しい構文で書いたのにわざわざ古い方へ変換しなきゃいけないかというと、
ブラウザごとにJavaScriptの新バージョンへの対応状況が違うので、新しい書き方だと動いてくれないブラウザがあるからです。(※IEとかIEとかIEとかね)
ということで、Babelを使って変換すればブラウザが対応してない構文でも気にせずコーディングできます。
Babelの環境構築
実行環境
- Node.js: 11.10.1
- npm: 6.7.0
npmで必要なパッケージをインストールします。
インストールする前にnpm init -y
でpackage.json
を作っておきます。
$ npm install --save-dev @babel/core @babel/cli @babel/preset-env
設定ファイル
babel.config.js
というファイルを作って、ここにBabelの設定を書いていきます。
const presets = [ ['@babel/preset-env', { 'targets': { 'ie': '11', 'chrome': '58' } }] ]; module.exports = { presets }
使用するプリセット(@babel/preset-env
)と、targets
にサポートするブラウザのバージョンを指定します。
指定した環境を最低限サポートするよう変換してくれます。
Babel実行
試しに以下のJavaScriptを変換してみます。
どれもIE11では対応していないECMAScript2015の構文で書いてみました。
index.js
const add = (a, b) => a + b; class Person { constructor(age, name) { this.age = age; this.name = name; } toString() { return `name=${this.name}, age=${this.age}`; } } const numbers = [1, 2, 3, 4, 5]; for (const number of numbers.map(x => x * 2)) { console.log(number); }
次にpackage.json
にBabelの実行コマンドを登録しておきましょう。
ここでは、src
というフォルダに先程のindex.js
を用意して変換してみます。
-o
オプションで変換後のファイルを出力できます。dist
フォルダに出力することにします。
"scripts": { "build": "./node_modules/.bin/babel src/index.js -o dist/index.js" },
保存したらpackage.json
がある場所で
$ npm run build
変換後のindex.js
"use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var add = function add(a, b) { return a + b; }; var Person = /*#__PURE__*/ function () { function Person(age, name) { _classCallCheck(this, Person); this.age = age; this.name = name; } _createClass(Person, [{ key: "toString", value: function toString() { return "name=".concat(this.name, ", age=").concat(this.age); } }]); return Person; }(); var numbers = [1, 2, 3, 4, 5]; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = numbers.map(function (x) { return x * 2; })[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var number = _step.value; console.log(number); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } }
はい。ちゃんとアロー関数やクラス、for ofループが変換されています。
for ofループのとこなんかぱっと見た感じ何やってんのか分からないレベルですね...
他にもいろいろ設定があったりするのですが、とりあえずES2015の構文が変換できればいいということで終わりにします。