ES2015のモジュール管理

2017年5月9日(火)
今井 宏明
ES2015に追加されたモジュール管理の機能を紹介し、現行のブラウザから使用する方法を解説する。

ES Modulesを使用するために

ここまで説明してきたES Modulesですが、上記の通りWHATWGによって仕様策定が進んでいるものの、2017年4月時点ではES Modulesの機能をサポートしている環境はありません。ES Modulesを使用するには、Babelなどのトランスパイラが必要となります。

トランスパイラ

トランスパイラとはES2015などの新しいバージョンのコードをES5などの以前のバージョンに変換して、以前のバージョンのブラウザでも動作するコードに変換してくれるツールのことです。

トランスパイラとして代表的なものとしてはBabelがあります。ECMAScript 6 compatibility tableを参照すると、2017年4月時点でBabelはES2015の71%の項目についてサポートしていることがわかります。

ECMAScript 6 compatibility table

Babelを使用してES2015で書かれたファイルを変換するには下記のコマンドを実行します。下記の例ではsrcフォルダにあるapp.jsファイルを変換し、distフォルダへ保存します。

リスト13:トランスパイラBabelの実行例

$ babel src/app.js --out-file dist/app.js

実際にES Modulesで書かれたファイルを変換してみると、下記のようなCommonsJS形式のコードに変換されることがわかります。

リスト14:変換前のES2015のコード

// ---ES2015 app.js---
import { square, num } from './lib'

console.log(square(4))
console.log(num)

// ---lib.js---
function square(x) {
  return x * x
}
const num = Math.E + Math.PI

export { square, num }

リスト15:CommonJS形式に変換されたコード

// ---app.js---
'use strict';

var _lib = require('./lib');

console.log((0, _lib.square)(4));
console.log(_lib.num);

// ---lib.js---
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
function square(x) {
  return x * x;
}
var num = Math.E + Math.PI;

exports.square = square;
exports.num = num;

このようにトランスパイラを使用することで、ES2015の記述をCommonJSの記述に変換できます。しかしこのままではCommonJS形式のコードになっているため、ブラウザ上で実行することができません。ブラウザで実行可能な形式にするにはBrowserifyやWebpackを使用してビルドする必要があります。本章では近年利用されることが多くなってきたWebpackを利用したビルドについて解説していきます。

Webpackとは

Webのコンテンツには、様々なアセットが含まれます。Webpackはこれらのアセットをモジュールとして扱い、それらのモジュールの依存関係を解決しつつ、静的なアセットを生成するビルドツールです。

Webpackを使用することで、複数に分割したJavaScriptファイルを依存関係を解決しながら結合や圧縮をすることができます。またBabelなどのトランスパイラとも連携ができるため、現在のフロントエンド開発では欠かすことのできないツールとなっています。

Webpackを使用するには、Node.jsが必要となります。詳細な設定は割愛しますがNode.jsをインストールした後に、npmからWebpackをインストールしてください。セットアップ完了後、WebpackからBabelを利用するために必要なパッケージを導入していきます。インストールするパッケージは「package.json」に記述しておきます。

リスト16:package.json

{
  "name": "ES2015_project",
  "version": "1.0.0",
  "description": "Setting for Webpack.",
  "main": "app.js",
  "scripts": {
    "build": "webpack"
  },
  "author": "Hiroaki Imai",
  "devDependencies": {
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.1",
    "babel-preset-es2015": "^6.24.0",
    "webpack": "^2.3.2"
  }
}

今回はES2015用のBabelのプリセットを使用するため、Babelの設定ファイル(.babelrc)を作成します。

リスト17:.babelrc

{
  "presets": [
    ["es2015", {"modules": false}]
  ]
}

「npm install」コマンドを実行すると、必要なパッケージがインストールされます。パッケージインストール後、ES2015のコードをビルドするための設定ファイルを準備します。

リスト18:webpack.config.js

const path = require('path')

module.exports = {
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  }
}

上記の設定例では「./src/app.js」にて記述されたコードが「app.bundle.js」という名前で「dist」フォルダ以下に出力されます。この「app.bundle.js」をHTMLファイルから読み込むことで、ES2015で記述されたコードをブラウザ上で動かせるようになります。

最後に

本連載では6回に渡り、ES2015の背景から言語として追加された機能や非同期処理、モジュール管理といったES2015の魅力的な仕様について解説してきました。ES2015の導入を見送っていた方にとっては改めて導入を検討するきっかけに、またすでに導入していた方にとっても、ES2015の機能を再確認する良いきっかけになれば幸いです。

ECMAScriptとしては、ES2015以降もJavaScriptについては活発に議論が進められており、前回のES2015が備えるモダンな非同期処理で解説したAsync Functionsを始めES2017以降に導入されるであろういくつかの機能がリリース前段階のStage 4(Finished Proposals)となっています。

Finished Proposals - Ecma TC39

JavaScriptという言語は様々な分野へ活用の場を広げており、Web開発においてなくてはならない存在となってきています。これからも日々の開発に積極的に活用していき、JavaScriptがますます魅力的な言語となるように盛り上げていきましょう!

リクルートテクノロジーズ ITマネジメント統括部 オフショアソリューション部所属

2015年4月中途入社。前職はSIerにてWebサービスやアプリの開発からインフラ構築まで幅広い業務を担当。リクルートテクノロジーズ入社後はオフショアマネジメントを経てフロントエンドチームへ参画。週末は子育てエンジニア。ラーメンは毎日食べても飽きない。

連載バックナンバー

Web開発技術解説
第6回

ES2015のモジュール管理

2017/5/9
ES2015に追加されたモジュール管理の機能を紹介し、現行のブラウザから使用する方法を解説する。
開発言語技術解説
第5回

ES2015が備えるモダンな非同期処理

2017/3/28
ES2015に追加された非同期処理の新しい記述方法について学ぶ。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています