Back to tech

webpack を入門してみた

5 min read
Table of Contents

スマートプラグをWebアプリから操作できるようにしてみた で react を初めて使ってみた傍らで webpack も初めて使ってみました。

今まで食わず嫌いで触ってはこなかったのですが、現代のフロントエンドマンになるには必須の技術だとおもい学ぶことにしました。

個人的な webpack の使い方をメモがてらつらつらと記載していきます。

※ この記事はあくまで個人的なメモであるため、実際の公式に記載されている情報とは違う可能性がありますのでご注意ください。

webpack を避けてきた理由

避けてきた理由は下記の一点です。

設定ファイルがよくわからん

webpack は webpack.config.js のなかに設定があります。

この中に、対象にするうJSファイルの指定やひとまとめにしたファイルの出力先、プラグインの設定等々が入ります。

はじめて webpack.config.js をみて、「敷居が高そうだ、まだ学ぶべきではない」と思い避けていました。

大規模アプリも作ることがなかったのでまだ良いかなぁと思っていました。

ぶっちゃいきなり、「webpack.config.js はこんなふうにしました」なんて書かれても意味わからんのよ。設定項目多すぎなのよ。

それでも、いまのフロントエンドには必須の技術なのでとりあえず触ってみたという経緯があります。

webpack とは

webpack は JavaScript の依存関係をなんとかしてくれるツールです。

複数に分かれている JavaScript ファイルをひとつまとめにする(バンドル)することで解決します。

また、loader や plugin を導入することによって CSS や image ファイルといった JavaScript 以外のファイルもひとまとめにすることができます。

その他にも、開発用のサーバーを起動させるプラグインを導入することによって、作っている web アプリをブラウザに表示させながら開発できます。

さらに逐一ページの更新やサーバーを停止させなくても勝手にリロードさせるので開発を加速することが可能です。

個人的にわかりやすいなと思った記事

最近のフロントエンドでのwebpackの重要性について考えてみる - Qiita
qiita.com
image

触ってみた

ゴールは JavaScript と  HTML と sass のバンドル及び 開発サーバープラグインの導入までにします。(フレームワーク使いたい等々になると webpack.config.js が複雑になるため)

準備

とりあえず作業ディレクトリ作ります。

mkdir test-webpack
cd test-webpack

yarn init で初期化

yarn init

webpack のインストール

yarn add webpack webpack-cli

local インストールの場合は node_modules/.bin に path を通す必要があります。

export PATH=$PATH:./node_modules/.bin

バンドルするファイルをつくる

webpack の設定をする前にバンドルするためのファイルをつくります。

とりあえずは html ファイル(index.html)と JavaScirpt ファイル(index.js, helloworld.js)をつくります。(CSS は一旦放置)

構成は以下のようにします。

test-webpack
  ├── node_module
    └── ・・・・
  ├── package.json
  ├── public
   └── index.html
  ├── src
  │   ├── helloworld.js
  │   └── index.js
  └── yarn.lock

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>test-webpack</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

index.js

import HelloWorld from "./helloworld"
const root = document.getElementById("root");
root.innerHTML = HelloWorld();

helloworld.js

const sayHello = () => {
  return "<h1>Hello World </h1>"
}

export default sayHello

id が root の div タグの中に h1 タグで “hello world” が表示されるようにしました。(helloworld.js に文言を返すようにしているのは JavaScript ファイルを無理やり二つ作るために作りました)

webpack を使わずに html + JavaScript を使っている人ならわかると思いますが、 index.html に index.js と helloworld.js を読ませるための script タグがありません。

理由は、今回行う方法にて、html もビルドするためです。

html をビルドするときに、読み込む script ファイルが自動で付与されるため記述する必要がないです。

webpack の設定をする

webpack の設定ファイルである webpack.config.js を作ります。

touch webpack.config.js

ファイル構成はこの以下になります。

test-webpack 
  ├── node_module
  │   └── ・・・・
  ├── package.json
  ├── public
  │   └── index.html
  ├── src
  │   ├── helloworld.js
  │   └── index.js
  ├── webpack.config.js
  └── yarn.lock

とりあえずは webpack 公式にならって webpack.config.js を作成

const path = require('path');

module.exports = {
  entry: './src/index.js',                  // 対象の親(エントリーポイント)となる js ファイル(モジュールは入れなくてよい)
  output: {                                 // ビルドした js の設定
    path: path.resolve(__dirname, 'dist'), // 出力先ディレクトリ
    filename: 'bundle.js'                   // 出力するファイル名
  },
  mode: 'development'                       // 'development','production'、'none' があるが本記事では説明割愛
}

mode については 以下を参照してください

Mode | webpack
webpack.js.org
image

とりあえずこの状態で webpack を起動してみます。

起動すると dist というディレクトリが作成され、その中に bundle.js というファイルができています。

webpack
$ tree
.
├── dist
│   └── bundle.js
├── node_module 
 └── ・・・・
├── package.json
├── public
│   └── index.html
├── src
│   ├── helloworld.js
│   └── index.js
├── webpack.config.js
└── yarn.lock

bundle.js の中には src に入っている JavaScript がひとつにまとまっているものがはいっています。JavaScirpt がビルドされてひとつにバンドルされました。

しかし、この状態では Web アプリを起動させることができません。

public/ index.html が bundle.js を呼んでいないためです。

手動で public/ index.html に <script src=”../dist/bundle.js> をやっても良いですがとてもめんどいです。

そのため、プラグインを導入して HTML をビルドするように設定します。

HTML をバンドルする

HTML もビルドするように html-webpack-plugin を導入します。

yarn add html-webpack-plugin
webpack.config.js を追記

diff --git a/webpack.config.js b/webpack.config.js
index 1952ac5..118772d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,4 +1,5 @@
 const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
 
 module.exports = {
 
@@ -7,5 +8,10 @@ module.exports = {
     path: path.resolve(__dirname, 'dist'),
     filename: 'bundle.js'
   },
- mode: 'development'
+  mode: 'development',
+  plugins: [
+    new HtmlWebpackPlugin({  // HtmlWebpackPlugin プラグインを使用
+      template: 'public/index.html'   // public/index.html を基にして html build
+    })
+  ]
 }

この状態で改めて webpack でビルドしてみます。

webpack

そうするとファイル構成は以下のように dist ディレクトリ以下に index.html が作成されます。

$ tree
.
├── dist
│   ├── bundle.js
│   └── index.html
├── node_module 
   └── ・・・・
├── package.json
├── public
│   └── index.html
├── src
│   ├── helloworld.js
│   └── index.js
├── webpack.config.js
└── yarn.lock

dist/index.html をみると、 public/index.html  に が追加されたものが入っています。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>test-webpack</title>
</head>

<body>
  <div id="root"></div>
<script src="bundle.js"></script></body>

</html>

dist/index.html を開くとでっかく hello world と出るはずです。

このように webpack は 必要な plugin や loader をインストールしていくことでいろんなものをバンドルしていきます。

次に saas をバンドルしていきます。

saas をバンドルする

はじめに読み込むスタイルシートを準備します。

src/saas/style.scss としました。

% tree
.
├── dist
│   ├── bundle.js
│   └── index.html
├── node_module 
│ └── ・・・・
├── package.json
├── public
│   └── index.html
├── src
│   ├── helloworld.js
│   ├── index.js
│   └── saas
│       └── style.scss
├── webpack.config.js
└── yarn.lock

style.scss の中身は body の中にあるテキストは全て赤色に設定

body {
  color: red;
}

src/index.js に style.scss を読み込むように手を加えます。

diff --git a/src/index.js b/src/index.js
index f8f4212..e24d4b7 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,4 +1,5 @@
import HelloWorld from "./helloworld"
+import "./saas/style.scss"

const root = document.getElementById("root");

scss をバンドルするために sass-loader 等のモジュールをインストールします。

yarn add sass-loader sass css-loader style-loader

あとは webpack.config.js に sass をバンドルできるように追記します。

diff --git a/webpack.config.js b/webpack.config.js
index 118772d..73512df 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -13,5 +13,18 @@ module.exports = {
     new HtmlWebpackPlugin({
       template: 'public/index.html'
     })
- ]
+  ],
+
+  module: {
+    rules: [
+      {
+        test: /\.s[ac]ss$/i,
+        use: [
+          'style-loader', // CSS DOM に挿入する
+          'css-loader', // CSS から CommonJS に変換
+          'sass-loader' // Sass CSS にコンパイル
+        ]
+      }
+    ]
+  }
 }

最後に webpack コマンドを起動してあげ、dist/index.html を開くと helloworld の文字が赤くなっています。

ビルド時にスタイルシートは別途出力したい場合は、MiniCssExtractPlugin を使うことで別途スタイルシートが出力されます。

本記事では MiniCssExtracPlugin の説明はしません。

開発を楽にしよう

今までは ビルドしてからブラウザを立ち上げ、正しく表示できているか確認をしていました。

今回はかなり小規模なので逐一ビルドして確認してもよいですが、大規模になると「いちいち webpack コマンド打って確認して〜」がかなりめんどくなります。

そんなめんどい作業をやらなくてもよいプラグインが webpack-dev-server です。

さっそくインストールします。

yarn add webpack-dev-server

あとはターミナルで server を立ち上げます

webpack-dev-server --open

※ open オプションをつけると自動でブラウザが立ち上がる

自動でブラウザが立ち上がり赤文字で hello world が表示されます。

webpack-dev-server と打つのがめんどい のであれば スクリプト化してしまうと簡単に呼び出せます

paclage.json に以下のように編集

diff --git a/package.json b/package.json
index d9a1d57..2c2a352 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,9 @@
   "version": "1.0.0",
   "main": "index.js",
   "license": "MIT",
+  "scripts": {
+    "start": "webpack-dev-server --open"
+  },
   "dependencies": {
     "css-loader": "^3.5.3",
     "html-webpack-plugin": "^4.3.0",

そして Terminal で yarn start と打つと 同じように自動でサーバーが立ち上がり、ソースコードを編集するたびに自動更新(ホットリロード)がかかります。

まとめ

はじめて webpack を触ってみて、つらつらと 理解したことをまとめてみました。

最初はとっつきづらいと思っていましたが、慣れてしまえば便利だし開発を加速できると考えます。

今までは、「なんか知らないけどいい感じにビルドしてくれてまとめてくれている」でしたが、少しは Web アプリのビルドの仕組みが分かったような気がします。