[フロントエンド] ES2015のimport/exportをブラウザで使うためのコンパイル(Babel × Browserify)
こんにちは、フロントエンドのリハビリ中@yoheiMuneです。
今日はES2015(ES6)から言語レベルでサポートされたモジュール定義について、ブラウザで利用するための方法をブログに書きたいと思います。
この状態でブラウザで使おうとすると以下のようにエラーとなってしまいます。
[フロントエンド] nodeモジュール管理がフロントで使えるBrowserifyに入門
[フロントエンド] gulpからBrowserifyを利用する、watchでコンパイルする
具体的にはBrowserifyのトランスフォーム(transform)という機能で、Babelifyを用いて変換を行います。まずはBabelifyをインストールします。
babelifyで始めるES6 - to-R
最後になりますが本ブログでは、フロントエンド・開発関連・Swift・Linux・Python・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
今日はES2015(ES6)から言語レベルでサポートされたモジュール定義について、ブラウザで利用するための方法をブログに書きたいと思います。
目次
ES6のimport/exportはまだブラウザで使えない
ES6から利用可能なimport
とexport
によるモジュール定義と利用ですが、残念ながらまだブラウザでは使うことができません。例えば以下のようなコードがあった場合に、import React from "react"Chromeだと以下のようなエラーが発生します。
# Chrome v53の場合 Uncaught SyntaxError: Unexpected token importそして前回、「[フロントエンド] 次世代JavaScriptのコンパイラ、Babelに入門」でES6をES5にコンパイルする方法を紹介しましたが、残念ながら
import
とexport
は使える状態にはコンパイルされません。例えば以下のコードがある場合に、// hello.js export function hello () { console.log("Hello from a.js"); };
// my-file.js import {hello} from './hello.js'; hello();Babelでコンパイルすると以下のようになります。
# Babelでコンパイル $ babel -o hello-comiled.js hello.js $ babel -o my-file-comiled.js my-file.js
// hello-compiled.js "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hello = hello; function hello() { console.log("Hello from a.js"); };
// my-file-compiled.js 'use strict'; var _hello = require('./hello.js'); (0, _hello.hello)();上記のように
exports
とrequire
を用いた方式(Nodeの方式)にコンパイルされてしまいます。この状態でブラウザで使おうとすると以下のようにエラーとなってしまいます。
# Chrome v53の場合 Uncaught ReferenceError: require is not definedということで、EcmaScript6のインポートとエクスポートを使う場合には追加のコンパイルが必要となります。
Browserify × Babelを用いてコンパイルする
ES6のimport
とexport
をブラウザで使えるようにする方法は幾つかありますが、ここでは手軽なBrowserifyを用いた方法を紹介します。Browserify自体の紹介は以下でブログを書きましたので参照いただけますと幸いです。[フロントエンド] nodeモジュール管理がフロントで使えるBrowserifyに入門
[フロントエンド] gulpからBrowserifyを利用する、watchでコンパイルする
具体的にはBrowserifyのトランスフォーム(transform)という機能で、Babelifyを用いて変換を行います。まずはBabelifyをインストールします。
# Babelifyの導入 $ npm install --save-dev babelifyそして以下のようにBrowserifyを実行します。
# Babelifyを用いたコンパイル $ browserify --transform babelify --outfile my-file-compiled2.js my-file.jsすると以下のように変換され、ブラウザから利用することができるようになります。
// my-file-compiled2.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"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hello = hello; function hello() { console.log("Hello from a.js"); }; },{}],2:[function(require,module,exports){ 'use strict'; var _hello = require('./hello.js'); (0, _hello.hello)(); },{"./hello.js":1}]},{},[2]);また、gulpで以下のように実装することでgulp経由でコンパイルすることもできます。
// gulpfile.js "use strict"; var gulp = require('gulp'); var browserify = require('browserify'); var babelify = require('babelify'); var source = require('vinyl-source-stream'); gulp.task('browserify', function () { browserify({ entries: './my-file.js' }) .transform(babelify) .bundle() .pipe(source("myfile.js")) .pipe(gulp.dest("./dest")); });
# gulp実行 $ gulp browserify
transform
を指定する以外は普通のビルドですね!エラーが発生したら
僕がやった時には最初以下のようなエラーが発生しました。'import' and 'export' may appear only with 'sourceType: module'どうもよくよく調べたところ、Babelの
preset
でes2015
を指定し忘れたのが原因のようでした。npmで以下のようにモジュールをインストールして、$ npm install --save-dev babel-preset-es2015また、以下の
.babelrc
を準備することで無事に動きました。// .babelrc { "presets": [ "es2015" ] }隠れた設定ファイルが必要なあたり、Babelのはまりどころの1つですね。
参考記事
今回の内容を実装するために以下の記事を参照しました。ありがとうございます。babelifyで始めるES6 - to-R
最後に
ES2015スタイルでコードを書けるってなかなか素敵ですね。良い仕様は早めに取り込んで実装の品質アップを図りたいものです。最後になりますが本ブログでは、フロントエンド・開発関連・Swift・Linux・Python・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!