【小ネタ】Babelのpresetsを設定する2つの方法【Webpack】

# はじめに
昨今のJavaScriptでのフロントエンド開発において、Babel及びWebpackは無くてはならないものになっているかと思います。
通常、Babelのpresetは.babelrcに記述しますが、モジュールバンドラー側（今回の場合、具体的にはWebpack側）でも指定可能することが可能です。

Webpackを利用する開発環境において、Babelのpresetを設定する方法をまとめてみました。
\# フロントエンドを想定した内容であるため、Node APIを利用した指定方法については触れません。


# 設定する
## Webpackバージョン
Webpackは下記のバージョンを利用しました。

- webpack 4.28.3
- webpack-cli 3.1.2
- webpack-dev-server 3.1.14


## npmパッケージのインストール
では実際に設定してみます。
Babel loaderは8、Babel coreは7です。presetとして、preset-env及びpreset-reactを使います。

2019/1/1現在、インストールされるバージョンは下記のようになります。

- babel-loader 8.0.4
- @babel/core 7.2.2
- @babel/preset-env 7.2.3
- @babel/preset-react 7.0.0

インストールコマンドは下記のようになります。

```:最新版でインストール
$ npm install --save-dev webpack webpack-cli webpack-dev-server
$ npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
```

他に利用しているplug-in等が新しいバージョンに対応しておらず、古いバージョンが必要な場合は、Babel loaderの7、Babel coreの6を使うとよいでしょう。
なお、パッケージ名が変更になっているので気を付けてください。また、preset名も変更になっているので、実際のpresetの設定は読み換えてください。

- babel-loader 7.1.5
- babel-core 6.26.3
- babel-preset-env 1.7.0
- babel-preset-react 6.24.1

インストールコマンドは下記のようになります。

```:一つ前の版でインストール
$ npm install --save-dev webpack webpack-cli webpack-dev-server
$ npm install --save-dev babel-loader@7 babel-core@6 babel-preset-env babel-preset-react
```

## webpack.config.jsと.babelrcに書く
まずは、Webpackの設定ファイルwebpack.config.jsにbabel-loaderを利用する旨を設定し、.babelrcに必要なpresetを定義する方法です。
公式ドキュメントもこの方法です。
[Using Babel - How to use Babel with your tool of choice.](https://babeljs.io/setup#installation)

```javascript:webpack.config.js
const webpackConfig = {
  entry: [
    // 省略
  ],
  output: {
    // 省略
  },

  module: {
    rules: [
        {
            loader: "babel-loader",
            test: /\.js$/,
            exclude: /node_modules/
        }
    ]
  },
  devServer: {
    // 省略
  }
};

module.exports = webpackConfig;
```

```json:.babelrc
{
  "presets": ["@babel/preset-env","@babel/preset-react"]
}
```

## webpack.config.jsだけに書く
Webpackの設定ファイル内で、'babel-loader'にoptionsオブジェクトを指定し、Babelのpresetを指定する方法です。

```javascript:webpack.config.js
const webpackConfig = {
  entry: [
    // 省略
  ],
  output: {
    // 省略
  },

  module: {
    rules: [
        {
            loader: 'babel-loader',
            test: /\.js$/,
            exclude: /node_modules/,
            options: {
              presets: ["@babel/preset-env","@babel/preset-react"]
            }
        }
    ]
  },
  devServer: {
    // 省略
  }
};

module.exports = webpackConfig;
```

ちなみに以前のバージョンのWebpackでは「query」というオブジェクトで指定していたようですが、deprecatedになっているようです。

https://webpack.js.org/concepts/loaders/#loader-features
> **Loader Features**
> 
> Loaders can be configured with an options object (using query parameters to set options is still supported but has been deprecated).


# どちらの方法が良いか
どちらの方法を採用する方が良いか様々な観点がありますが、大きく以下の2つが考えられます。

- Babel開発者が推奨する方式を利用する
- プロジェクトにおける利便性の観点から、pros/consを検討する

Babelの公式ドキュメントには.babelrcを利用することを推奨している記述が散見されます
従って、前者の観点に基づく場合は.babelrcを利用する方が良いと言えます。

後者の観点に基づく場合、プロジェクト規模・位置づけによってその都度判断するのが良いと言えます。

一定規模以上のプロジェクトの場合、targets等の設定項目が増えてくると予想されるため、Babelに関する設定は全て.babelrcに寄せたほうが良いでしょう。
ただし、極小規模のプロジェクトや、何らかの機能検証等を目的とした使い捨てプロジェクトなど、難しいことを考えずにES2015(ES6)以降の機能を使いたい場合は、webpack.config.jsにまとめて書いたほうが良いように思います。


# 関連ドキュメント

> [Using Babel - How to use Babel with your tool of choice.](https://babeljs.io/setup#installation)

各環境でBabelを使うための方法が簡単にまとめられています。
「1 Choose your tool」の一覧から目的のボタンを押すと、設定方法が出てきます。


> [@babel/preset-env · Babel](https://babeljs.io/docs/en/babel-preset-env)

preset-envがどのように動くか、仕組みについての説明があります。


> [@babel/preset-react · Babel](https://babeljs.io/docs/en/babel-preset-react)

preset-reactに関するドキュメントです。
Usageとして、「Via .babelrc (Recommended)」と記載されています。


> [Loaders](https://webpack.js.org/concepts/loaders/)

WebpackのLoaderに関するドキュメントです。