webpackでの初めての環境構築 / フロントエンド

プログラミングを初めてまだ3ヶ月ですが、色々調べながら初めて環境を作ってみたので記録として残してみようと思います。
*今後使用していくうちにupdateしていく箇所や先輩方からのご指摘でより良いものに出来たらと思っております。
参考にさせて頂いたのはこちらのサイトです。
[【2019年版】webpack 4 個人的設定まとめ](https://www.expexp.jp/webpack4-2019/)

今回は下記画像のような構造に致しました。
srcディレクトリで作業し、build後にdistディレクトリにコンパイル後のコードを反映させます。

```
├── dist
│   ├── assets
│   │   ├── img
│   │   └── style.css
│   ├── bundle.js
│   └── index.html
├── package-lock.json
├── package.json
├── src
│   ├── assets
│   │   ├── img
│   │   ├── js
│   │   └── scss
│   ├── index.js
│   ├── index.pug
│   └── pug
│       ├── _footer.pug
│       ├── _header.pug
│       └── _template.pug
└── webpack.config.js
```
```package.json
{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "build": "webpack --mode=production",
    "build:dev": "webpack --mode=development --watch",
    "start:dev": "webpack-dev-server --mode=development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "clean-webpack-plugin": "^1.0.1",
    "css-loader": "^2.1.0",
    "file-loader": "^4.2.0",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.5.0",
    "node-sass": "^4.11.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "pug": "^2.0.3",
    "pug-loader": "^2.4.0",
    "sass-loader": "^7.1.0",
    "terser-webpack-plugin": "^1.4.1",
    "url-loader": "^2.1.0",
    "webpack": "^4.29.0",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.8.0"
  }
}
```
```webpack.config.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = ( env, argv ) => ({
  entry: {
    'dist/bundle.js':'./src/index.js',
  },
  output: {
    filename: ('bundle.js'),
    path: path.resolve(__dirname, 'dist')
  },

  // 最適化オプションを上書き
  optimization: {
    minimizer: [
      new TerserPlugin({}),
      new OptimizeCssAssetsPlugin({})
    ]
  },

  devtool: 'inline-source-map',

  //サーバーの設定 npm run start:dev
  devServer: {
    contentBase: path.resolve(__dirname, 'src'),
    // watchContentBase: true,
    compress: true,
    port: 8000,
    open: true,
  },

  module: {
    rules: [
      // pug-loaderの設定
      {
        test: /\.pug$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'pug-loader',
            options: {
              pretty: true,
              root: path.resolve(__dirname,'src'),
            }
          }
        ]
      },

      // babel-loaderの設定
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env']
            }
          }
        ],
        exclude: /node_modules/,
      },

      // css/sass-loaderの設定
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              url: true
            }
          },
          'sass-loader'
        ]
      },

      // imgの設定
      {
        test: /\.(png|svg|jpe?g|gif)/,
        use: {
          loader:'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: './assets/img/',
            publicPath: '../assets/img'
          }
        }
      }
    ]
  },

  plugins: [
    new CleanWebpackPlugin(
      ['dist'],
      {
        // 除外するファイルやディレクトリを指定
        exclude: ['img']
      }
    ),
    new MiniCssExtractPlugin({
      filename: './assets/style.css'
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './src/index.pug',
    }),
  ]
});

```

上記のようにしましたが結構手こずったところがありまして

```webpack.config.js
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              url: true
            }
          },
          'sass-loader'
        ]
      },
```
**webpack.config.js/css, scssの設定**　
url:trueをfalseのまま実行していたのでscssなどで画像ファイルが読み取れずbuild後も画像ファイルはbuildされないということがわからず手こずりました。。。
ここを変更しないとfile-loaderやurl-loaderが効きませんでした。

trueに変更することでscssで指定した画像urlを読み取りbuild後もassets配下でimgディレクトリとして出せました。


```index.pug
  img(src=require(`${assets_dir}img/image.png`))
  img(src=require("./assets/img/image.png"))
```
pugに書き込んだ画像urlは**require**を付けてあげないとbuildしてくれませんでした。。。


上記修整を持って、開発時は
```"start:dev": "webpack-dev-server --mode=development"```
```"build:dev": "webpack --mode=development --watch"```

上記で行ってみようかと思います。