webpackメモ:バンドル内容をHTMLに注入する

基本的なバンドルの続き

複数JSの個別バンドル

src/print.jsを追加して、関係するファイルも幾らか変更する

src/print.js

export const printMe = () => {
  console.log('I get called from print.js!');
}

src/index.js

import _ from 'lodash';
-import './index.css';
-import Icon from './icon.png';
+import { printMe } from './print';

function component() {
+  window.onload = printMe;

  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');
-    div.classList.add('hello');
-
-    const img = document.createElement('img');
-    img.src = Icon;
-    div.appendChild(img);

  return div;
}

document.body.appendChild(component());

webpack.config.js

const path = require('path');

module.exports = {
-   entry: './src/index.js',
+  entry: {
+    index: './src/index.js',
+    print: './src/print.js',
+  },
   output: {
-    filename: 'bundle.js',
+    filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
-   module: {
-    rules: [
-      {
-        test: /\.css$/i,
-        use: ['style-loader', 'css-loader'],
-      },
-      {
-        test: /\.(png|svg|jpg|jpeg|gif)$/i,
-        type: 'asset/resource',
-      },
-    ],
-  },
};

この状態でバンドルするとindex.bundle.jsとprint.bundle.jsが生えてくるが、前回バンドルした残骸が残ってしまう

バンドル時に出力フォルダをクリーンアップする

webpack.config.js

const path = require('path');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
+     clean: true,
   },
};

バンドルした内容をHTMLに反映する

この時点のindex.htmlはdist/bundle.jsを参照しているので、今回の結果が反映されていません
これが反映されるように修正します

npm i -D html-webpack-plugin

webpack.config.js

const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
+   plugins: [
+      new HtmlWebpackPlugin({
+        title: 'Webpack',
+      })
+   ]
};

これで設定したバンドルファイルがindex.htmlに反映されるようになりました

HTMLのテンプレートを用意する

しかし先程の設定では出力されるHTMLにどうしても限界があります
HtmlWebpackPlugin のリファレンスを見ることである程度なんとかなりますが、テンプレートに差し込むこともできます

次のように変えることでテンプレートHTMLにバンドルを差し込むことが確認できます

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
   plugins: [
      new HtmlWebpackPlugin({
        title: 'Webpack',
+        template: 'index.html'
      })
   ]
};

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
-    <title>Getting Started</title>
  </head>
  <body>
    <script src="dist/bundle.js"></script>
+    <h1>Webpack</h1>
  </body>
</html>