お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
Node.js::webpack

バンドル内容をHTMLに注入するの続き

Webpackには次の2つの開発モードがあるdevelopment, production

開発モードの設定

modeプロパティに'development', 'production', 'none'を設定する
これを設定するとprocess.env.NODE_ENVで値を取得できる様になる
それぞれの違いは mode-development にあるが、試してみた感じproductionは出力が最適化され、console系が消えるものと思われる
noneを設定するとminifyとかがされてない生のコードが出てくる

webpack.config.js

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

module.exports = {
+  mode: 'development', 
  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'
     })
  ]
};
投稿日:
Node.js::webpack

基本的なバンドルの続き

複数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>
投稿日:
Node.js::webpack

webpackとはなんぞやというところで軽く調べてみたメモ
ほぼ公式のチュートリアル
やれることが非常に多いので公式ドキュメントを読むのが一番良い

確認環境

Env ver
webpack 5.41.0
webpack-cli 4.7.2

webpackとは

JavaScriptのモジュールバンドラで次の機能を持つ

  • JSやCSS、画像ファイルやデータファイルなどの各種静的ファイルを出力フォルダにまとめて吐く
  • ブラウザのキャッシュの影響を回避するために、出力ファイル名を毎回変える
  • index.htmlに必要なファイル参照を自動で埋め込む
  • 出力フォルダのクリーンアップ
  • HMR用のサーバーを起動する
  • Sourcemapを吐く
  • 次の構成を利用したビルドパイプラインを構成する
    • TypeScript, CoffeeScript, Babel and JSX
  • その他色々
    • 豊富なAPIと設定が存在するのでいろんな事ができる!

webpackを試してみる

取り敢えずこんな感じのプロジェクトを作る

  1. npm init
  2. npm i -D webpack webpack-cli lodash
|- package.json
|- /dist
|- index.html
|- /src
  |- index.js

index.html

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

src/index.js

import _ from 'lodash';

function component() {
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return div;
}

document.body.appendChild(component());

npx webpackを流してバンドルしてあげるとlodashが組み込まれたJSが吐き出される

CSSのバンドル

  1. npm i -D style-loader css-loaderを流して
  2. webpack.config.jssrc/index.cssを作成
  3. src/index.jsもちょっと書き換えます

webpack.config.js

const path = require('path');

module.exports = {
   entry: './src/index.js',
   output: {
    filename: 'bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
   module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

src/index.css

.hello {
  color: red;
}

src/index.js

import _ from 'lodash';
+import './index.css';

function component() {
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');
+  div.classList.add('hello');

  return div;
}

document.body.appendChild(component());

この状態でnpx webpackを流すとCSSのバンドルが確認出来る

assetsのバンドル

webpack.config.js

const path = require('path');

module.exports = {
   entry: './src/index.js',
   output: {
    filename: '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',
+      },
    ],
  },
};

src/index.js

import _ from 'lodash';
import './index.css';
+import Icon from './icon.png';

function component() {
  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());

フォントファイルやデータファイルのバンドル

基本は同じなので公式のガイドを見るとわかりやすい