kosappi の日記

愛知県豊橋市に住んでます。

webpack を小さく試す

学生時代から今日まで、何度も JavaScript を書く機会はあったが、いまだに良くわかっていない。 特にバンドルツールやパッケージマネージャの話が出てくると???となる。 チームの詳しい人が整備してくれた環境をなんとなく使ったりアップデートする、という状況が続いている。 まずは webpack を理解したい。 そのために、小さい構成で webpack を試してみたい。

webpack

github.com

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

ブラウザで使用するために JavaScript ファイルをバンドルしてくれるツールで、いろんなリソースやアセットを変換したりバンドルしたりパッケージ化することができる。 開発中は、個別の JavaScript ファイルの間に依存関係が存在している状態が続くが、プロダクションに出す際に webpack を通すことで、1つの JavaScript ファイルにまとめてくれる。

試す

仕事で使う際はある程度育ったリポジトリで webpack を実行することが多いと思うが、今回は少ないファイル構成でやりたい。 複数の JavaScript ファイルを用意して、webpack で1つのファイルにしたい。

バンドル前

作業するディレクトリはあらかじめ git init しておく。 下記2つをバンドルしたい。

src/index.js

import messages from './messages.js';

console.log(messages);

src/messages.js

export const messages = ['first_message', 'second_message'];

webpack のインストール

まずはインストール。公式ドキュメントを見つつインストールする。

Getting Started | webpack

npm init -y
npm install webpack webpack-cli --save-dev

いろいろ置かれるので、一度 git status してみる。

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    node_modules/
    package-lock.json
    package.json

nothing added to commit but untracked files present (use "git add" to track)

node_modules は npm がインストールしてくれたモジュール達なので ignore する。

echo node_modules/\*\* > .gitignore

package.jsonpackage-lock.json はコミットする。

webpack の設定

We also need to adjust our package.json file in order to make sure we mark our package as private, as well as removing the main entry. This is to prevent an accidental publish of your code.

とのことなので package.json を編集する。

--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "webpack_test",
   "version": "1.0.0",
   "description": "",
-  "main": "index.js",
+  "private": true,
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },

webpack.config.js はなくてもいい感じにやってくれるらしい。

実行結果

実行するとこういう出力になった。

$ npx webapck
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/webapck - Not found
npm ERR! 404
npm ERR! 404  'webapck@latest' is not in this registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)

npm install webpack@latest --save-dev で更新した。 もう一度実行する。

$ npx webpack
asset main.js 223 bytes [emitted] [minimized] (name: main)
orphan modules 62 bytes [orphan] 1 module
runtime modules 274 bytes 1 module
./src/index.js + 1 modules 124 bytes [built] [code generated]

WARNING in ./src/index.js 3:12-20
export 'default' (imported as 'messages') was not found in './messages.js' (possible exports: messages)

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpack 5.64.2 compiled with 2 warnings in 240 ms

今回は html を置いていないため orphan なのは想定通り。 警告を順番にみていく。

WARNING in ./src/index.js 3:12-20
export 'default' (imported as 'messages') was not found in './messages.js' (possible exports: messages)

import 文が間違ってるので下記のように修正してパスした。 import 文を理解できてないことがバレた...。

import - JavaScript | MDN

-import messages from './messages.js';
+import { messages } from './messages.js';

次の警告。

The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

mode を設定してとのこと。 今回は設定ファイルなしでやっているので、コマンドに追加のオプションを加えてみる。

$ npx webpack --mode=development

asset main.js 4.15 KiB [emitted] (name: main)
runtime modules 670 bytes 3 modules
cacheable modules 128 bytes
  ./src/index.js 66 bytes [built] [code generated]
  ./src/messages.js 62 bytes [built] [code generated]
webpack 5.64.2 compiled successfully in 78 ms

パスした。

バンドル後

dist/main.js が成果物として置かれるのだが --mode=development で書き出したため、開発用の便利ツールが含まれた大きな js になっている。 今回はバンドルの様子だけ知りたかったので --mode=production でもう一度やってみる。

$ npx webpack --mode=production

asset main.js 71 bytes [emitted] [minimized] (name: main)
orphan modules 62 bytes [orphan] 1 module
./src/index.js + 1 modules 128 bytes [built] [code generated]
webpack 5.64.2 compiled successfully in 163 ms

結果はこのようになった。

$ cat ./dist/main.js
(()=>{"use strict";console.log(["first_message","second_message"])})();%

なるほど。 依存先のソースを取り込んで、短い js に変換してくれている。

感想

最小限の構成で webpack を使ってみた。 ここからいろいろ足して、プロダクションコードで理解できていなかったアレとかコレを再現させてみたい。