webpack init で webpack.config.js を自動生成しよう

`webpack`で環境構築をする時に、毎回`webpack.config.js`を手作業で作成していました。
面倒だったので、コマンドで作成できないか調べていたら、`webpack init`で普通に出来ました！

## 使い方
`webpack init` コマンドを実行するだけです。
`npm init`と同じ感覚で、対話形式で`webpack.config.js`を自動生成してくれます。

## 実際に試してみよう

### 準備

デモ用にディレクトリを作成して、`webpack`をインストールします。
`webpack-cli`は`webpack`コマンドをCLI上で利用するためのモジュールです。

**※`npm`コマンドでパッケージ管理をすると、ビルドで失敗するので`yarn`を利用する必要があります。**

```zsh
$ mkdir webpack-init-demo && cd webpack-init-demo
$ yarn init -y
$ yarn add webpack webpack-cli
```

### webpack.config.jsの生成
対話項目については、公式のリポジトリにドキュメントが置いてあるので、そちらをご参照ください。  
[webpack-cli/INIT.md at master · webpack/webpack-cli](https://github.com/webpack/webpack-cli/blob/master/INIT.md)

```zsh
$ npx webpack init

ℹ INFO For more information and a detailed description of each question, have a look at https://github.com/webpack/webpack-cli/blob/master/INIT.md
ℹ INFO Alternatively, run `webpack(-cli) --help` for usage info.

? Will your application have multiple bundles? No
? Which module will be the first to enter the application? [default: ./src/index]
? Which folder will your generated bundles be in? [default: dist]:
? Are you going to use this in production? No
? Will you be using ES2015? Yes
? Will you use one of the below CSS solutions? CSS
? Name your 'webpack.[name].js?' [default: 'config']:
yarn add v1.6.0
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
...
```

```js:webpack.config.js
const webpack = require('webpack');
const path = require('path');

/*
 * We've enabled UglifyJSPlugin for you! This minifies your app
 * in order to load faster and run less javascript.
 *
 * https://github.com/webpack-contrib/uglifyjs-webpack-plugin
 *
 */

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

/*
 * SplitChunksPlugin is enabled by default and replaced
 * deprecated CommonsChunkPlugin. It automatically identifies modules which
 * should be splitted of chunk by heuristics using module duplication count and
 * module category (i. e. node_modules). And splits the chunks…
 *
 * It is safe to remove "splitChunks" from the generated configuration
 * and was added as an educational example.
 *
 * https://webpack.js.org/plugins/split-chunks-plugin/
 *
 */

module.exports = {
	output: {
		filename: '[name].[chunkhash].js',
		chunkFilename: '[name].[chunkhash].js',
		path: path.resolve(__dirname, 'dist')
	},

	module: {
		rules: [
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel-loader',

				options: {
					presets: ['env']
				}
			},
			{
				test: /\.css$/,

				use: [
					{
						loader: 'style-loader',

						options: {
							sourceMap: true
						}
					},
					{
						loader: 'css-loader'
					}
				]
			}
		]
	},

	plugins: [new UglifyJSPlugin()],
	mode: 'development',

	optimization: {
		splitChunks: {
			chunks: 'async',
			minSize: 30000,
			minChunks: 1,
			name: true,

			cacheGroups: {
				vendors: {
					test: /[\\/]node_modules[\\/]/,
					priority: -10
				}
			}
		}
	}
};
```

### ビルド
最後に簡単なコードを書いて、ビルド出来るか確認してみます。

```js:index.js
import _ from 'lodash'

_.each([1,2,3], (v) => console.log(v*2))
```

```zsh
$ mkdir src && touch src/index.js
$ yarn add lodash
$ npx webpack
Hash: b3b3346c1e5aee203d71
Version: webpack 4.6.0
Time: 3397ms
Built at: 2018-04-21 22:45:06
                       Asset     Size  Chunks             Chunk Names
main.c1f2e2395b8f15edd497.js  548 KiB    main  [emitted]  main
Entrypoint main = main.c1f2e2395b8f15edd497.js
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 489 bytes {main} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {main} [built]
[./src/index.js] 275 bytes {main} [built]
    + 1 hidden module
$ node dist/main.c1f2e2395b8f15edd497.js
2
4
6
```

無事にビルドできました！(･ω･ﾉﾉﾞ☆ﾊﾟﾁﾊﾟﾁ

### ビルドエラーについて
最後に自分がハマったビルドエラーについて補足しておきます。
`npm`を利用すると、ビルド時に`ERROR in Entry module not found: Error: Can't resolve 'babel-loader'`が発生して、ビルドに失敗していました。

恐らく原因としては`webpack.config.js`が生成される時に、`yarn add`で依存モジュールを追加しているのですが、この時に`yarn`側の問題が発生しているのかな？と思います。

別リポジトリにも同じ内容のissueがあり、これと同じ現象が起きていると思われます。
[Entry module not found: Error: Can't resolve 'babel-loader' · Issue #237 · symfony/webpack-encore](https://github.com/symfony/webpack-encore/issues/237)