ちょっとがんばるWebサイト開発 on Webpack5 - HTMLをコピー＆ペーストする

# 前書き

## 本記事のゴール

この記事では、ソースフォルダ `/src` および配信用フォルダ `/dist` を管理するプロジェクトにおいて、Webpackを利用して `/src` フォルダに含まれるHTMLファイルを `/dist` フォルダに移動させる（コピー＆ペーストする）方法を理解することを目指します。

## この記事で解説する内容

- ソースフォルダ `/src` および配信用フォルダ `/dist` の分割管理について説明します
- `/src` フォルダに含まれるHTMLファイルを `/dist` にコピー＆ペーストする方法を説明します
- 簡単な実例を示します

## この記事で解説しない内容

- CSS/JavaScript等HTML以外のファイル形式は取り扱いません

## シリーズ記事

この記事はシリーズ **「ちょっとがんばるWebサイト開発 on Webpack5」** の記事です。
シリーズ全体の概要は [以下のリンク先記事](https://qiita.com/Sharkkii/items/df707cb68f3729493800) にまとめられています。

https://qiita.com/Sharkkii/items/df707cb68f3729493800

:::note info
この記事では **Webpack5** (version5.X.X) を対象としています。
:::

# 背景知識

## ソースフォルダ `/src` ・配信用フォルダ `/dist` 

一般にプロジェクト開発では、ソースコード（開発者が手動で実装したコード）と配信用コード（利用/公開するコード）を分離して管理することがあります。例えば、C/Java言語のようにコンパイルが必要な言語を使用する場合や、ソースコードの一部または全部を非公開にしたい場合にそのような管理方法を採用します。慣例的に、ソースコードは `/src` フォルダに、配信用コードは `/dist` に格納されることが多いです[^1]。

## このシリーズ記事における設計思想

このシリーズ記事では、ソースコードの一部または全部に対して各種変換処理/最適化を行うことでWebサイトとして公開する配信用コードを生成することを想定します。そのため、C/Java言語のプロジェクトと同様に、ソースコードと配信用コードを分離して管理することにしています。慣例に倣って、ソースコードを `/src` フォルダに、配信用コードを `/dist` に格納しています。

それに加えて、配信用コードはそのままの形で利用可能であることが望ましいと考えています。すなわち、配信用コードにはWebサイトの公開に必要なものがすべて含まれており、`/dist` ディレクトリ配下のファイル群をWebサーバにアップロードすることで完全なWebサイトになるような設計を目指します。そのため、プロジェクトのビルドの出力結果が完全なWebサイトになるように設定します。

実践的なプロジェクトでは、すべてのソースファイルに対して変換処理/最適化を行うとは限りません。例えば、ソースHTMLファイルをそのままの形で利用/公開したい場合もあるでしょう。そうした場合（実装したソースコードと利用/公開する配信コードが同一の場合）でも、当該ファイルを `/src` フォルダから `/dist` フォルダに移動させる（コピー＆ペースト）するようにします。それによって、Webサーバにアップロードすべきファイル/フォルダを `/dist` フォルダで統一的に管理することができるようになり、配信用コードを選別する時間的コストを削減することができます。

なお、単純なファイル/フォルダのコピー＆ペーストはシェルスクリプト等によっても実現可能ですが、このシリーズ記事ではWebpackを利用して解決することにしています。ビルド作業全体をWebpackに集約することでビルドツールの管理コストも削減することができますし、新たに変換処理/最適化を適用したくなった際にも比較的容易に移行することができるためです。

# 方法

:::note info
サンプルコードをGitHubで公開しています。記事と併せてご覧ください。
**[/website/website-dev-on-webpack5/plain-html-on-webpack5](https://github.com/Sharkkii/sample-codes/tree/develop/website/website-dev-on-webpack5/plain-html-on-webpack5)**
:::

:::note info
実装例の説明では、ファイル/フォルダパスを *ルート相対パス* の形式で記述しています。ここでルートはプロジェクトルートまたはWebサイトのドキュメントルートに相当します。
:::

## 準備

Webpackを含むNode.jsパッケージの利用には [Node.js](https://nodejs.org/ja/) が必要です。
インストールが未実施の場合には、以下のリンクからインストールしておいてください。

https://nodejs.org/ja/

また、動作確認を行うためのNode.jsプロジェクトを作成しておきます。
適当な名前のディレクトリ（ここでは `my-html-project` ）を用意した上で、そのディレクトリにおいて `npm init` コマンドを実行することでNode.jsプロジェクトを新規作成することができます。

```shell:ターミナル
# my-html-projectディレクトリの作成
mkdir /path/to/my-html-project
cd /path/to/my-html-project

# Node.jsプロジェクトの作成
npm init
```

`npm init` コマンドを実行するとプロジェクトに関する情報を入力するよう促されますが、今回は適当な設定にしておいて問題ありません。今後必要に応じて適宜変更しましょう。
コマンド実行完了後、 `/package.json` という設定ファイルが新規作成されていることを確認したら事前準備完了です。

## 手順概要

1. [npmパッケージを導入する](#手順1-npmパッケージを導入する)
HTMLのコピー＆ペーストに必要なnpmパッケージ　`webpack` `webpack-cli` `html-webpack-plugin` をプロジェクトに追加します。

2. [Webpackの設定ファイルを記述する](#手順2-webpackの設定ファイルを記述する)
HTMLをコピー＆ペーストする手順やルールを設定ファイル `/webpack.config.js` に記述します。

3. [HTMLファイルを作成する](#手順3-htmlファイルを作成する)
動作確認用のHTMLファイル `/src/source.html` を作成します。

4. [Webpackのビルドを実行する](#手順4-webpackのビルドを実行する)
Webpackのビルドを実行することで、HTMLファイル `/dist/target.html` を生成（コピー＆ペースト）します。

## 手順詳細

### [手順1] npmパッケージを導入する

今回は [Webpack](https://webpack.js.org/) を利用してHTMLファイルのコピー＆ペーストを行います。

まず初めに、Webpackを利用するのに必要な　`webpack` `webpack-cli` パッケージをインストールします。
Webpack5（version5.X.X）をインストールするため、バージョン指定を行っています。

https://webpack.js.org/

```shell:ターミナル
npm install --save-dev webpack@5 webpack-cli@5
```

次に、HTMLファイルをコピー＆ペーストするのに必要な　`html-webpack-plugin` パッケージをインストールします。

https://www.npmjs.com/package/html-webpack-plugin

```shell:ターミナル
npm install --save-dev html-webpack-plugin
```

### [手順2] Webpackの設定ファイルを記述する

Webpackは、適切に設定を記述することで様々な処理を実行することができます。
ここではHTMLファイル　`/src/source.html` をコピーして `/dist/target.html` にペーストするための必要最小限の設定を示します。

```js:/webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = function() {
  return {

    mode: "development",

    entry: {},

    output: {
      path: path.resolve(__dirname, "dist"),
    },
    
    plugins: [
      new HtmlWebpackPlugin({
        template: path.resolve(__dirname, "src", "source.html"),
        filename: "target.html",
        minify: {
          collapseWhitespace: true,
          preserveLineBreaks: true,
        },
      }),
    ],

  }
}
```

上記の設定を要約すると、
**Webpackのプラグイン設定箇所に、適切な設定を含む `HtmlWebpackPlugin({...})` オブジェクトを追加する**
となります。特に注目すべきパラメータは以下の通りです。

- `template: path.resolve(__dirname, "src", "source.html")`
入力HTMLファイルの *絶対パス* を指定する

- `filename: "target.html"`
出力HTMLファイルの *相対パス* を指定する

なお、入力HTMLファイルパスは絶対パス、出力HTMLファイルパスは相対パスになっていることに注意してください。

:::note warn
上記Webpack設定ではエントリ設定を空にしています（`entry: {}`）が、この設定は省略することができません。エントリ設定を省略するとWebpackは空ではないデフォルト値を使用する（`entry: "./src/index.js"`）ため、当該ファイルが存在しないという旨のエラーが発生します。
Webpack設定の詳細については別記事を参照してください。

> [参考] Webpackエントリ設定
> [Webpack - Concepts#Entry](https://webpack.js.org/concepts/#entry)
:::

> [参考] Webpackの設定方法およびHTMLWebpackPluginの各種パラメータに関する詳細説明
> - [Webpack - Concepts](https://webpack.js.org/concepts)
> - [Webpack - Plugins](https://webpack.js.org/concepts/plugins/)
> - [HTMLWebpackPlugin](https://github.com/jantimon/html-webpack-plugin)

### [手順3] HTMLファイルを作成する

手順2の設定に従ってHTMLファイルを作成します。
上記設定ファイル `/webpack.config.js` では入力HTMLファイルパスを　`/src/source.html` に指定したので、その位置に `source.html` ファイルを作成しましょう。
ファイル内容はどんなものでも構いませんが、ここでは例として以下のように記述することにします（折りたたみ要素の中にあります）。

<details>
<summary> /src/source.html の入力内容例</summary>

```html:/src/source.html
<!doctype html>
<html>
  <head>
    <title>My HTML Project</title>
  </head>
  <body>
    <h1>Hello, Webpack!</h1>
  </body>
</html>
```
</details>

### [手順4] Webpackのビルドを実行する

手順1〜3でHTMLのコピー＆ペーストのための準備が完了しました！
それではWebpackを用いて `/src/source.html` から `/dist/target.html` を生成（コピー＆ペースト）してみましょう。
ターミナルで `npx webpack` コマンドを実行することでビルド作業が開始します。

```shell:ターミナル
# ディレクトリ移動
cd /path/to/my-html-project

# Webpackコマンド実行
npx webpack
```

ビルドが正常に完了すれば、`/src/source.html` と同一内容のHTMLファイル `/dist/target.html` が生成されていることを確認できると思います。

<details>
<summary>　/dist/target.html の出力内容例</summary>

```html:/dist/target.html
<!doctype html>
<html>
<head>
<title>My HTML Project</title>
</head>
<body>
<h1>Hello, Webpack!</h1>
</body>
</html>
```
</details>

# 後書き

**サンプルコード**
**[/website/website-dev-on-webpack5/plain-html-on-webpack5](https://github.com/Sharkkii/tech-blog-code/tree/develop/website/website-dev-on-webpack5/plain-html-on-webpack5)**

[^1]: ソースコードをビルドして利用/公開するコードを生成するプロジェクトでは、ビルドの出力結果を `/build` に格納することもあります。その他のディレクトリの命名方法については [この記事](https://tenderfeel.xsrv.jp/memo/1229/) に詳しいです。