webpackとbabelを組み合わせてIE11対応をする最小構成を試す

webpackとは?

複数ファイルに分けて管理しているJS(モジュール)を一つのファイルにまとめてくれるツール(モジュールバンドラー)です。
別の記事(webpackの最小構成を試す)が参考になります。
※正確には1つのファイルとは限りませんが、役割に応じてファイルをまとめられます

babelとは?

ブラウザがまだ対応していない最新のJavaScriptソースコードを、ブラウザが対応しているソースコードへ変換してくれるツール (トランスパイラ)です。 別の記事(Babelの最小構成を試す)が参考になります。

webpackとbabelを組み合わせる

webpackとBabelを組み合わせれば、複数ファイルに分けて管理しているJSを一つのファイルにまとめながら、ブラウザがまだ対応していない最新のJSのソースコードを、ブラウザが対応しているソースコードへ変換させることができます。
(略:モジュールをバンドルしながらトランスパイルさせられる)

例えば、4つのJSファイルを1つにまとめたmain.js(名前は任意)を作成しながら
※今回はソースマップのファイルも作成します。

<script src="lodash.js"></script>
<script src="foo.js"></script>
<script src="bar.js"></script>
<script src="index.js"></script>

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

<script src="main.js"></script>

IE11では動作させることができなかったコードを動作可能なコードに変換できます。

// アロー関数はIE11で動作しない
const component = () => {
  let element = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  return element;
}

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

var component = function component() {
  var element = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  return element;
};

コマンドラインから実行できるようにする

以下がインストールされていることを前提としています。

  • node.js
  • npm

以下が手順概要です。

  1. npmでプロジェクトを作る
  2. webpackとBabel等をインストールする
  3. 必要なファイルを手動で作成する
  4. コマンドラインからwebpackを実行する(Babelはwebpackの中で動作する)
  5. 確認する

1. npmでプロジェクトを作る

任意のディレクトリで以下のコマンドを実行します。

mkdir webpack-babel-demo
cd webpack-babel-demo
npm init -y

2. webpackとBabel等をインストールする

以下のコマンドを実行します。

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

3. 必要なファイルを手動で作成する

以下のディレクトリ、ファイルを作成します。

  • webpack.config.js
  • babel.config.js
  • ./src/foo.js
  • ./src/bar.js
  • ./src/index.js
  • ./dist/index.html

以下のようなディレクトリ構造になるはずです。

│  package.json
│  babel.config.js
│  webpack.config.js
│
├─dist
│
├─node_modules
│  └─etc...
└─src
    bar.js
    foo.js
    index.js

package.jsonを以下のように書き換えます。

  • - "main": "index.js",
  • + "private": true,
  • + "build": "webpack",
{
  "name": "webpack-babel-demo",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.4.0",
    "@babel/preset-env": "^7.4.2",
    "babel-loader": "^8.0.5",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0"
  },
  "dependencies": {
    "@babel/polyfill": "^7.4.0",
    "lodash": "^4.17.11"
  }
}

webpack.config.jsの内容を次のようにし、webpackの動作を設定します。

const path = require('path');

module.exports = {
  mode: 'development',
  devtool: 'source-map', // ソースマップを作成する
  entry:  './src/index.js', // webpackが最初にエントリーするファイル名
  output: {
    filename: 'main.js', // 出力されるファイル名
    path: path.resolve(__dirname, 'dist') // 出力されるディレクトリ
  },
  module: {
    rules: [
      {
        test: /\.js$/, // 拡張子がjsであり、
        exclude: /(node_modules)/, // それがnode_moduleディレクトリの外のファイルであれば、
        use: {
          loader: 'babel-loader' // Babelを実行する
        }
      }
    ]
  }
};

babel.config.jsの内容を次のようにし、Babelの動作を設定します。

const presets = [
  [
    "@babel/env",
    {
      targets: {
        ie: '11'
      },
      useBuiltIns: "usage"
    }
  ]
];

module.exports = { presets };

./src/foo.js

export default () => {
  return 'from foo!';
}

./src/bar.js

export default () => {
  return 'from bar!';
}

./src/index.js

import _ from 'lodash';
import foo from './foo.js'
import bar from './bar.js'

const webpackAndBabel = () => {
  let element = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  element.innerHTML += `<br>${foo()}`;
  element.innerHTML += `<br>${bar()}`;
  return element;
}

document.body.appendChild(webpackAndBabel());

./dist/index.html

<!doctype html>
<html>
  <head>
    <title>webpack + babel</title>
  </head>
  <body>
    <script src="main.js"></script>
  </body>
</html>

4. コマンドラインからwebpackを実行する(Babelはwebpackの中で動作する)

プロジェクトのルートで以下のコマンドを実行します。

npm run build

上記のコマンドはpackage.jsonに定義してあり、以下と同等です。

npx webpack

5. 確認する

./dist/を開くと、以下のファイルが追加されています。

  • main.js
  • main.js.map

main.jsを開き、「webpackAndBabel」で文字列検索をかけてみます。すると、以下のような定義が見つかります。
IE11でも動作するコードに変換されていますね。

var webpackAndBabel = function webpackAndBabel() {
  var element = document.createElement('div');
  element.innerHTML = lodash__WEBPACK_IMPORTED_MODULE_0___default.a.join(['Hello', 'webpack'], ' ');
  element.innerHTML += "<br>".concat(Object(_foo_js__WEBPACK_IMPORTED_MODULE_1__["default"])());
  element.innerHTML += "<br>".concat(Object(_bar_js__WEBPACK_IMPORTED_MODULE_2__["default"])());
  return element;
};

また、IE11で./dist/index.htmlを開いてみます。 以下のように表示されていれば成功です。

Hello webpack
from foo!
from bar!

外部リンク

今回やったことのリポジトリ