webpack入門して仲良くなりたい～Plugin編～

#仲良くなりたい

- [基本編](https://qiita.com/gabochi/items/b0bc1d522b12fe124f90)　
- [開発環境編](https://qiita.com/gabochi/items/caca7cdfaa4a35b73246)
- [Loaders編](https://qiita.com/gabochi/items/1eab632837c9831172f6)
- Plugins編　←今ココ!!

今回の記事では**Babel**と**Plugin**について書きます。

# Babel

突然出てきたBabel…
まずは、役割の確認を行います。

>Babel is a JavaScript compiler
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments. Here are the main things Babel can do for you:

引用: https://babeljs.io/docs/en/

要するに、最新のJavaScriptの記述を汎用的に使えるものに変換(トランスパイル)してくれるみたいです。

```JavaScript
// アロー関数(変換前)
[1, 2, 3].map((n) => n + 1);

// 変換後
[1, 2, 3].map(function(n) {
  return n + 1;
});
```

これを導入することで、開発時は最新の記法を使用するがブラウザに反映させるファイルは変換しているので、ファイルの考慮がいらないというわけです。

## Babel導入
### babel

それでは早速、導入していきます。
必要なパッケージを入れます。

```
npm i -D @babel/core@7.8.4 babel-loader@8.0.6 
npm i -S @babel/cli@7.8.4 @babel/preset-env@7.8.4
```

ちなみに前回の記事で紹介した`ts-loader`を使えばTypeScriptをES5にコンパイルしてくれるっぽいです。ここの章はBabelの基本的な動作が見たいのでJavaScriptで記述します。

### babel-core

babelの本体です。

### babel-loader

おなじみのローダーですね。
バンドルが実行される前にbabelを作動させるためのloaderです

### babel-preset-env

トランスパイルするためのパッケージです。

### webpack.config.jsの設定追加

```webpack.config.js
const path = require("path");
const outputPath = `${__dirname}/dist`;

// モジュールどうやって出力するか記述します
module.exports = {
  // 実行環境設定
  mode: "development",
  // エントリー ポイントを決めます
  entry: "./src/app.js", //js
  output: {
    // どこにバンドルファイルを出力するか決まます
    path: outputPath,
    // 出力先のファイル名を決めます
    filename: "bundle.js"
  },
  // loaderの設定
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  },
  devServer: {
    contentBase: outputPath
  },
// bundle.jsのコードを見やすくする
  devtool: "inline-source-map"
};
```

### .babelrc

このファイルでは、babelのコンパイル方の設定を行います。

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

### トランスパイル実行

今回バンドルするファイルはアロー関数を記述したものを使います。

```allow.js
export const allow = array => {
  var mappedArray = array.map(n => n + 1);
  return mappedArray;
};
```

buildを実行して、Babelによってトランスパイルされたファイル部分を見てみます

```bundle.js
/***/ "./src/allow.js":
/*!**********************!*\
  !*** ./src/allow.js ***!
  \**********************/
/*! exports provided: allow */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "allow", function() { return allow; });
var allow = function allow(array) {
  var mappedArray = array.map(function (n) {
    return n + 1;
  });
  return mappedArray;
};
/***/ }),
```
なんだかよさげですね！

# html出力を自動化

今までは、distフォルダ内の`index.html`を事前に用意していましたが、これもビルド時に自動生成するようにします。

## html-webpack-plugin

ここでプラグインのを使ってこの問題の解決を目指します。プラグインとはwebpackを拡張するものと考えてよさそうです。
htmlファイルの自動生成には`htnl-webpack-plugin`が必要なので早速導入します。

```
npm install -D html-webpack-plugin@3.2.0
```

次に`webpack.config.js`の編集を行います。

```webpack.config.js
const path = require("path");
const outputPath = `${__dirname}/dist`;
// プラグインの読み込み
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",
  entry: "./src/app.js",
  output: {
    path: outputPath,
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  },
  devServer: {
    contentBase: outputPath
  },
  devtool: "inline-source-map",
  // ここを追加
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    })
  ]
};
```

## plugins
ここのプロパティは配列で、使用するプラグインを追加していきます。

ここまで編集が終えたら実行してみてください。
distフォルダ内に`bundle.js`と`index.html`が出力されているはずです。

# 最後に

ここまで、webpackを使っていろいろ遊んでみました。
まだまだ、多くのLoaderやPluginが存在します。
ですが、これだけ遊んだら基本的なことがわかっているので調査も身近なものに感じると考えています。

次は、React入門して仲良くなりたいと思っています。