【JavaScript】WebpackとBabelの設定

# はじめに

WebpackとBabelがどういったものかは頭では理解していましたが、実際に設定ファイルとしてどのように書かれているのか、どのように変換されているのかということが気になったため、独自で設定する方法をまとめました。

モダンなフロントエンドUIライブラリであるReactやそのフレームワークであるNext.jsがありますが、npmやyarnのコマンドでプロジェクトを生成するとWebpackやBabelがデフォルトで使えるようになっています。
（TypeScriptをJavaScriptに変換（トランスパイル）するためにもBabelが必要）

しかし、これらのツールを独自に設定することでバンドル設定を好きなように変更することができるようになるため、少しでも興味があればぜひ手を動かしてみてください。

設定については下記の動画を参考にしていますので、詳しく知りたい方は観てみてください。

https://youtu.be/Jjl8XsxSm1A?si=eU_csQhnu4SgPy8H

# 概要
- Webpack
- Babel
- 実際のセットアップ
- 補足

## Webpack

Webpackは「複数のモジュールを一つのファイルにまとめて出力」する、モジュールバンドラー呼ばれるツールです。

※バンドル（bundle）＝束ねる

基本的にはjsファイルをまとめることが多いですが、cssファイルもまとめることができます。

これらは複数のjsファイルを一つにまとめることでブラウザからのリクエスト数を減らし、ファイル転送の最適化をすることが目的となります。
また、モジュールの依存関係（require、import文など）を事前に解決してファイルをまとめておくことで、読み込みスピードの向上にもつながります。

## Babel

Babelは、新しいバージョンの記法で書かれたJavascriptコードを古いバージョンのコードに変換するコンパイラツールです。

ブラウザによっては新しいバージョンのJavaScriptの書き方に対応していない場合があるため、これを互換性のある古いバージョンのコードに書き換えてくれるのがBabelです。

また、TypeScriptをJavaScriptにトランスパイルするのもBabelが担っています。

※厳密には、バージョンを持っているのはECMAScriptというJavaScriptの標準規格になります。

https://www.javadrive.jp/javascript/ini/index11.html

## 実際のセットアップ

※今回はパッケージマネージャーにnpmを使用しますが、Node.jsのインストール手順は割愛するため、未インストールの方は下記からインストールをお願いします。

バージョン管理ツール（anyenvのnodenv、asdfなど）を使いたい方はそちらでも結構です。

https://nodejs.org/ja

まずは作業用のワークスペースフォルダを作成し、中に移動

```sh
mkdir webpack_babel_workspace
cd webpack_babel_workspace
```

package.jsonの初期化

```sh
npm init -y
```

![スクリーンショット 2023-10-06 7.36.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/5cd93db9-100e-dc71-0e1f-2cbe982f6c49.png)

これでpackage.jsonが生成されます
![スクリーンショット 2023-10-06 7.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/aec2f458-fc0a-5189-62a0-c881a679ea0f.png)

Webpack関連のモジュールのインストール

```sh
npm i -D webpack webpack-cli webpack-dev-server

// webpack-dev-server はローカルサーバーを起動するためのモジュール
// 今回はビルド時のバンドル結果を確認するだけなので、なくてもOK
```

package.jsonのdevDependenciesに記述されます
![スクリーンショット 2023-10-06 7.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/7786e1bc-95a3-15e8-be9b-ee4cb167084d.png)

サーバー起動時のコマンドをWebpackを使用したスクリプトに修正
![スクリーンショット 2023-10-06 7.43.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/7f713299-1d2a-8ff1-70ed-597faa759e0e.png)
![スクリーンショット 2023-10-06 7.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/2a3f9632-4704-f52d-271c-a6c8c8a0f8ae.png)

このようにすることで、開発モードとビルドモードでそれぞれバンドルされるようになります

その後は、バンドル元のファイルとなる index.js と外部読み込み用の calculator-function.jsをsrcフォルダ内に作成
![スクリーンショット 2023-10-06 8.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/194b00aa-4be9-ee75-586b-d7432f56c664.png)


中身

calculator-function.js は、引数に渡した２つの値の合計値を返却するadd関数を定義
![スクリーンショット 2023-10-06 8.48.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/dfbcfda6-eb47-1b83-65cc-2fc5aabcbde6.png)

```calculator-function.js
export function add(num1, num2) {
  return num1 + num2;
}
```

index.js では上記の関数を使用した処理を作成
![スクリーンショット 2023-10-06 8.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/529bd178-d901-78e8-e3a3-2d99bb475a29.png)


```index.js
import { add } from "./calculator-function";

console.log("Hello webpack");

const main = (num1, num2) => {
  const result = add(num1, num2);
  console.log(result);

  if (result < 2) {
    console.log("less than 2");
    return;
  }

  console.log("greater than or equal to 2");
};

main(1, 2);
```


バンドルするためには webpack.configファイルが必要なのでそれも作成

※どのファイルをバンドルするか、どこにバンドルするか、ローダーは何を使用するか、といったことを定義するファイル

本番環境にデプロイする時は、4行目のmodeを"production"に変更する。（Minifyで圧縮、軽量化してくれるため）

Minifyは不要な改行や空白を削除してくれます
![スクリーンショット 2023-10-06 8.12.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/7017d809-89c6-4963-9064-597a46efbb69.png)
```webpack.config.js
const path = require("path");
module.exports = {
  // バンドルモードを指定
  mode: "development",
  // エントリーポイントとしてどのファイルをまとめるかを指定（今回はsrc/index.js）
  // Pathモジュールでファイルを指定
  // __dirnameは今いる階層
  entry: path.resolve(__dirname, "./src/index.js"),
  // バンドル先にdist（distribution(配布)）フォルダを指定
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};
```

ここからはBabel-Loaderの組み込んでいきます

※CSS、Sass、Three.js、TypeScriptなど、様々な用途のローダーが存在

https://webpack.js.org/loaders/babel-loader/

Babel用のモジュールをインストール

```sh
npm i -D babel-loader @babel/core @babel/preset-env
```

設定ファイルの変更
![スクリーンショット 2023-10-06 9.21.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/928ef9b0-00ab-2b62-7198-322fc31d03a3.png)



```webpack.config.js
const path = require("path");
module.exports = {
  // バンドルモードを指定
  mode: "development",
  // エントリーポイントとしてどのファイルをまとめるかを指定（今回はsrc/index.js）
  // Pathモジュールでファイルを指定
  // __dirnameは今いる階層
  entry: path.resolve(__dirname, "./src/index.js"),
  // バンドル先にdist（distribution(配布)）フォルダを指定
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },

  // ここから追記
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/, // どの拡張子にBabel-loaderを適用させるか
        exclude: /node_modules/, // 除外するファイルやディレクトリ
        use: [
          {
            loader: "babel-loader",
          },
        ],
      },
    ],
  },
  resolve: {
    // import時の拡張子が不要になる
    // import SumType from "app/src/sumType.js"の.jsの部分
    extensions: [".js", ".jsx", ".ts", ".tsx"],
  },
  // ローカルサーバーを開く時の設定
  devServer: {
    static: {
      // distディレクトリをdevServerで監視する
      directory: path.resolve(__dirname, "dist")
    },
    port: 3000
  }
};

```

ここまで設定できたので、一旦ビルドしてバンドルファイルを確認してみます。

```sh
npm run build
```

すると distフォルダが生成されています
![スクリーンショット 2023-10-06 8.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/24263a8e-2d82-5eaa-20d7-d73e8897ad1e.png)

中には bundle.jsファイルが生成されており、バンドルされたソースが確認できました
![スクリーンショット 2023-10-06 8.53.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021235/96f86975-7038-f8b6-8624-fc3cb6f5a5e2.png)

# 補足

※2023/11/23（木）追記

TypeScriptのトランスパイル方法が色々あることを知ったので、リンクだけメモ程度に貼っておきます。

・tsc

https://note.affi-sapo-sv.com/typescript-compile.php

・babel-loader

https://chaika.hatenablog.com/entry/2021/10/30/083000

・ts-loader

https://qiita.com/SoraKumo/items/5d92b15d06778458f5e1

・ts-node

https://qiita.com/mangano-ito/items/75e65071c9c482ddc335

# 最後に

今回は基礎的な部分しか触りませんでしたが、突き詰めれば色々と便利な設定ができるようになるみたいです。

また最初にもお話しした[参考動画](https://youtu.be/Jjl8XsxSm1A?si=eU_csQhnu4SgPy8H)ではReactコードのバンドルも試しているため、気になる方はそちらもぜひどうぞ。

最後まで読んでいただきありがとうございました。