(Part 2. Config Webpack4) Startup JavaScript Project with Webpack4, Vue2, Vue-Router, Vuex, Axios, ESLint, Babel, AirBnb

We will use three webpack configuration files. This way can make project maintenance easier and more flexible.
>
* webpack.common.js <-- Put the common settings.
* webpack.dev.js    <-- Only put the develop period settings
* webpack.prod.js   <-- Only Put the release production settings.


# Step 1. Setup webpack.common.js

* **webpack.common.js**

```javascript:webpack.common.js
/* eslint-disable import/no-extraneous-dependencies */ <-- If you use ESLint, add this.
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
```
```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  entry: {
    app: [
      'babel-polyfill', <-- This setting is used for JS promise that make it can run on older browser.
      './src/Main.js',
    ],
  },
  ...
  ...
  ...
}
```

```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js',
  },
  ...
  ...
  ...
}
```

```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  resolve: {
    extensions: ['.js', '.vue', '.json', '.css'],
    alias: {
      vue$: 'vue/dist/vue.esm.js', <-- This setting is must for Vue2.
      '@': path.resolve(__dirname, 'src'), <-- This let us can used "import foo from '@/foo/foo';" instead of "import foo from '../../foo/foo';"
    },
  },
  ...
  ...
  ...
}
```

```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.(vue|js)$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        loader: 'eslint-loader',
      },
      {
        test: /\.vue$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        loader: 'vue-loader',
      },
      {
        test: /\.js$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        loader: 'babel-loader',
      },
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)(\?.+)?$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
            },
          },
        ],
      },
    ],
  },
  ...
  ...
  ...
}
```

```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  target: 'web',

  watchOptions: {
    ignored: /node_modules/,
    aggregateTimeout: 300,
    poll: 1000,
  },
  ...
  ...
  ...
}
```

```javascript:webpack.common.js
module.exports = {
  ...
  ...
  ...
  plugins: [
    new VueLoaderPlugin(),
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
      title: 'Johnny Chu Demo',
      template: 'index.html',
    }),
  ],
  ...
  ...
  ...
}
```


# Step 2. Setup webpack.dev.js

* **webpack.dev.js**

```javascript:webpack.dev.js
/* eslint-disable import/no-extraneous-dependencies */ <-- If you use ESLint, add this.
const path = require('path');
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const common = require('./webpack.common.js');
```
```javascript:webpack.dev.js
module.exports = merge(common, {
  ...
  ...
  ...
  mode: 'development',
  devtool: '#eval-source-map',
  devServer: {
    compress: true,
    contentBase: 'dist',
    historyApiFallback: true,
    host: '0.0.0.0',
    hot: true,
    port: 9487,
  },
  ...
  ...
  ...
}
```
```javascript:webpack.dev.js
module.exports = merge(common, {
  ...
  ...
  ...
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        use: [
          'vue-style-loader',
          'css-loader',
        ],
      },
    ],
  },
  ...
  ...
  ...
}
```

```javascript:webpack.dev.js
module.exports = merge(common, {
  ...
  ...
  ...
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  ...
  ...
  ...
}
```



# Step 3. Setup webpack.prod.js

* **webpack.prod.js**

```javascript:webpack.prod.js
/* eslint-disable import/no-extraneous-dependencies */ <-- If you use ESLint, add this.
const path = require('path');
const merge = require('webpack-merge');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const common = require('./webpack.common.js');
```

```javascript:webpack.prod.js
module.exports = merge(common, {
  ...
  ...
  ...
  mode: 'production',
  devtool: '#source-map',
  ...
  ...
  ...
}
```

```javascript:webpack.prod.js
module.exports = merge(common, {
  ...
  ...
  ...
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true,
      }),
      new OptimizeCSSAssetsPlugin({}),
    ],
  },
  ...
  ...
  ...
}
```

```javascript:webpack.prod.js
module.exports = merge(common, {
  ...
  ...
  ...
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash].js',
    chunkFilename: '[id].[chunkhash].js',
  },
  ...
  ...
  ...
}
```

```javascript:webpack.prod.js
module.exports = merge(common, {
  ...
  ...
  ...
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        include: [path.resolve('src')],
        exclude: [path.resolve('node_modules')],
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
  ...
  ...
  ...
}
```

```javascript:webpack.prod.js
module.exports = merge(common, {
  ...
  ...
  ...
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[hash].css',
      chunkFilename: '[id].[hash].css',
    }),
  ],
  ...
  ...
  ...
}
```

[Part 6. Config index.html](https://qiita.com/shaching/items/3d7fcc34204af9aaaa29)

[Part 5. Config .stylelintrc.json](https://qiita.com/shaching/items/5f21f396f08c45ff598c)

[Part 4. Config .eslintrc.json](https://qiita.com/shaching/items/288926001dbbbc905953)

[Part 3. Config .babelrc](https://qiita.com/shaching/items/8eac974989f32379a5fe)

[Part 2. Config Webpack4](https://qiita.com/shaching/items/a72565bd0836a83df79c)

[Part 1. Install package.json](https://qiita.com/shaching/items/522f4c9f01662a592bb8)

[Github : Vue2-Starter-Kit](https://github.com/shaching/Vue2-Starter-Kit)