しがないエンジニアのブログ

技術的な内容をメモ代わりにつらつら

babelを使ったjavascriptの自動コンパイル

Babel

ECMAScript2015 (ES6)やECMAScript7などで書かれたソースコードを一般的なブラウザがサポートしているECMAScript5の形式に出力することができます。

つまり、新しい言語仕様を昔の仕様に落としてトランスコンパイルしてくれるコンパイラ

セットアップ

babel v6.0以降、pluginまたはpresetの指定が必要になっている
基本的には.babelrcというファイルに記述するのだが、設定が少ないため、package.jsonに合わせて記述する

"babel": {
  "presets": [
    "env"
  ]
}

envというのは、コンパイル環境を自動で決定してくれるすぐれもの

追記 20180827】
index.js(下記参照)にenvの設定をして、そこを参照していたので、package.jsonに追加する必要はありませんでした。


あわせて、次の2つのパッケージをインストール

npm install babel-cli
npm install babel-preset-env

コンパイラの作成

実際にコンパイルするためには、babelコマンドが必要になってくる
それをjs側で管理して実行できるようにする
ファイル名は、package.jsonのmainタグで管理されているファイル名に設定(デフォルトはindex.js

const babel  = require('babel-core')
const fs     = require('fs')

const srcFile  = 'src/test.js'
const distFile = 'dist/test.js'
const options  = {"presets": ["env"]}

const code = fs.readFileSync(srcFile, 'utf-8')
const newCode = babel.transform(code, options).code
fs.writeFileSync(distFile, newCode)

console.log('babel build finished!')

サンプルとして、ここでは
src/test.jsの内容を、
dist/test.jsコンパイルして出力するようにしている

例えば、

class Hoge {
  constructor() {
    this.x = 3;
    this.y = 2;
  }
  add() {
    return this.x + this.y;
  }
}
const exp = (x, y) => x ** y;
const hoge = new Hoge();
console.log(exp(hoge.x, hoge.y));
console.log(hoge.add());

を変換する。
$ node index.jsを実行すると、

"use strict";

var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Hoge = function () {
  function Hoge() {
    _classCallCheck(this, Hoge);

    this.x = 3;
    this.y = 2;
  }

  _createClass(Hoge, [{
    key: "add",
    value: function add() {
      return this.x + this.y;
    }
  }]);

  return Hoge;
}();

var exp = function exp(x, y) {
  return Math.pow(x, y);
};
var hoge = new Hoge();
console.log(exp(hoge.x, hoge.y));
console.log(hoge.add());

になる。ちゃんと実行もできる

自動コンパイル環境の構築

今のままだと、変更・保存して毎回node index.jsを叩かなくてはいけない
そのため、ファイルを変更したら自動でコンパイルしてくれるようにする
gulpやgruntは使わない

まず、ファイルの変更を監視するwatchというパッケージがあるので、それをインストールする

npm install watch

次に、package.jsonのscriptを変更する

"scripts": {
  "start": "watch 'npm run build' src/",
  "build": "node index.js"
}

これは、src/下のファイルが変更されたら、npm run buildを実行するということ
そして、buildには、先程も実行していたnode index.jsを記述している

これで、

$ npm start

を実行するだけ
あとは、変更を加えるたびに自動でコンパイルしてくれるようになる


参考サイト