最新版で学ぶwebpack 5入門
Babel 7でES2023環境の構築
(React, Vue, Three.js, jQueryのサンプル付き)

214
347

ECMAScript 2015(略:ES2015)以上の言語仕様でJavaScriptを書くことが、昨今のウェブのフロントエンドエンジニアの基本テクニックです。しかし、ECMAScript 2015以上の仕様のJavaScriptで記述すると、Internet Explorer 11など古いブラウザでは動作しないこともあります。そこでBabelなどのトランスパイラと呼ばれるツールを使って、ES2015〜ES2023の仕様で記述したJavaScriptファイルを互換性のあるECMAScript 5に変換します

トランスパイラとして一番有名なのが「Babel」というツールです。ただ、BabelにはECMAScript Modules(importexport文のこと。以下、ES Modulesと記載)のJSファイルをまとめる機能が提供されていません。そのため、ES ModulesのJSファイルをまとめるモジュールバンドラー(例:webpackRollup等)をBabelと合わせて使うのが一般的です。

この記事ではトランスパイラのBabelとモジュールバンドラーのwebpackを連携する方法を網羅的に解説します。使い方として次の5種類を解説します。

※webpackの基本的な使い方は前回の記事「最新版で学ぶwebpack入門」を参照ください。

webpack+Babelの構成を作成しよう

webpackとBabelを最小構成で作っていきましょう。

npmモジュールのインストール

webpackとBabelなど必要なモジュールをインストールしましょう。Babelは複数のモジュールを組み合わせて使う形式上、「@babel/core」「@babel/preset-env」「babel-loader」と3種類を最低限インストールする必要があります。もちろん「webpack」と「webpack-cli」も指定します。

npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env

※Babel本体のモジュール「@babel/core」「@babel/preset-env」には先頭に「@」があり、webpack用「babel-loader」には「@」がない点にも注意ください。

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-env": "^7.20.2",
    "babel-loader": "^9.1.2",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。rulesの部分でbabel-loaderを指定しているのがポイントです。Babelはプリセットの設定に応じてECMAScriptのバージョンを下位にトランスパイルします。

presetsプロパティに@babel/preset-envの指定することで、最新仕様(執筆時点ではECMAScript 2020)の構文をECMAScript 5に変換できます。webpack 5からtarget: ["web", "es5"]プロパティーの設定が必要になりました。これを設定しないとIE 11でバンドル後のJavaScriptファイルが動作しなくなります(アロー関数などES2015の記法がIE11で認識しないため、実行時エラーとなります)。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: "./src/index.js",

  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、新しいESをES5に変換
                "@babel/preset-env",
              ],
            },
          },
        ],
      },
    ],
  },
  // ES5(IE11等)向けの指定
  target: ["web", "es5"],
};

※プリセット「@babel/preset-env」は「ECMAScript 5/6/7 compatibility tables」に基づきターゲットブラウザを指定できたりとさまざまな機能が提供されています。たとえば、ターゲットブラウザがSafari 10だけでよければ、ES5まで落として変換する必要はなく、ES2015(ES6)をターゲットにすれば良いということになります。興味がある方はドキュメントを参考ください。

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したJSファイルがトランスパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

webpack+Babel+jQueryの構成を作成しよう

jQueryは言わずと知れた汎用的なJSライブラリです。webpackやBabelに興味のあるフロントエンドエンジニアであれば、「いまどき、jQueryを使いたくない」という方もいるかもしれません。しかし、現場では使わざるを得ない状況の方も多いはずです。まとめ記事「jQueryはオワコンなのか - ウェブアプリ開発者とウェブサイト制作者の大きな溝 - Togetter」でも、不要論の是非について話題になりましたね。ここでは、npmモジュールのjQueryをwebpackで取り込む方法について紹介します。

npmモジュールのインストール

必要なモジュールをインストールしましょう。上述のwebpack+Babelの構成と同じです。

npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env

実行用の「jQuery」モジュールもインストールしましょう。こちらは実行ファイルに含まれるモジュールとして利用したいので、コマンドオプション「-D」は省いてます。「-D」を省くとdependenciesにモジュールが記載されます。

npm install jquery

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependenciesdependencies以外の情報は省略しています。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack"
  },
  "dependencies": {
    "jquery": "^3.6.4"
  },
  "devDependencies": {
    "@babel/core": "7.21.3",
    "@babel/preset-env": "7.20.2",
    "babel-loader": "^9.1.2",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。rulesの部分でbabel-loaderを指定します。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: 'production',

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: './src/index.js',
  // ファイルの出力設定
  output: {
    //  出力ファイルのディレクトリ名
    path: `${__dirname}/dist`,
    // 出力ファイル名
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: 'babel-loader',
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES5 に変換
                '@babel/preset-env',
              ]
            }
          }
        ]
      }
    ]
  },
  // ES5(IE11等)向けの指定
  target: ["web", "es5"],
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したJSファイルがトランスパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

jQueryのサンプルの実行結果は次となります。

webpack+Babel+Reactの構成を作成しよう

Reactウェブアプリケーションの開発に役立つ人気のJSライブラリです。2023年現在の最新版であるReact 18を例に、npmモジュールをwebpackで取り込む方法について学んでいきましょう。

npmモジュールのインストール

必要なモジュールをインストールしましょう。上述のwebpack+Babelの構成に加えて、トランスパイル用に「@babel/preset-react」が必要となります。

npm install -D webpack webpack-cli babel-loader @babel/core  @babel/preset-env @babel/preset-react

実行用の「react」と「react-dom」もインストールしましょう。

npm install react react-dom

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependenciesdependencies以外の情報は省略しています。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "7.21.3",
    "@babel/preset-env": "7.20.2",
    "@babel/preset-react": "7.18.6",
    "babel-loader": "^9.1.2",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。rulesの部分でbabel-loaderを指定します。

オプションのプリセットには@babel/preset-envの指定だけでなく、@babel/reactを記述するのがポイントです。これによって、JSXと呼ばれるReact特有のシンタックス(JavaScriptの中にDOM要素を記述する方法)を解釈できるようになります

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",

  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES5 に変換
                "@babel/preset-env",
                // React の JSX を解釈
                "@babel/react"
              ]
            }
          }
        ]
      }
    ]
  },
  // ES5(IE11等)向けの指定(webpack 5以上で必要)
  target: ["web", "es5"],
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したJSファイルがトランスパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

サンプルの実行結果は次となります。

Reactの初期設定を簡単にするツール「create-react-app」やViteからReactを始める人も多いと思います。create-react-appのビルドでは、内部的にwebpackとBabelが使われています。

webpack+Babel+Three.jsの構成を作成しよう

Three.jsは3D表現の制作に役立つ人気のJSライブラリです。使い方は記事「Three.js入門」で説明したことがあります。Three.jsを例に、npmモジュールをwebpackで取り込む汎用的な方法について学んでいきましょう。

npmモジュールのインストール

必要なモジュールをインストールしましょう。上述のwebpack+Babelの構成と同じです。

npm install -D webpack webpack-cli babel-loader @babel/core  @babel/preset-env

実行用の「three」と「core-js」モジュールもインストールしましょう。こちらは実行ファイルに含まれるモジュールとして利用したいので、コマンドオプション「-D」を省いています。dependenciesにモジュールが記載されます。

WebGLはIE11でも動作しますが、Three.jsライブラリのコードがIE11向けに提供されていないので、ポリフィルを導入します。

npm install three core-js

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependenciesdependencies以外の情報は省略しています。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack"
  },
  "dependencies": {
    "core-js": "^3.29.1",
    "three": "^0.150.1"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-env": "^7.20.2",
    "babel-loader": "^9.1.2",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。rulesの部分でbabel-loaderを指定し、excludenode_modulesフォルダーを除外します。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: "./src/index.js",
  // ファイルの出力設定
  output: {
    //  出力ファイルのディレクトリ名
    path: `${__dirname}/dist`,
    // 出力ファイル名
    filename: "main.js"
  },
  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES5 に変換
                "@babel/preset-env"
              ]
            }
          }
        ]
      }
    ]
  },
  // ES5(IE11等)向けの指定(webpack 5以上で必要)
  target: ["web", "es5"],
};

Three.jsのルートファイルではポリフィルを読み込むように設定しておきます。threeモジュールの読み込みよりも手前でimport "core-js/stable"を取り込む必要があります。以下は抜粋のコードです。

import "core-js/stable"; // 古いブラウザで動作するようにポリフィルを導入
import * as THREE from "three";

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したJSファイルがトランスパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

サンプルの実行結果は次となります。

webpack+Babel+Vue.jsの最小構成

Vue.js公式サイト

Vue.jsはReactと並んで注目を集めるJSライブラリです。@vue/cliViteで導入するのがもっとも簡単ですが、カスタマイズを目的として自前でビルド環境を用意したい方もいるでしょう。この解説ではwebpack 5とBabelとVue.jsを最小構成で作っていきます。

Vue.jsはさまざまな記述方法が可能なので、ここで紹介する構成は一例に過ぎません。アンケートで調べたところ、Vue.jsの開発では単一ファイルコンポーネントがもっとも使われているようなので、その構成で解説します。

npmモジュールのインストール

webpackとBabelなど必要なモジュールをインストールしましょう。.vueファイルを読み込むために、vue-loaderやvue-template-compilerを入れておきます(必須)。.vueファイルではCSSも扱うので、css-loaderも必要となります。

npm i -D @babel/core @babel/preset-env babel-loader css-loader vue-loader vue-style-loader vue-template-compiler webpack webpack-cli

実行用の「vue」モジュールもインストールしましょう。本記事はVue 3で説明しています。

npm i vue

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch"
  },
  "dependencies": {
    "vue": "^3.2.47"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-env": "^7.20.2",
    "babel-loader": "^9.1.2",
    "css-loader": "^6.7.3",
    "vue-loader": "^17.0.1",
    "vue-style-loader": "^4.1.3",
    "vue-template-compiler": "^2.7.14",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。resolveの部分でaliasを指定することや、プラグインVueLoaderPluginを指定することも重要です。拡張子vueやcssに対してもルールを設定し、extensionsの箇所にはvueファイルを登録しておきます。要は設定するところが多いので大変です。

webpack.config.jsファイル

const { VueLoaderPlugin } = require("vue-loader");

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",

  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["vue-style-loader", "css-loader"],
      },

      {
        test: /\.vue$/
        loader: "vue-loader",
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        // Babel のオプションを指定する
        options: {
          presets: [
            // プリセットを指定することで、ES5 に変換
            "@babel/preset-env",
          ],
        },
      },
    ],
  },
  // import 文で .ts ファイルを解決するため
  resolve: {
    // Webpackで利用するときの設定
    alias: {
      vue$: 'vue/dist/vue.runtime.esm-bundler.js',
    },
    extensions: ["*", ".js", ".vue", ".json"],
  },
  plugins: [
    // Vueを読み込めるようにするため
    new VueLoaderPlugin(),
  ],
  // ES5(IE11等)向けの指定
  target: ["web", "es5"],
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したjsやvueファイルがコンパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

Vue.jsのサンプルの実行結果は次となります。

webpack+ECMAScript 2023の構成を作成しよう

ECMAScript 2023仕様のJavaScriptをフルに利用するには、さらに設定が必要です。Babelはアロー関数やクラス、letconstといった新しい構文を下位バージョンに変換しますが、PromiseArray.includes()といった機能までは変換しません。後者を利用するにはポリフィルを導入する必要があります。

npmモジュールのインストール

必要なモジュールをインストールしましょう。

npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env

今回はポリフィルとして「core-js」もインストールします。

npm install core-js

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependenciesdependencies以外の情報は省略しています。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "dependencies": {
    "core-js": "^3.29.1"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-env": "^7.20.2",
    "babel-loader": "^9.1.2",
    "webpack": "^5.76.2",
    "webpack-cli": "^5.0.1"
  },
  "private": true
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",
  devtool: "source-map",

  module: {
    rules: [
      {
        // 拡張子 .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES5 に変換
                "@babel/preset-env",
              ],
            },
          },
        ],
      },
    ],
  },
  // ES5(IE11等)向けの指定
  target: ["web", "es5"],
};

エントリーポイントentryのJavaScriptファイルには、ポリフィルを取り込むように記載しましょう。デフォルトではsrc/index.jsファイルの先頭に記載します。

▼ src/index.js ファイル

import "core-js/stable";

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したJSファイルがトランスパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開しています。

サンプルのコードではECMAScript 2015(ES6)からECMAScript 2023(ES14)までのさまざまなAPIを試しています。変換前後の結果を見比べてみるとおもしろいです。たとえば、ES2016のべき乗演算子(Exponentiation Operator)を使ったコード3 ** 2はBabelによってMath.pow(3, 2)に変換されています(次の図版はクリックで拡大できます)。ES2017のpadEnd()メソッドや、ES2018の非同期イテレーション、ES2020のオプショナルチェインニング、ES2023のArray.toReversed()も動作します。

]

このほかにもサンプルを用意してます

このほかにも、さまざまなJavaScriptライブラリのサンプルを用意してます。ここまで記事を読み進めて頂いた方であれば、次のリポジトリのソースコードを見れば簡単に導入できるはずです。

最後に

最近のブラウザではECMAScript 2015以上の言語仕様が標準で使えるようになってきました。IE 11のサポート期間は2022年6月(Windows 8.1では2023年2月)で終了したことで、トランスパイラとしてのBabelは現在のウェブ制作では必要性が低くなりました。

モジュールバンドラーの役割は複数のファイルをまとめることです。ES Modulesは各種ブラウザが対応し利用できるようになってきました(参考記事『ブラウザで覚えるES Modules入門』)。ただ、HTTP/1.1環境下では同時リクエスト数の上限があるため、モジュールバンドラーによってまとめる利点が依然として存在します。npmモジュールのバンドルにも役立つことを考えると、モジュールバンドラーの寿命はトランスパイラよりも長いかもしれません。

モジュールバンドラーとしてのwebpackは多機能であるがゆえに設定が複雑です。本記事で紹介した設定は一例に過ぎないので、コピペするだけではなく理解したうえで応用しなけば現場ではまったく役に立ちません。

前回の記事「最新版で学ぶwebpack入門」には、JavaScriptの圧縮やソースマップ、webpack-dev-serverなどについて解説しています。あわせて参照くださいませ。

連載一覧

※この記事が公開されたのは7年前ですが、1年前の2023年3月に内容をメンテナンスしています。

池田 泰延

ICS代表。筑波大学 非常勤講師。ICS MEDIA編集長。個人実験サイト「ClockMaker Labs」のようなビジュアルプログラミングとUIデザインが得意分野です。

この担当の記事一覧