[JS]Babelとwebpackを使いES6用のスクリプトを古いブラウザに対応させる

Pocket

JavaScript(ECMAScript) にはバージョンによって大きく機能に差があり、最新の書き方をすると古いブラウザでは動作しない場合があります。例えば ES6(ECMAScript Edition 6) ではクラスやモジュールの読み込みなど多くの機能が追加されましたが、それらは ES5 以前では備わっていないため、Internet Explorer などのレガシーブラウザでは機能しません。

そういった問題を解決するためには、TypeScript などの Javascript ではない言語(AltJS)で書いたものを ES5 対応のスクリプトにトランスパイルしたり、ES6 の書き方で書いたスクリプトを Babel で ES5 以前の書き方に変換するのが一般的です。

今回は Babel と webpack を組み合わせて、スクリプトの保存時に自動的に ES5 対応スクリプトに変換される環境を作ってみます。

前提として Node.js がインストールされている必要があります。公式サイトや Homebrew 等を使ってあらかじめインストールしておいてください。

Babel のインストール

まずはプロジェクト用のフォルダを用意し、関連パッケージを管理するための土台となる package.json ファイルを作ります。ファイルの作成はコマンドから行います。

npm init

プロジェクト名やバージョン等の入力は基本的にそのまま Enter で進めていって構いません。必要なら後からでも変更できます。完了すると現在のフォルダに package.json ファイルが作られます。

次に npm コマンドで Babel 本体とプリセットをインストールします。

npm install --save-dev babel babel-cli babel-preset-env

どのプリセット(変換ルール)に基づいて処理を行うかを指定するために .babelrc ファイルを作ります。
内容は次のようにします。

{
  "presets": ["env"]
}

Babel を使ったスクリプトの変換

変換作業を簡単にするために package.json ファイルの scripts の箇所を探して次のように書き換えます。

  "scripts": {
    "build": "babel src -d dist"
  },

「babel」の後に変換対象となるスクリプトがあるフォルダを指定し、「-d」オプションに続けて保存先のフォルダを指定します。「babel src -d dist」の場合 src フォルダのスクリプトを変換し、dist フォルダに保存することになります。

では src フォルダと dist フォルダを用意し、src フォルダ内に実際にスクリプトを作ります。

example.js
function hello(word="World"){
    console.log("Hello, " + word);
}

ES6 では引数に初期値を用意できるようになりました。引数を省略した場合その初期値が代わりに代入されるのですが、ES5 以前ではそういった機能は用意されていないため、Babel を通して古いブラウザでも動作するように変換します。

変換を実行するコマンドはこちらです。

npm run build

実行すると保存先の dist の中に同じ名前のファイルが作られ、内容を見ると変換されているのがわかると思います。

“use strict”;
function hello() {
    var word = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "World";

    console.log("Hello, " + word);
}

webpack のインストール

手動で変換を行うだけなら Babel だけでもできるのですが、ファイルに変更を加えた際に自動的に変換が実行されるようにしたほうが効率的です。

そうしたケースではタスクランナーの gulp や、モジュールバンドラーの webpack がよく使われます。

今回は webpack を使い、メインとなる JS ファイルに変更が加えられたとき、Babel で自動変換されるようにしてみます。インストールは次のコマンドで行います。

npm install --save-dev webpack webpack-cli

加えて webpack から Babel を読み込むためのパッケージもインストールします。

npm install --save-dev babel-loader

変換処理を webpack 経由にするために再度 package.json の scripts の箇所を書き換えます。

  "scripts": {
    "watch": "webpack --watch --progress"
    "build": "webpack"
  },

変換処理の具体的な指定は webpack.config.js ファイルを作り、そちらで行います。

const path = require('path');

module.exports = {
  mode: 'development',
  entry: path.resolve(__dirname, 'src/app.js'),
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['env']
        }
      }
    }]
  },
  devtool: 'source-map'
};

entry はメイン(エントリーポイント)となるスクリプトファイルを指定します。このファイルに変更を加えた場合は Babel によってスクリプトが変換され、output で指定された場所に bundle.js というファイル名で保存されることになります。

module の rules は条件に合うファイルに対し処理を行うという記述で、上の例では「.js」ファイルを babel-loader で処理するというルールが書かれています。exclude は対象外とするものを指定します。今回は node_modules フォルダ内に加えられた変更は無視しています。

devtool はソースマップの生成に関するもので、生成しておくと Babel を通す前のソース上のエラー箇所が特定しやすくなります。

すべての準備が完了したら src/app.js ファイルを作り、何らかのプログラムを書いてください。コマンドで次のようにするとファイル監視がスタートします。

npm run watch

監視モード実行中に app.js に変更を加えると自動的に Babel による変換が行われ、dist/bundle.js として変換後のスクリプトが保存されます。ウェブサイトでこのスクリプトを利用するときは dist/bundle.js の方だけを <script> タグで読み込んでください。


Similar Posts:




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です