webpackで画像やcssの読み込みをさせるまでにやったこと

TypeScriptプロジェクトでwebpackを使ったサイトの開発を行っています。
webpackインストール後、標準設定のままでは開発環境で画像やCSSファイルが正常に読み込めなかったため対処したことの記録です。

# 大雑把なまとめ
* 開発環境、本番環境それぞれのリソースを置くディレクトリを作成
* configで開発環境のファイル参照先を指定するpublicPathを追加
* 画像、CSSを読み込むためのパッケージを追加
* ビルド時に開発環境のリソースを本番用のディレクトリにコピーするプラグインを追加


最終的な階層構造は以下のようになりました。
```
project/
　├ dist/
　│　└ resource/
　│　   └ img/ // 本番環境の画像ファイル
　│　   └ css/ // 本番環境のCSSファイル
　│　└ index.html
　│　└ main.js
　│　└ // 各種jsファイル
　│　
　├ src/
　│　└ img/ // 開発環境の画像ファイル
　│　└ css/ // 開発環境のcssファイル
　│　└ index.ts
　│　
　├ index.html
　├ package-lock.json
　├ package.json
　├ tsconfig.json
　├ postcss.config.js
　└ webpack.config.js
```

# やったこと詳細
## devServerの設定内にpublicPathを追加
publicPathは出力するファイルのパスを指定するためのオプション。
* devServer.staticプロパティを追加。
    * ビルド結果が出力されるdistディレクトリを設定
```webpack.config.js

const config = {
  entry: "./src/index.ts",
  output: {
    path: path.resolve(__dirname, "dist"),
  },
  devServer: {
    open: true,
    host: "localhost",
    static: {
      directory: path.join(__dirname, "dist"), // これを追加
    },
  },
```

## file-loaderを入れる
画像ファイルをバンドルするnpmパッケージ。

https://v4.webpack.js.org/loaders/file-loader/#name-1

* インストール
```
npm install --save-dev file-loader
```

* package.json内に"file-loader"が追加されていることを確認する

* webpack.config.jsに設定を追加
```webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const config = {
 // 中略
  plugins: [
 // 中略
      // Add your rules for custom modules here
      // ----- ここからfile-loader追加 ----- 
      {
        test: /\.(png|jpg|gif|svg)/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'img/[name].[ext]'
            }
          }
        ]
      },
      // ----- ここまで ----- 
      // Learn more about loaders from https://webpack.js.org/loaders/
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".jsx", ".js", "..."],
  },
};

```

## css-loaderを入れる
CSSをバンドルするnpmパッケージ。
これはwebpackインストール時のオプション設定でCSS関連ソリューションを使用する設定をしていたため、最初から入ってました。
あとから追加する場合は上記file-loaderと同様にインストール&configに追記で対応。

## copy-webpack-pluginを入れる
ビルド時に指定したディレクトリへファイルをコピーするプラグイン。

* インストール
```
npm install --save-dev copy-webpack-plugin
```

* Webpackの設定ファイルにcopy-webpack-pluginを追加

```webpack.config.js
// ビルド時にsrc内のリソースをdistへコピーするためのプラグイン
const CopyWebpackPlugin = require('copy-webpack-plugin');

const config = {
  // 中略
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html",
    }),

    // Add your plugins here
    // Learn more about plugins from https://webpack.js.org/configuration/plugins/
    // ----- ここからプラグイン追加 -----
    new CopyWebpackPlugin({
      patterns: [
        { from: 'src/img', to: 'resource/img' },
        { from: 'src/css', to: 'resource/css' }
      ]
    }),
    // ----- ここまで -----
  ],
```

今回はビルド時に `src/img` `src/css` にあるファイルをそれぞれ
`dist/resource/img` `dist/resource/css` にコピーするように設定。

## htmlファイルでの参照パスの指定
1つめの手順でdevServerのpublicPathを `dist` に設定しているので、`dist` ディレクトリ内のリソースファイルパスを指定しました。
```index.html
 <img src="resource/img/画像ファイル名.png">

 <link rel="stylesheet" href="resource/css/CSSファイル名.css">
```

#
ここまでで、開発環境でも画像やCSSを正しく読み込んで表示できるようになりました。

srcディレクトリ内にリソースファイルを追加編集して、ビルドしてdistに写ったファイルをdev環境から参照する。という流れになっていますが、これが適切な運用なのかは分かりません。