Posted at

ECMAScript6を書きたい part1 ( babel )

More than 3 years have passed since last update.


初めに

ECMAScript6が出ました

EC6では、今までのJavaScriptで問題だった各種機能にたいして

改善されており、より便利になりました

一例ですが

Class構文が使えるようになり従来のprototypeによるオブジェクト指向が不要になったり

letによる変数のカプセル化や

importによるモジュール管理

また、言語機能ではないけど future/promiseで非同期処理を綺麗に書けるように

現状のブラウザではEC6対応が不十分なため

babelというトランスパイラを利用し、EC6のコードをEC5に変換します

しかも、asm.jsに変換することも可能!

大雑把に環境構築


環境構築


node

nodeはバージョンアップが速いので、nodeのバージョン管理ツール使うと楽です

Macではnodebrew、Linuxではnvm が人気なのかな?

Windowsにはnodistがありますが

とりあえず ここでは生nodeインストールします

$brew install node

あるいは、yumなりapt-getなり、パッケージマネージャで基本インストール出来るはずです

Windowsならmsiからインストールすると楽です


babel-cli

babel-cli をインストール

$npm install -g babel-cli

babel6.0以降、presetをインストールする必要がある(ローカルで)

$npm install babel-preset-es2015 --save-dev


確認

$babel 入力ファイル -o 出力ファイル --presets es2015

で、ES6で書いたコードが ES5で出力されるので確認


test.es6.js

class Hoge {

constructor(name) {
this.name = name;
}
print(){
console.log( "name=" + this.name );
}
}

var hoge = new Hoge("Yuki");
hoge.print();


$babel test.es6.js -o test.js --presets es201


test.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; }; }();

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

this.name = name;
}

_createClass(Hoge, [{
key: "print",
value: function print() {
console.log("name=" + this.name);
}
}]);

return Hoge;
}();

var hoge = new Hoge("Yuki");
hoge.print();


EcmaScript6の class構文が使えるようになりました!

その他、ラムダ式等も使えます


presetを指定

別に設定しなくてよいですが、毎回 babelのたびに presetsを指定するのは面倒

なので、デフォルトのpresetsを指定します

カレントディレクトリに .babelrc を作ります


.babelrc

{

"presets": ["es2015"]
}

これで preset指定なく

$babel test.es6.js -o test.js

で トランスコンパイル出来るようになりました


babel-polyfill

今までで、classやexport等、言語仕様的な部分は使えるようになりましたが

future/promise のような、ライブラリ的な拡張は有効になっていないので

そちらもインストールします

(私のブラウザでは、インストールしなくても promise動きましたが・・)

$npm install -g --save-dev babel-polyfill babel-core


test.ec6.js


class Hoge {
constructor(name) {
this.name = name;
}
print(){
console.log( "name=" + this.name );
}
}

var hoge = new Hoge("Yuki");

new Promise((resolve, reject) => {
setTimeout(resolve, 5000)
}).then(() => hoge.print());


$babel test.es6.js -o test.js --presets es201


test.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(name) {
_classCallCheck(this, Hoge);

this.name = name;
}

_createClass(Hoge, [{
key: "print",
value: function print() {
console.log("name=" + this.name);
}
}]);

return Hoge;
}();

var hoge = new Hoge("Yuki");

new Promise(function (resolve, reject) {
setTimeout(resolve, 5000);
}).then(function () {
return hoge.print();
});


約5秒後に console.logされるようになったはずです

(Promiseがないと怒られる場合は PromiseライブラリをRequireすると良いと思います)


次回

とりあえず今回は babelの環境構築でした

次からは

コンパイル自動化(makefile的な)

Asm.js出力

そのあたりかなと。