前から気になっていたwebpackをUdemyを使って勉強してみました。
業務で使っていて曖昧だったところが、結構クリアになった気がしますので、備忘録がてら書き残しておきたいと思います。
javascript開発を行なってるなら耳には入れておきたい、webpack!
使用したUdemyコース
日本語のコースもあったのですが、こちらのコースは評価がよかったので、英語のコースを受けてみました。
少しアクセントのある英語なので、リスニングが苦手な方はちょっと難しいかもしれません。
簡単なjavascriptのwebアプリを開発する過程で、webpackを使っていきます。
簡単なアプリなので、自分の手元でも実際に動かして、理解することができました!
webpackとは?
javascript用のバンドルツールです。バンドルとは束ねるものという意味があります。
アプリを作る場合、たくさんのファイルが必要になりますよね?プログラムの入ったファイルや画像、スタイルなどなど。
これらをぎゅっとまとめたものをバンドルといいます。
で、webpackはこのバンドル化を効率良く実行してくれる神のような道具なのです。
利点は?
依存の解決
実際にアプリを書いていると、ファイルAはファイルBを使用しているからこの順番で書かなくてはいけない、といった経験はありませんか?
このような依存のせいで、コードが書きづらくなったり複雑化してしまうことがあります。
これらの依存をwebpackならば解決してくれます。どうやら、webpack内部でこれらの依存関係のグラフを生成することができ、
アプリ開発者はファイル同士の依存については気にしなくてよくなるそうです。
ロード時間の改善
例えば、ウェブではユーザがサイトに訪れるたびにサーバにページ情報を取りに行くのでは、時間もかかるし無駄なので、
キャッシュという技術を使って、瞬時にウェブが表示できるようになっています。
とはいっても、サイト側に更新内容がある場合は、サーバに情報を取りにいかなくてはいけません。
もしこれが膨大な量であると、その分ロードする時間がかかります。
しかし、webpackを使えば、バンドルを小分けにすることで、修正のあったバンドルだけをサーバに取りに行けばよいだけなので、
大幅なロード時間短縮につながります。
Module Federationの機能を使いたい場合
ここから新しい横文字がいろいろと出てくるのですが、一から説明します。
Module Federationとは、Micro Frontendなアプリを開発する場合に使用します。
https://webpack.js.org/concepts/module-federation/
では、Micro Frontendとは何か?
Micro Frontendとは、アプリをヘッダやボディなどに細分化して開発することをいいます。
https://micro-frontends.org/
なので、全ての機能をまるごと1つのモジュールに詰め込むのではなく、ヘッダはヘッダモジュール、ボディはボディモジュールというように、
Micro(細かい)な部位ごとにわけて、Micro Frontendなアプリは作られます。
では、Module Federationの定義に戻ります。先ほど述べたものに追記します。
Module Federationとは、Micro Frontendなアプリを開発する場合に使用します。
各モジュールをダイナミックにロード・ビルドして開発をすることが可能となります。
https://webpack.js.org/concepts/module-federation/
Micro Frontendでないアプリであれば、ヘッダだけを修正したくてもそのアプリに関係するすべてのモジュールをロード・ビルドしなくてはいけません。
しかし、Micro FrontendなアプリでかつModule Federationを利用するアプリであれば、ヘッダチームだけがビルド、ロードすることで開発を可能とします。
このように、モジュールを細分化する開発が可能となることで、柔軟にアプリ開発ができるようになります。
どういった時に使う?
アプリをバンドルにする必要がある場合や、上記の利点を享受したい場合に、使用するのがいいのですかね。
あとは、Module Federationを使いたい場合でしょうか。
1つのアプリに大人数のチームがそれぞれContributeしているときは、Module Federationを導入することで、少人数のチームでそれぞれ仕事を進めることができますよね。
webpack.config.jsの書き方
ではwebpackを使うとなると、どういうふうにバンドル化するか細かい条件を設定することが可能です。
それを実現するのに、webpack.config.js
ファイルを使います。設定ファイルですね。
Udemyのコースで使用したwebpack.config.js
を参考例として載せておきたいと思います。
const path = require("path"); // パスをabsoluteパスに変換してくれる
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // outputファイル内をクリーンしてくれる
const HtmlWebpackPlugin = require("html-webpack-plugin"); // html用にindex.htmlを最適化
// bundleを二つに分ける理由:パラレルにロードすれば時間短縮になる
module.exports = {
entry: {
"hello-world": "./src/hello-world.js",
"cat": "./src/cat.js"
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "./dist"),
publicPath: "", // 画像などのパスを指定可能
},
mode: "development", // production or developmentが選べる。 後者はバンドル大きめ、デバッグしやすい
devServer: { // devserverを立てることで、dynamicにコード編集などができる
port: 9000,
static: {
directory: path.resolve(__dirname, "./dist"),
},
devMiddleware: {
index: "index.html",
writeToDisk: true
}
},
module: { // 画像などのassets用
rules: [
{
test: /\.(png|jpg)$/,
// type: "asset/inline", // base64に変更して、bundleにinjectする。その分バンドルファイルは大きくなる。HTTP requestを行うよりマシな場合がある。小さい画像に適している
// type: "asset/resource", // http requestを都度行う . 大きい画像に適している
type: "asset", // 8kb以下:inline, 以上:resource
parser: { // type: assetを指定したときのサイズ条件を指定できる。
dataUrlCondition: {
maxSize: 3 * 1024 // 3 kb
}
}
},
{
test: /\.txt/,
type: "asset/source", // js としてimportできるようにする, textファイルとかが多いっぽい
},
{
test: /\.css/,
use: [
"style-loader", "css-loader" // explicitily import する必要あり
]
},
{
test: /\.scss/,
use: [
"style-loader", "css-loader", "sass-loader" // explicitily installする必要あり。右から左に見ていく。
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader", // jsを古いjsに変換して、browserとかで使えるようにしてくれる
options: {
presets: ["@babel/env"],
plugins: ["@babel/plugin-proposal-class-properties"]
}
}
}
]
},
plugins: [ // webpackに便利なライブラリを入れることができる
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: "hello-world.html",
chunks: ["hello-world"],
title: "hello world",
description: "hello world description",
template: "src/page-template.hbs",
}),
new HtmlWebpackPlugin({
filename: "cat.html",
chunks: ["cat"],
title: "cat",
description: "cat description",
template: "src/page-template.hbs",
}),
]
};
こんな感じに書いていきます。モジュール化したオブジェクトにいろんなパラメタをセットしていきます。
webpackにはpluginも豊富にあるので、自由度が増しますね。
では、ここで使っているパラメータを紹介します。
entry
アプリのエントリーポイントを指定します。
例のように2つに分けることができ、パラレルにロードすることも可能です。
このようにすることで、アプリのロード時間を早めることができますね。
output
バンドルファイルの出力形式を設定できます。
出力ファイルに[name]
を使うことで、entry
で使用しているname
パラメタをセットしてくれます。
mode
production
とdevelopment
モードの指定ができます。
上記ではdevelopment
モードを使用しており、devserver
の起動などができるようになります。
devserver
devserver
を起動することができます。開発を行う時にダイナミックに修正が確認できるため、あるととても便利です。
module
module
をどう扱うかを定義することができます。
その中でもrules
プロパティで各ファイルの設定を書くことができます。
今回のコースでは主に画像やフォントなどのアセット系が多く出てきたので、そういうものをロードする際に設定できる項目なのかなと思います。
最後にでてきているbabel
は、ブラウザで表示できないバージョンのjsファイルがあった場合は、表示できるバージョンに変換してくれるといった機能があるようです。
plugins
これは拡張機能ですね。いろんなpluginが世の中に存在するので、それらを好きにnewして追加していくことができるようです。
まとめ
webpackについて学びました。
今まで開発は、アプリ自体のコードが一番大事だと思ってたんですが、ロードする部分だったりビルドをする部分も考えなくてはいけないんですね。
特に大きなアプリでは、Module Federationの開発方法を取ることで、チーム全体の開発効率を上げることができるんですよね。深い。
javascript開発を行なっている方は、webpackについての知識を持ってるとよいのかもしれません。
にほんブログ村に参加しております!よろしければクリックお願いします 🙂
にほんブログ村
コメント