今日から始めるNext.js #2~webpack入門~

この記事の文字数は、8,671 文字です。
モダンなフロントエンド開発では必須のpackageとwebpack。 なぜwebpackがフロントの開発で必要になるか理解していますか? yarnによるpackageの扱い方など、基本を解説します。
目次
こんにちは、ナオツです。
前回はNext.jsをはじめるにあたり、環境構築の話をしました。
今回はモダンフロントエンド開発では必ず用いるpackageとwebpackについて解説していきます。
packageとwebpackはNext.jsに限らずNuxt.js(Vue.js)、Angularなど他のJSフレームワーク開発においても同じように用いられます。
今回はNext.jsに限らず、モダンフロントエンド開発に興味がある方や、開発で利用しているものの何となく使っていた、という方にむけて解説していきたいと思います。
packageとは
実は前回の記事では、すでにpackageをインストールしています。
このときyarnコマンド使いましたね?
最初にたくさんインストールが始まったかと思います。
あのとき、Next.jsで必要なpackage(ライブラリ・モジュール)と呼ばれるソースコードがたくさんのpackageがインストールされています。
なぜインストールしたか?というと、
どんなサービスでも、システムを実装する際にゼロから実装することは100%ありません。
ライブラリは「ある程度実装された機能のカタマリ」というイメージです。
プログラミングとは、このカタマリをうまく組み合わせ、そのつなぎ目をコーディングしていく作業に他なりません。
レゴブロックをうまく組み合わせて、組み合わせの方法や組み合わない部分だけ作るのです。
レゴブロックそのものを作ることはほとんどありません。
yarnとは
package(ライブラリ・モジュール)自体もゼロから実装されているものは少なく、別のpackageを組み合わせて作っていることがほとんどです。
これをpackageどうしの 依存関係 といいます。
AというpackageがBというpackageを用いて実装されていたとしたら、Aをインストールする際に、先にBをインストールしておかなければAは動きません。
当然BというpackageがCというpackageに依存していたら、、、なんていうことももちろんあります。
yarnは、こうした依存関係を解決してpackageをインストールできるツールなのです。
モダンフロントエンドの作り方
Webページは、基本的に「HTML・CSS・JavaScript」で構成されています。
HTMLからJavaScriptを使うには、scriptタグを使って呼び出します。
ここでたくさんpackage(ライブラリ・モジュール)をインストールしていると問題が発生することにお気づきでしょうか。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
~コンテンツ~
<script type="text/javascript" src="sample1.js"></script>
<script type="text/javascript" src="sample2.js"></script>
<script type="text/javascript" src="sample3.js"></script>
.
.
.
<script type="text/javascript" src="sample100.js"></script>
</body>
</html>
packageとはJavaScriptのソースなので、packageどうし依存関係があるとHTML上でのscriptタグの呼び出し順がシビアになってきます。
2~3個のpackageならまだ良いですが、100個もあったら大変ですよね・・・?(^^;)
さて前回インストールしたNext.jsの場合を見てみましょう。
プロジェクトのルートディレクトリに node_modules というディレクトリが出来ているはずです。
$ ll
total 192
drwxr-xr-x 7 naotsu naotsu 4096 Jun 27 10:43 ./
drwxr-xr-x 3 naotsu naotsu 4096 Aug 20 13:30 ../
-rw-r--r-- 1 naotsu naotsu 50 Jun 27 10:33 .eslintrc
-rw-r--r-- 1 naotsu naotsu 386 Jun 27 10:33 .gitignore
drwxr-xr-x 5 naotsu naotsu 4096 Jun 27 10:43 .next/
-rw-r--r-- 1 naotsu naotsu 1581 Jun 27 10:33 README.md
-rw-r--r-- 1 naotsu naotsu 46 Jun 27 10:33 next.config.js
drwxr-xr-x 366 naotsu naotsu 12288 Jun 27 10:40 node_modules/
-rw-r--r-- 1 naotsu naotsu 373 Jun 27 10:40 package.json
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 pages/
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 public/
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 styles/
-rw-r--r-- 1 naotsu naotsu 137627 Jun 27 10:40 yarn.lock
yarnでインストールしたpackageは node_modules ディレクトリ内にインストールされます。 中を覗いてみましょう。
$ ll node_modules/
total 1564
drwxr-xr-x 366 naotsu naotsu 12288 Jun 27 10:40 ./
drwxr-xr-x 7 naotsu naotsu 4096 Jun 27 10:43 ../
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 .bin/
-rw-r--r-- 1 naotsu naotsu 74578 Jun 27 10:40 .yarn-integrity
drwxr-xr-x 8 naotsu naotsu 4096 Jun 27 10:40 '@babel'/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 '@eslint'/
drwxr-xr-x 5 naotsu naotsu 4096 Jun 27 10:40 '@hapi'/
drwxr-xr-x 7 naotsu naotsu 4096 Jun 27 10:40 '@next'/
drwxr-xr-x 5 naotsu naotsu 4096 Jun 27 10:40 '@nodelib'/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 '@rushstack'/
drwxr-xr-x 4 naotsu naotsu 4096 Jun 27 10:40 '@types'/
drwxr-xr-x 7 naotsu naotsu 4096 Jun 27 10:40 '@typescript-eslint'/
drwxr-xr-x 4 naotsu naotsu 4096 Jun 27 10:40 acorn/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 acorn-jsx/
drwxr-xr-x 5 naotsu naotsu 4096 Jun 27 10:40 ajv/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 anser/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 ansi-colors/
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 ansi-regex/
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 ansi-styles/
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 anymatch/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 argparse/
drwxr-xr-x 3 naotsu naotsu 4096 Jun 27 10:40 aria-query/
.
.
.
(以下省略)
なにやらたくさん出てきましたね・・・?
下記のコマンドでnode_modules内のディレクトリの数(≒package数)をカウントできます。
実行してみましょう。
$ ls -l node_modules/ | grep ^d | wc -l
363
なんと363個のpackageがインストールされていました。
今はNext.jsのpackageのみですが、開発を進めるにあたり途中で追加のpackageをインストールすることになりますので、今後もっと増えていきます。
これ、全部HTMLにscriptタグで書く元気ありますか?
ちなみに僕はムリです。笑
そこでwebpackが役に立ちます。
webpackの恩恵
前述したとおり、packageはレゴブロックのようなものなので、自分で組み立てて足りない部分は実装しないと、自分の思い通りに動きません。
仮に1つ画面で必要なソースが、
- package A
- package B
- package C
- 自分で書いたソース
だったとします。
webpackはこれを なんと1つにまとめてくれます 。 しかも単純にまとめるだけでなく、package間の依存関係を解決した上でまとめてくれます。
これめちゃくちゃ便利なんです。
1ファイルになるので、開発者がHTMLで呼び出すときは、この出来上がったファイルだけ呼べば良いですね。
こういった機能は、package(モジュール)をまとめる(バンドルする)ので、 モジュールバンドラ と呼ばれます。
出力されたファイルそのものを バンドル と呼ぶこともあります。
またエンジニアによっては、バンドルすることを ビルドする ということもあるようです。
たくさんのファイルをインプットに、1つのファイルを組み立てる(ビルドする)、というイメージです。
用語のまとめ
ここまででいろんな用語が出てきましたので、まとめておきましょう。
- package: JavaScriptのライブラリ・モジュールのこと(他の言語だと名称が違う。ex) RubyだとGemなど)
- yarn: npmと同じく依存関係を解決しながら必要なpackage(ライブラリ・モジュール)をインストールできるツール
- webpack: 複数のpackage(ライブラリ・モジュール)をまとめることができるモジュールバンドラ
- バンドル: 複数のライブラリ・モジュールをまとめたファイル
- ビルドする: webpackによってライブラリ・モジュールをバンドルする一連の処理のこと
packageの一覧
さて、前回インストールしたNext.jsのひな形にてルートディレクトリに package.json と yarn.lock というファイルが生成されているのが確認できると思います。
$ ll package.json yarn.lock
-rw-r--r-- 1 naotsu naotsu 373 Jun 27 10:40 package.json
-rw-r--r-- 1 naotsu naotsu 137627 Jun 27 10:40 yarn.lock
package.json
package.jsonでは、このプロジェクトがなんのpackageを使っているか、一覧で確認できます。
{
"name": "naotsu-blog",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "11.0.1",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"eslint": "7.29.0",
"eslint-config-next": "11.0.1"
}
}
冒頭にはプロジェクトの名称やバージョンが記載されています。 好きに変更できます。
"name": "naotsu-blog",
"version": "0.1.0",
scripts
"scripts" という部分はプロジェクト内でCLIコマンドを登録できます。
ここに登録しておけば、yarn xxxx でコマンドを呼び出せます。
たとえば、Next.jsを起動する際に、node_modules内のnext.jsのCLIコマンドを呼ぶ必要があるのですが、
"next dev" が dev として登録されているので、yarn dev というコマンドでNext.jsを起動することができるようになるという意味です。
ちなみに本来のnextコマンドは下記にあります。
$ ll node_modules/next/dist/bin/
total 28
drwxr-xr-x 2 naotsu naotsu 4096 Jun 27 10:40 ./
drwxr-xr-x 13 naotsu naotsu 4096 Jun 27 10:40 ../
-rwxr-xr-x 1 naotsu naotsu 4874 Jun 27 10:40 next*
-rw-r--r-- 1 naotsu naotsu 80 Jun 27 10:40 next.d.ts
-rwxr-xr-x 1 naotsu naotsu 8018 Jun 27 10:40 next.map*
また、"scripts"に登録されているその他のコマンドについては、今後の記事で紹介していきます。
dependenciesとdevDependencies
dependenciesとdevDependencies という部分がインストールされているpackageですね。 ざっくり、
- dependencies: 開発時と本番環境で必要なpackage
- devDependencies: 開発時にのみ必要なpackage
といった理解で良いかと思います。
packageを追加すると、ここにどんどん追記されていきます。
また、
"next": "11.0.1"
これはnextというpackageが、バージョン11.0.1でインストールされている状態という意味です。
前述した通りpackageは世界の誰かが作ったプログラムなので、脆弱性やバグが含まれている可能性は否めません。
その場合は開発者の発信を確認して、バージョンアップする必要があります。
発信の確認方法やバージョンアップ方法、またpackageの追加方法については、今後の記事で紹介していきます。
yarn.lock
このファイルは基本的に開発者が直接編集することはありません。
このファイルにはyarn installした際にインストールしたpackageの依存情報が事細かに記載されています。
ちなみに間違えて削除してしまったとしても、再度yarn installすれば復活します。
もし間違えて編集して、挙動がおかしくなったらnode_modulesと合わせて削除→再作成するのをオススメします。
$ cat yarn.lock
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/code-frame@7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/helper-validator-identifier@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
.
.
.
(以下省略)
まとめ
いかがだったでしょうか?
Next.jsで開発するには、webpackを用いて複数のライブラリを効率的に利用することが求められます。
正直言ってNext.jsが何のライブラリに依存しているか、完全に理解して開発している方は少ないかと思います。
ただ、「こういう仕組みで動いている」というバックグラウンドを知っておくことで、開発中に問題が起きたときに解決への糸口が広がります。
webpackへの理解はこれくらいで開発は進められるので、次回はエディターを使って実装に少し触れてみましょう。