webpackとbabelとは何かをわかりやすく

webpackとbabelがどう動いているかイメージつかなかったので、簡単なサンプルで手を動かしてみました。

webpack と babel とは何か

webpack

アプリケーションを作成する際には、あるファイルが他のファイルの関数を呼び出したり、画像を読み込んだりといろいろ依存します。その依存をみてファイルを一つに固めてくれるツールがwebpackです。

以下の公式URLの最上部の図がわかりやすいです。

https://webpack.js.org/

.js や .sass や .img が複雑に依存していますが、これらの依存を自動的に判断して、ファイルを固めてくれます。

babel

javascript の最新バージョンでは最新の構文が登場します。しかし、その構文は古いブラウザでは動作しないことがあります。

babel は最新の構文を古いブラウザでも動くように変換するツールです。

こちらも公式URLがわかりやすいです。

https://babeljs.io/

右枠に新しい構文が入力され、それが左枠に古い書き方に変換されています。

Nodeをインストールする

まずNode.jsをインストールします。

Node.jsはJavaScriptを実行するための実行環境です。

https://nodejs.org/ja/

インストールが完了したら以下のコマンドを実行してnodeのバージョンを確認します。

node -v

nodeをインストールすると一緒にnpmもインストールされます。

npmはパッケージ管理ツールといって、色々な外部のモジュールをインストールしたり、依存のあるモジュールを管理してくれます。あなたのアプリケーションで誰かが作った便利なモジュールを使用したい時に便利です。

https://www.npmjs.com/

npmのバージョンも確認します。

npm -v

node と npm のバージョンが出力されたら正常にインストールされているので、次に進みます。

プロジェクトを作成する

プロジェクト用のディレクトリを作成し、移動します。

mkdir webpack-babel-test
cd webpack-babel-test

以下のコマンドを実行し、プロジェクトを初期化します。

npm init

package name などをいろいろ聞かれますがすべてEnterを押します。

新たにpackage.jsonというファイルが作成されます。

{
  "name": "webpack-babel-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

これがこのプロジェクトの設定ファイルです。

プロジェクトの名前などの設定の他、外部のモジュールをインストールするとこのファイルに追記されます。

webpackをインストールする

npm を使った webpack をインストールします。

npm install webpack

終わると package.json に以下が追加されます。

"dependencies": {
  "webpack": "^4.42.0"
}

また、プロジェクト直下に node_modules というディレクトリが作成され、ここに webpack が入っています。

webpack の設定ファイルを作成する

公式のURLを参考にしながら webpack.config.js を作成します。

https://webpack.js.org/concepts/

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, './dist/bundle.js'),
    },
};

entry はバンドルの開始ファイルです。公式URLの図でいうと左上の「.js」のことです。

https://webpack.js.org/

output はバンドル後のファイルの出力先を指定します。

ソースファイルを作成する

webpack.config.js で指定したディレクトリがないので作成します。

mkdir src
mkdir dist

src の下に index.js を作成し、シンプルなコードを書きます。

console.log('Hello tamibouzu')

package.json に webpack 実行用のコマンドを定義する

package.json に script オブジェクトを定義して、webpack を実行できるようにします。

{
  "name": "webpack-babel-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "webpack": "^4.42.0"
  },
  "scripts": {
    "start": "webpack"
  }
}

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

npm start

以下のようなメッセージがでたら、yes を入力して Enter を押します。

Do you want to install 'webpack-cli' (yes/no): 

npm start が完了したら、dist/bundle.js が作成されます。

cat ./dist/bundle.js

webpack によって変換された中身になっています。

新しい構文でソースを書き換えてみる

次に babel による変換を試しますが、その前に src/index.js を最新の構文に書き換えます。

[1, 2, 3].map(n => n ** 2);

再度、npm start を実行し、bundle.js の中身を見てみます。ファイルの最後の方に以下の記載があります。

function(e,t){[1,2,3].map(e=>e**2)

ソースコードの内容がそのまま出力されています。

次に babel を通してこの出力が変換されるかを確認していきます。

babel をインストールする

npm install を実行して babel をインストールします。

npm install @babel/core babel-loader @babel/preset-env

package.json に追加されていることを確認します。

{
  "name": "webpack-babel-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.8.7",
    "@babel/preset-env": "^7.8.7",
    "babel-loader": "^8.0.6",
    "webpack": "^4.42.0"
  },
  "devDependencies": {
    "webpack-cli": "^3.3.11"
  }
}

babel の設定ファイルを作成する

以下のように webpack.config.js を編集します。

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, './dist/bundle.js'),
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                '@babel/preset-env',
                            ]
                        }
                    }
                ]
            }
        ]
    }
};

.js ファイルを babel-loader を使って変換するという意味です。

options の presets では、@babel/preset-env を使って変換を行います。

babel 変換後のファイルをみてみる

npm start を実行し、bundle.js を確認します。

function(e,t){[1,2,3].map((function(e){return Math.pow(e,2)}))}

アロー演算子を使っていた部分が function に変換されています。