[Babel] Babel: import / export をブラウザ向けに Browserify で実現する

前回の続き。
Module を require する。

import / export 構文

モジュールを読み込む。

モジュールを切り出すことができるようになりました。これまで JavaScript では言語レベルでモジュールの分割ができませんでした。そのため、JavaScript をモジュール化してフロントで読み込む際には require.js 使ったり、 browserify 使ったりというライブラリで解決するか、global 空間に独自の名前空間を作ってそこに生やすといった処理がされてきました。

ES2015 からはこのモジュール化をするための専用の構文 export と import が使えるようになりました。

基本的には commonjs と似ています、つまり、 export でオブジェクトを import できるようにして、require の代わりに import 構文でオブジェクトを利用できるようにします。

Node.js

src/math.es6 を作成。

src/math.es6
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;

src/basic.es6 から下記の形で利用できる。

src/basic.es6
'use strict';
import * as math from "./math.es6";
console.log("2π = " + math.sum(math.pi, math.pi));

Node で実行。

% $(npm bin)/babel-node src/basic.es6
2π = 6.283186

Browser

が、Browser では import できない。

2016-04-08_babel_01

Babel でトランスコンパイルすると、import/ export 構文が require 構文となるが、ブラウザが解釈できない。

lib/basic.js
'use strict';
var _math = require("./math.es6");
var math = _interopRequireWildcard(_math);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
console.log("2π = " + math.sum(math.pi, math.pi));
//# sourceMappingURL=basic.js.map%

このため WebpackBrowserify を利用して解決するというのが、現在の一般的なアプローチ。

インストール

ここでは疎結合に扱える Browserify を利用する。

browserify とプラグインの babelify をインストールする。

% npm install --save-dev browserify babelify

使い方

オプション付きで bundle up する。

% $(npm bin)/browserify src/basic.es6 -t babelify -o lib/basic.js

なにやらコードが生成され、1ファイルにまとまって出力された。

lib/basic.js
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var _math = require("./math.es6");
var math = _interopRequireWildcard(_math);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
console.log("2π = " + math.sum(math.pi, math.pi));
},{"./math.es6":2}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.sum = sum;
function sum(x, y) {
  return x + y;
}
var pi = exports.pi = 3.141593;
},{}]},{},[1]);

期待した結果が表示された。

2016-04-08_babel_02