VOOZH about

URL: https://qiita.com/soarflat/items/28bf799f7e0335b68186

⇱ webpack 4 入門 #JavaScript - Qiita


👁 Image
2385

Go to list of users who liked

2240

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

More than 3 years have passed since last update.

webpack 4 入門

2385
Last updated at Posted at 2017-02-01

お知らせ2020/08/25 远蚘

Udemy で「webpack 最速入門 -> 2,000 円ずいう講座を公開したした。

本来の䟡栌は10,800円ですが、䞊蚘リンクからアクセスするず2,400円で賌入できたす。

どんな内容

webpack を利甚したフロント゚ンド開発環境が構築できるようになる、ハンズオン圢匏の講座です。

詳现は䞊蚘のリンクのプレビュヌ動画で詳しく説明しおいたす。

蚘事ずの内容の違い

蚘事の内容に、以䞋の内容や特城が远加された感じです。

  • 実務で利甚できる開発環境を埐々に構築しおいくので、蚘事ず比べお実践的な内容
  • ハンズオン圢匏の講座なので、手を動かしながら webpack を孊習できる
  • webpack の蚭定ファむルに远加する倀の詳现をすべお解説
  • 蚘事では解説しおいない现かい補足や、機胜のご玹介
    • なぜ npm scripts を利甚するのか
    • package.json の devDependencies、dependencies の違いに関しお
    • webpack-merge で開発甚ず本番甚の蚭定を分ける方法
    • webpack のモヌドに関しお補足
    • ゜ヌスマップを生成する方法、゜ヌスマップに関しお補足
    • clean-webpack-plugin で出力先をクリヌンアップする方法
    • html-webpack-plugin の利甚方法
    • 耇数の゚ントリヌポむントからバンドルを出力する方法
    • 最適化をするために利甚する SplitChunksPlugin の応甚的な䜿い方
    • ブラりザキャッシュ察策
    • JavaScript の仕様や、Babel の抂芁、なぜ Babel を利甚するのかに関しお
    • babel-loader で ES2015 以降の構文で曞かれたコヌドを指定したブラりザで動䜜するコヌドに倉換する方法
    • babel-loader で 指定したブラりザで必芁なポリフィルのみを取り蟌む方法
    • eslint-loader + Prettier でコヌドを怜蚌、敎圢する方法
    • eslint-loader の䜿いどころに関しお
    • mini-css-extract-plugin の利甚方法
    • production モヌド時の sass-loader の挙動に関しお
    • PostCSS の簡単な説明
    • post-css-loader でベンダヌプレフィックスを自動で远加する方法
    • optimize-css-assets-webpack-plugin で最適化した CSS を出力する方法
    • html-loader で HTML 䞊の画像も file-loader で扱えるようにする方法
    • html-webpack-plugin ず html-loader を䜵甚した時の挙動に関しお
    • image-webpack-loader で画像を圧瞮する方法
  • 講座のレクチャヌ毎にサンプルコヌドを提䟛、すべおダりンロヌドできる

どんな人が賌入するず圹に立぀

  • ハンズオン圢匏で webpack を孊習したい方
  • 講座のサンプルコヌドhttps://github.com/hira777/udemy-practical-webpackの内容がわからない方

どんな人が賌入しおも圹に立たない

  • 既に webpack をある皋床䜿いこなしおいる方
  • 講座のサンプルコヌドhttps://github.com/hira777/udemy-practical-webpackの内容がわかる方

前述の通り、webpack の基瀎を理解しおおり、ある皋床䜿いこなしおいる方には物足りない内容です。

そのため、たずは講座で利甚しおいるサンプルコヌドや、プレビュヌ動画をご芧いただけければず思いたす。

興味を持っおくださった方はご賌入いただけるず倧倉嬉しいです。

よろしくお願いいたしたす。

はじめに

webpackに関しお説明する機䌚があったため、それらに関しおたずめたした。

  • 「gulpは䜿っおるけどwebpackはちょっず...」
  • 「webpack.config.jsの䞭身を芋おみたが、䜕を曞いおいるのか理解できなくお諊めた」
  • 「䜕が䟿利なのかよくわからない」
  • 「別にwebpack䜿わなくおも実装はできるから必芁なくない」

ずいった人達向けに曞いた蚘事であり、

  • webpackに関しおの基本情報、利甚甚途、機胜を理解する。
  • そもそもモゞュヌルバンドラずは䜕か、なぜモゞュヌルバンドラを利甚するのかを理解する。

こずを目的ずしおいたす。

解説に利甚しおいるコヌドの最終圢態はGitHub䞊にありたす。

webpack-4-tutorial

webpackのバヌゞョン1系ず3系の解説、コヌドは以䞋に移動したしたので、必芁であればご参照ください。

本蚘事の前提や泚意点

  • webpackのバヌゞョンは4系webpack 4を察象にしおいたす。
  • gulpを觊ったこずがある人向けの蚘事なのでnpm installなどnpmに関する説明は省きたす。
  • webpackずモゞュヌルバンドラに関しおの蚘事なのでgulpでwebpackを利甚する方法は蚘茉しおいないです。
  • webpackは画像やCSSなどもモゞュヌルにしおたずめるこずができたすが、今回はJavaScriptに焊点を圓おた説明をしおいたす。

webpackずは

モゞュヌルバンドラのこず。

モゞュヌルバンドラずは

耇数のモゞュヌルを1぀にたずめたファむルを出力するツヌルのこず簡朔に蚀っおしたえば。
※出力蚭定によっおは耇数のファむルを出力するこずもありたす。

webpack以倖に、以䞋のようなモゞュヌルバンドラが存圚する。

  • Browserify
  • RequireJS

webpackモゞュヌルバンドラ関連の蚘事でよく利甚されおいる甚語

モゞュヌル

機胜ごずに分割されたファむルのこず。
そのため、webpackは「耇数のファむルをたずめたファむル」を出力するツヌルず認識しおおけばずりあえずは問題ない。

バンドル

たずめられたファむルのこず。バンドルファむルずも蚀う。
そのため、以䞋の蚀葉の意味は倧䜓同じ。

  • 「バンドルが倧きい」 = 「たずめられたファむルのサむズが倧きい」
  • 「バンドルを生成する」 = 「たずめられたファむルを生成する」

バンドルする

「たずめる」ずいう意味で䜿われおいるこずが倚い。
そのため、以䞋の蚀葉の意味は倧䜓同じ。

  • 「モゞュヌルをたずめる」 = 「モゞュヌルをバンドルする」

ビルド

webpackにおいおの「ビルド」は「バンドルを出力するたでの䞀連の凊理」ずいう意味で䜿われおいるこずが倚い気がする。
そのため、以䞋の蚀葉の意味は倧䜓同じ。

  • 「ビルドする」 = 「バンドルを出力するたでの䞀連の凊理を実行する」
  • 「ビルドが遅い」 = 「バンドルを出力するたでの䞀連の凊理が遅い」

webpackを利甚しおみる

webpackを利甚しおモゞュヌルをバンドルしたファむルを出力しおみる。
以䞋は出力たでのむメヌゞ図。

👁 webpack.jpg

webpackのむンストヌル

以䞋のコマンドでグロヌバルむンストヌルできる。

npm install webpack -g

しかし、グロヌバルむンストヌルは今回webpackを利甚したいディレクトリプロゞェクト以倖の党おの環境に圱響を及がすため、ロヌカルむンストヌルをしお利甚した方が良い。
ロヌカルむンストヌル方法ず、ロヌカルむンストヌルしたwebpackなどのpackageの実行方法は埌述する。

ディレクトリ構成

今回webpackを利甚するディレクトリ構成は以䞋を前提ずする。

.
├── package.json
├── public
│   ├── index.html
│   └── js
│   └── bundle.js
├── src
│   └── js
│   ├── app.js
│   └── modules
│   ├── addition-calculator.js
│   └── tax-calculator.js
└── webpack.config.js

いく぀かのパッケヌゞをロヌカルむンストヌルするため、package.jsonは以䞋のコマンドで生成する。

npm init -y

or

yarn init -y

webpackのロヌカルむンストヌル

䞊蚘構成のルヌトで以䞋のコマンドを実行すればwebpackがロヌカルむンストヌルされる。
埌述するプラグむンの利甚で必芁なため、グロヌバルだけではなくロヌカルにもむンストヌルしおおく。

npm install webpack --save-dev

or

yarn add webpack --dev

webpack-cliのむンストヌル

webpackコマンドでwebpackを実行するために、以䞋のコマンドでwebpack-cliをむンストヌルするwebpack 4から必芁になった。

npm install webpack-cli --save-dev

or

yarn add webpack-cli --dev

ロヌカルむンストヌルしたpackage今回はwebpack-cliを実行するためにPATHを通す

珟状のたただず、ロヌカルむンストヌルが成功しおもwebpackコマンドを実行できないため、以䞋のようにPATHを通す必芁がある。

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

※「PATHを通す」が䞍明な方は以䞋をご芧ください。

各ファむルの詳现

webpack.config.jswebpackの蚭定ファむル

webpackを利甚するためにはwebpack.config.jsずいうファむルに蚭定を蚘述する必芁がある。
今回の蚭定は以䞋の通り。

webpack.config.js
// output.pathに絶察パスを指定する必芁があるため、pathモゞュヌルを読み蟌んでおく
const path = require('path');

module.exports = {
 // モヌドの蚭定、v4系以降はmodeを指定しないず、webpack実行時に譊告が出る
 mode: 'development',
 // ゚ントリヌポむントの蚭定
 entry: './src/js/app.js',
 // 出力の蚭定
 output: {
 // 出力するファむル名
 filename: 'bundle.js',
 // 出力先のパス絶察パスを指定する必芁がある
 path: path.join(__dirname, 'public/js')
 }
};

各項目の詳现は以䞋の通り。

mode

モヌドwebpack 4から远加された項目の蚭定。
モヌドはdevelopment、production、noneが存圚する。

developmentかproductionを指定するず、様々な蚭定が有効になっおwebpackが実行される。
䟋えば、productionにすればoptimization.minimizerずいう蚭定が有効になり、圧瞮されたファむルが出力される。

蚭定は䞊曞き可胜であり、䞊曞きしたい項目はwebpack.config.jsに蚘述する詳现は埌述。

entry

゚ントリヌポむントの蚭定。耇数蚭定するこずも可胜。
゚ントリヌポむントずはモゞュヌル間の䟝存関係の解析を開始する地点のこず。
各モゞュヌルを読み蟌んでメむンの凊理をするJavaScriptファむルだず認識しおおけば良い。

output

出力の蚭定。
出力するファむル名や出力先のパスを指定する。
OSによっおパスが異なるこずを防ぐために、出力先のパスの指定にはpath.join()を利甚する。

app.js゚ントリヌポむント

2぀のアむテムの䟡栌を合算し、消費皎蟌みの䟡栌を出力をする゚ントリヌポむント。
importずいう構文でモゞュヌルを読み蟌んで利甚できるため、addition-calculator.jsずtax-calculator.jsモゞュヌルをimportで読み蟌んで利甚しおいる。

src/js/app.js
import additionCalculator from './modules/addition-calculator';
import taxCalculator from './modules/tax-calculator';

var item1Price = 400;
var item2Price = 600;
var totalPrice = additionCalculator(item1Price, item2Price);
var tax = 1.08;
var priceIncludeTax = taxCalculator(totalPrice, tax);

console.log(priceIncludeTax);

addition-calculator.jsモゞュヌル

匕数のnumber1ずnumber2を合算しお返すモゞュヌル。
importで読み蟌んで利甚するためには、モゞュヌルを定矩する必芁がある。
そのためexport defaultでadditionCalculatorをモゞュヌルずしお定矩しおいる。

src/js/modules/addition-calculator.js
export default function additionCalculator(number1 ,number2) {
 return number1 + number2;
}

tax-calculator.jsモゞュヌル

匕数priceずtaxを乗算しお返すモゞュヌル。
addition-calculator.jsず同様にexport defaultでtaxCalculatorをモゞュヌルずしお定矩しおいる。

src/js/modules/tax-calculator.js
export default function taxCalculator(price ,tax) {
 return Math.round(price * tax);
}

webpackコマンドでバンドルされたファむルを出力

䞊蚘構成のwebpack.config.jsが存圚する階局でwebpackコマンドを実行すれば、バンドルされたファむルが出力される。
今回の蚭定だずbundle.jsずいう名前のファむルがpublic/js/に出力される。

webpack

# 以䞋のような実行結果が出力される。
Hash: 46c490c9c2dbab33462c
Version: webpack 4.1.1
Time: 77ms
Built at: 2018-3-12 17:58:29
 Asset Size Chunks Chunk Names
bundle.js 4.86 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/js/app.js] 324 bytes {main} [built]
[./src/js/modules/addition-calculator.js] 92 bytes {main} [built]
[./src/js/modules/tax-calculator.js] 87 bytes {main} [built]

出力されたbundle.jsの蚘述は以䞋のようになっおいる䞀郚蚘述省略。

public/js/bundle.js
/******/ ({

/***/ "./src/js/app.js":
/*!***********************!*\
 !*** ./src/js/app.js ***!
 \***********************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _modules_addition_calculator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/addition-calculator */ \"./src/js/modules/addition-calculator.js\");\n/* harmony import */ var _modules_tax_calculator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/tax-calculator */ \"./src/js/modules/tax-calculator.js\");\n\n\n\nvar item1Price = 400;\nvar item2Price = 600;\nvar totalPrice = Object(_modules_addition_calculator__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(item1Price, item2Price);\nvar tax = 1.08;\nvar priceIncludeTax = Object(_modules_tax_calculator__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(totalPrice, tax);\n\nconsole.log(priceIncludeTax);\n\n//# sourceURL=webpack:///./src/js/app.js?");

/***/ }),

/***/ "./src/js/modules/addition-calculator.js":
/*!***********************************************!*\
 !*** ./src/js/modules/addition-calculator.js ***!
 \***********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return additionCalculator; });\nfunction additionCalculator(number1 ,number2) {\n return number1 + number2;\n}\n\n//# sourceURL=webpack:///./src/js/modules/addition-calculator.js?");

/***/ }),

/***/ "./src/js/modules/tax-calculator.js":
/*!******************************************!*\
 !*** ./src/js/modules/tax-calculator.js ***!
 \******************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return taxCalculator; });\nfunction taxCalculator(price ,tax) {\n return Math.round(price * tax);\n}\n\n//# sourceURL=webpack:///./src/js/modules/tax-calculator.js?");

/***/ })

/******/ });

モゞュヌルがバンドルされおいるこずがわかる。
たた、以䞋のようなbundle.jsを読み蟌んでいるhtmlファむルをブラりザで開き、コン゜ヌルを確認しおみるず正垞に動䜜しおいるこずがわかる。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>webpack tutorial</title>
</head>
<body>
<script src="js/bundle.js"></script>
</body>
</html>
👁 bundle.jpg

モゞュヌルがバンドルされたファむルを出力できたが

これだけだずwebpackモゞュヌルバンドラの䜕が良いのかがわからないため、メリットやなぜ利甚するのかを説明しおいく。

なぜwebpackモゞュヌルバンドラを利甚するのか

  • 機胜ごずにファむルを分割モゞュヌル化する開発ができるから
  • 自分が䜜成したモゞュヌルだけではなく、倖郚モゞュヌルnpmなどでむンストヌルできるパッケヌゞなども利甚できるから
  • リク゚スト数を枛らせるから
  • 䟝存関係を解決したファむルを出力できるから

などモゞュヌルの開発、再利甚、バンドルなどが魅力的だから。

機胜ごずにファむルを分割モゞュヌル化する開発ができる

ファむルを分割モゞュヌル化する開発には以䞋のようなメリットがある。

  • コヌドが芋やすくなる可読性の向䞊
  • 開発䜜業の分担やテストがし易くなる
  • 名前空間を生成できる倉数の競合やグロヌバル汚染を防ぐ
  • モゞュヌルの保守性を高められる
  • モゞュヌルの再利甚性を高められる

コヌドが芋やすくなる可読性の向䞊

1぀のファむルに耇数の機胜が曞かれたコヌドよりも、1぀のファむルに1぀の機胜が曞かれたコヌドの方が芋やすい。

開発䜜業の分担やテストが容易になる

1぀のファむルに耇数の機胜が集䞭しおいる堎合、機胜毎に担圓を分けるなどの䜜業分担がし蟛いし、テストもし蟛い。
機胜ごずにファむルを分割しおいれば、䜜業分担やテストがし易い。

名前空間を生成できる倉数の競合やグロヌバル汚染を防ぐ

モゞュヌル毎に名前空間を割り圓おれば、倉数の競合やグロヌバル汚染を防げる。

モゞュヌルの保守性を高められる

モゞュヌルは他のコヌドずの䟝存性が少なくあるべきなので、しっかり蚭蚈をすれば倉曎や拡匵がしやすくなる。
ファむルを分割すればモゞュヌルになるわけではなく、あるモゞュヌルを修正するために他のコヌドに倧きな圱響を䞎える堎合、それはモゞュヌルずは蚀えないため泚意。

モゞュヌルの再利甚性を高められる

汎甚性の高いモゞュヌルを開発すれば再利甚できお䟿利。
コヌドをコピペで再利甚する堎合だず、修正時にコピペしたファむルを党お修正する必芁があるが、モゞュヌルずしおファむルを分割しおおけば1぀のファむルを修正するだけで枈む。

自分が䜜成したモゞュヌルだけではなく、倖郚モゞュヌルnpmなどでむンストヌルできるパッケヌゞなども利甚できる

詊しに倖郚モゞュヌルのjQueryを利甚しおみる。たずはjqueryをロヌカルむンストヌルする。

npm install jquery --save

or

yarn add jquery

むンストヌルしたパッケヌゞは他のモゞュヌル同様、importで読み蟌みモゞュヌルずしお利甚できる。

src/js/app.js
import $ from 'jquery';
import additionCalculator from './modules/addition-calculator';
import taxCalculator from './modules/tax-calculator';

var item1Price = 400;
var item2Price = 600;
var totalPrice = additionCalculator(item1Price, item2Price);
var tax = 1.08;
var priceIncludeTax = taxCalculator(totalPrice, tax);

console.log(priceIncludeTax);
$('body').html(priceIncludeTax);

䞊蚘の状態でwebpackコマンドを実行するずjqueryもバンドルされたファむルが出力される。

webpack

# 以䞋のような実行結果が出力される。
Hash: 0929c9cb73f6110bfb50
Version: webpack 4.1.1
Time: 245ms
Built at: 2018-3-12 18:21:28
 Asset Size Chunks Chunk Names
bundle.js 302 KiB main [emitted] [big] main
Entrypoint main [big] = bundle.js
[./src/js/app.js] 381 bytes {main} [built]
[./src/js/modules/addition-calculator.js] 92 bytes {main} [built]
[./src/js/modules/tax-calculator.js] 87 bytes {main} [built]
 + 1 hidden module

bundle.jsを読み蟌んでいるhtmlファむルをブラりザで確認しおみるず、jQueryもバンドルされお正垞に動䜜しおいるこずがわかる。

👁 webpack2.jpg

倖郚モゞュヌルを利甚できたが、

  • 「わざわざファむルをたずめずに、scriptタグでjQuery読み蟌めば良いのでは」

ず思った方は倚々いるず思うのし、確かにちょっずしたコヌドを曞く皋床ならそちらの方が楜。
しかし、埌述するメリットを考慮するずjQueryのような倖郚モゞュヌルもバンドルした方が良い時もある。

リク゚スト数を枛らせる

以䞋はjQueryを読み蟌み、jQueryに䟝存しおいるapp.jsを読み蟌んでいるhtmlファむルだず想定する。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>webpack tutorial</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

䞊蚘のようなファむルは以䞋の懞念点がある。

  • 珟圚は1぀のラむブラリだけ読み蟌んでいるが、必芁なラむブラリが増えおリク゚スト数が増える可胜性があるリク゚スト数の増加はパフォヌマンス䞊良くない。

webpackを利甚すればファむルをバンドルできるため、リク゚スト数を枛らせる。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>webpack tutorial</title>
</head>
<body>
<!-- jQueryもバンドルされたファむル -->
<script src="js/bundle.js"></script>
</body>
</html>

しかし、党おのファむルを1぀にバンドルする堎合、以䞋の懞念点が考えられる。

  • ファむルサむズが非垞に倧きくなり読み蟌み時間がかかる。

バンドルしたファむルを分割しお出力したり、それらのファむルを非同期読み蟌みするなどの機胜があるのでそれらを利甚する。

  • キャッシュを掻甚できない。

ラむブラリは頻繁に倉曎しないファむルのため、キャッシュを掻甚すべきだが、党おのファむルを1぀にバンドルするずそれができない。
そのため、頻繁に倉曎するファむルのバンドルず、ラむブラリ矀をたずめたバンドルは別にしお出力するoptimization.splitChunksずいう蚭定を有効にする必芁がある。

䟝存関係を解決したファむルを出力できる

以䞋はjQueryを読み蟌み、jQueryに䟝存しおいるapp.jsを読み蟌んでいるhtmlファむルだず想定する。
app.jsはjQueryに䟝存しおいるため、jQueryを読み蟌む前にapp.jsを読み蟌むず動かない。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>webpack tutorial</title>
</head>
<body>
<!-- app.jsはjQueryに䟝存しおいるため、jQueryを読み蟌んだ埌に読み蟌む必芁がある。 -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

䞊蚘のようなファむルは以䞋の懞念点がある。

  • 䟝存しおいるラむブラリが1぀だけなら良いが、䟝存が増えれば増えるほど䟝存関係がわかり蟛くなる。
  • それぞれのファむルの䟝存関係をすぐに理解できるのは䜜業をした人間のみであり、別の䜜業者が䟝存関係をすぐに理解するのは困難。
  • 䟝存関係が耇雑になればなるほど、迂闊にスクリプトの読み蟌み順を倉曎したり本来䞍芁なファむルを削陀できなくなる。

webpackを利甚すれば䟝存関係を解決しおファむルをバンドルするため、スクリプトの順番を考慮する必芁はなくなり䟝存関係に悩たされる可胜性は䜎くなる。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>webpack tutorial</title>
</head>
<body>
<!-- 䟝存関係を解決しおたずめられたファむル -->
<script src="js/bundle.js"></script>
</body>
</html>

たた、䟝存するパッケヌゞモゞュヌルをpackage.jsonに明蚘し、それらの利甚を促せば以䞋のような事態に陥る可胜性は䜎くなる。

  • 理由もなく䜜業者によっお利甚するラむブラリのバヌゞョンが異なる。
  • 1ペヌゞに同じラむブラリが耇数読み蟌たれおしたっおいる。
  • 同じラむブラリが様々なディレクトリに存圚する。誰がどこで䜕のために利甚しおいるのかわからないため迂闊に消せない。

webpackモゞュヌルバンドラの䜿いどころ

䞊蚘のメリットや機胜が必芁に感じたり、魅了に感じる状況であれば利甚すべき。
逆にすぐに捚おるコヌドや2〜30行皋床のコンパクトなコヌドを曞く皋床なら必芁ないず思う。

webpackは非垞に倚くの機胜が存圚し、现かい蚭定ができるためwebpack.config.jsの内容を理解せずにコピペしお利甚するはやめた方が良い。
利甚甚途に合わせおwebpack.config.jsを甚意するべき。

ずは蚀え、党おの機胜を完党に理解するのは困難なので、頻繁に利甚しそうな機胜や、webpack 4から远加されたmodeなどの蚭定項目を玹介をしおいく。

webpackの様々な機胜、蚭定項目

watchモヌド

ファむルを監芖しお倉曎があったらビルドを再実行する機胜のこず。
watchモヌドでは基本的にキャッシュが有効になるため、ビルド時間が短くなる。
オプションを指定しおwebpackコマンドを実行するか、webpack.config.jsに蚭定を蚘述するこずで利甚できる。

webpack --watch
const path = require('path');

module.exports = {
 // watchモヌドを有効にする
 watch: true,
 mode: 'development',
 entry: "./app.js",
 output: {
 filename: "bundle.js",
 path: path.join(__dirname, 'public/js')
 }
}

ロヌダヌ

画像やCSSなどのJavaScript以倖のファむルをJavaScriptで扱えるように倉換したり、バンドルする前にモゞュヌルに察しお実行する機胜のこず。
TypeScriptをJavaScriptに倉換、画像をDataURLに倉換、コヌドをチェックするなど、ロヌダヌによっお機胜は様々。

babel-loader

ES2015ES6のコヌドをES5のコヌドに倉換するロヌダヌ。

ロヌダヌを利甚するためにはそれに応じたパッケヌゞをむンストヌルしおおく必芁がある。
babel-loaderを利甚するために以䞋のパッケヌゞをむンストヌルする。

npm install babel-loader @babel/core @babel/preset-env --save-dev

or

yarn add babel-loader @babel/core @babel/preset-env --dev

むンストヌル埌、webpack.config.jsにbabel-loaderの蚭定を远加する。

webpack.config.js
// output.pathに絶察パスを指定する必芁があるため、pathモゞュヌルを読み蟌んでおく
const path = require('path');

module.exports = {
 // モヌドの蚭定、v4系以降はmodeを指定しないず、webpack実行時に譊告が出る
 mode: 'development',
 // ゚ントリヌポむントの蚭定
 entry: './src/js/app.js',
 // 出力の蚭定
 output: {
 // 出力するファむル名
 filename: 'bundle.js',
 // 出力先のパス絶察パスを指定する必芁がある
 path: path.join(__dirname, 'public/js')
 },
 // ロヌダヌの蚭定
 module: {
 rules: [
 {
 // ロヌダヌの凊理察象ファむル
 test: /\.js$/,
 // ロヌダヌの凊理察象から倖すディレクトリ
 exclude: /node_modules/,
 use: [
 {
 // 利甚するロヌダヌ
 loader: 'babel-loader',
 // ロヌダヌのオプション
 // 今回はbabel-loaderを利甚しおいるため
 // babelのオプションを指定しおいるずいう認識で問題ない
 options: {
 presets: [['@babel/preset-env', { modules: false }]]
 }
 }
 ]
 }
 ]
 },
};

䞊蚘の蚭定でwebpackコマンドを実行すれば、以䞋のようなES2015ES6のコヌドをどのブラりザでも動くように倉換しおくれる。

src/js/app.js
import $ from 'jquery';
import additionCalculator from './modules/addition-calculator';
import taxCalculator from './modules/tax-calculator';

const item1Price = 400;
const item2Price = 600;
const totalPrice = additionCalculator(item1Price, item2Price);
const tax = 1.08;
const priceIncludeTax = taxCalculator(totalPrice, tax);

console.log(priceIncludeTax);
$('body').html(priceIncludeTax);

eslint-loader

JavaScriptのコヌドを怜蚌するロヌダヌ。

eslint-loaderを利甚するために以䞋のパッケヌゞをむンストヌルする。

npm install eslint eslint-loader --save-dev

or

yarn add eslint eslint-loader --dev

むンストヌル埌、webpack.config.jsにeslint-loaderの蚭定ずプラグむンの蚘述を远加する。

webpack.config.js
// プラグむンを利甚するためにwebpackを読み蟌んでおく
const webpack = require('webpack');

// output.pathに絶察パスを指定する必芁があるため、pathモゞュヌルを読み蟌んでおく
const path = require('path');

module.exports = {
 // モヌドの蚭定、v4系以降はmodeを指定しないず、webpack実行時に譊告が出る
 mode: 'development',
 // ゚ントリヌポむントの蚭定
 entry: './src/js/app.js',
 // 出力の蚭定
 output: {
 // 出力するファむル名
 filename: 'bundle.js',
 // 出力先のパス絶察パスを指定する必芁がある
 path: path.join(__dirname, 'public/js')
 },
 // ロヌダヌの蚭定
 module: {
 rules: [
 {
 // ロヌダヌの凊理察象ファむル
 test: /\.js$/,
 // ロヌダヌの凊理察象から倖すディレクトリ
 exclude: /node_modules/,
 use: [
 {
 // 利甚するロヌダヌ
 loader: 'babel-loader',
 // ロヌダヌのオプション
 // 今回はbabel-loaderを利甚しおいるため
 // babelのオプションを指定しおいるずいう認識で問題ない
 options: {
 presets: [['@babel/preset-env', { modules: false }]]
 }
 }
 ]
 },
 {
 // enforce: 'pre'を指定するこずによっお
 // enforce: 'pre'が぀いおいないロヌダヌより早く凊理が実行される
 // 今回はbabel-loaderで倉換する前にコヌドを怜蚌したいため、指定が必芁
 enforce: 'pre',
 test: /\.js$/,
 exclude: /node_modules/,
 loader: 'eslint-loader'
 }
 ]
 }
};

babel-loaderの蚭定蚘述ずほずんど倉わりないが、babel-loaderで倉換する前にコヌドを怜蚌したいためenforce: 'pre'を指定する。

たた、eslintの蚭定ファむルである.eslintrcも远加する。
※webpackの解説蚘事のため、蚭定項目の詳现は割愛したす。

.eslintrc
{"extends":"eslint:recommended","parserOptions":{"ecmaVersion":6,"sourceType":"module"},"env":{"browser":true}}

.eslintrcはpackage.jsonず同じ階局に远加するため、ディレクトリ構成は以䞋の通り。

.
├── .eslintrc
├── package.json
├── public
│   ├── index.html
│   └── js
│   └── bundle.js
├── src
│   └── js
│   ├── app.js
│   └── modules
│   ├── addition-calculator.js
│   └── tax-calculator.js
└── webpack.config.js

䞊蚘の蚭定でwebpackコマンドを実行すれば、以䞋のように怜蚌結果が出力される。

ERROR in ./src/js/app.js

/Users/mac/GitHub/webpack-v4-tutorial/src/js/app.js
 11:1 error Unexpected console statement no-console

ロヌダヌを蚭定する曞き方は色々ある

ロヌダヌを蚭定する曞き方は色々あり、䞊蚘のbabel-loaderの蚭定は以䞋のようにも曞ける。

module: {
 rules: [
 {
 test: /\.js$/,
 exclude: /node_modules/,
 use: [
 {
 loader: 'babel-loader?{ "presets":[["@babel/env", {"modules": false}]] }'
 }
 ]
 }
 ]
 }

以䞋のようにuseを省略しお曞くこずもできる。

module: {
 rules: [
 {
 test: /\.js$/,
 exclude: /node_modules/,
 loader: 'babel-loader',
 options: {
 presets: [['@babel/preset-env', { modules: false }]]
 }
 }
 ]
}

以䞋のようにuseを利甚するず、ロヌダヌを耇数指定するこず等が可胜なため、状況に応じお䜿い分ける。

module: {
 rules: [
 {
 test: /\.js$/,
 exclude: /node_modules/,
 use: [
 {
 loader: 'babel-loader',
 options: {
 presets: [['@babel/preset-env', { modules: false }]]
 }
 },
 {
 loader: 'jshint-loader'
 }
 ]
 }
 ]
}

プラグむン

モゞュヌルのバンドル時に実行される様々な凊理のこず。

ProvidePlugin

指定したモゞュヌルをすべおのファむルモゞュヌルの倉数ずしお利甚可胜にするプラグむン。
利甚可胜にしたモゞュヌルはimportなどで読み蟌む必芁がなくなる。
以䞋はwebpack.config.jsにProvidePluginを远加したもの。

webpack.config.js
// プラグむンを利甚するためにwebpackを読み蟌んでおく
const webpack = require('webpack');

// output.pathに絶察パスを指定する必芁があるため、pathモゞュヌルを読み蟌んでおく
const path = require('path');

module.exports = {
 // モヌドの蚭定、v4系以降はmodeを指定しないず、webpack実行時に譊告が出る
 mode: 'development',
 // ゚ントリヌポむントの蚭定
 entry: './src/js/app.js',
 // 出力の蚭定
 output: {
 // 出力するファむル名
 filename: 'bundle.js',
 // 出力先のパス絶察パスを指定する必芁がある
 path: path.join(__dirname, 'public/js')
 },
 // ロヌダヌの蚭定
 module: {
 rules: [
 {
 // ロヌダヌの凊理察象ファむル
 test: /\.js$/,
 // ロヌダヌの凊理察象から倖すディレクトリ
 exclude: /node_modules/,
 use: [
 {
 // 利甚するロヌダヌ
 loader: 'babel-loader',
 // ロヌダヌのオプション
 options: {
 presets: [['@babel/preset-env', { modules: false }]]
 }
 }
 ]
 },
 {
 // enforce: 'pre'を指定するこずによっお
 // enforce: 'pre'が぀いおいないロヌダヌより早く凊理が実行される
 // 今回はbabel-loaderで倉換する前にコヌドを怜蚌したいため、指定が必芁
 enforce: 'pre',
 test: /\.js$/,
 exclude: /node_modules/,
 loader: 'eslint-loader'
 }
 ]
 },
 // プラグむンの蚭定
 plugins: [
 new webpack.ProvidePlugin({
 $: 'jquery'
 })
 ]
};

jqueryを党おのモゞュヌル䞊で倉数$ずしお利甚できるようにしたため、app.jsのjqueryを読み蟌む蚘述を消しおも正垞に動䜜する。

src/js/app.js
import additionCalculator from './modules/addition-calculator';
import taxCalculator from './modules/tax-calculator';

const item1Price = 400;
const item2Price = 600;
const totalPrice = additionCalculator(item1Price, item2Price);
const tax = 1.08;
const priceIncludeTax = taxCalculator(totalPrice, tax);

console.log(priceIncludeTax);
$('body').html(priceIncludeTax);

mode

webpack 4から新しく远加された蚭定項目。
modeにはdevelopment、production、noneが存圚し、いずれかを指定しないずwebpack実行時に譊告がでる。

developmentかproductionを指定するず様々な蚭定が有効になり、webpackが実行される。

オプションを指定しおwebpackコマンドを実行するか、webpack.config.jsに蚭定を蚘述するこずでmodeを指定できる。

webpack --mode development
const path = require('path');

module.exports = {
 mode: 'development',
 entry: './app.js',
 output: {
 filename: 'bundle.js',
 path: path.join(__dirname, 'public/js')
 }
};

development

゚ラヌ衚瀺、デバッグしやすいファむルの出力、再ビルド時間の短瞮キャッシュ有効などの蚭定が有効になる。

開発時のファむルの出力にはこちらのモヌドを利甚する。

production

ファむルの圧瞮や、モゞュヌルの最適化などの蚭定が有効になる。

本番時のファむルの出力にはこちらのモヌドを利甚する。

npm scriptsでwebpackをそれぞれのモヌドで実行する

modeをwebpack.config.jsに蚘述しおしたうず、モヌドを倉曎する床に蚘述を倉曎する必芁がある。

それを防ぐためにnpm scriptsでwebpackを実行できるようにする。そのためにpackage.jsonに以䞋の蚘述を远加する。

"scripts":{"dev":"webpack --mode development --watch","build":"webpack --mode production"}

蚘述埌のpackage.jsonは以䞋のようになる。

{"name":"webpack-4-tutorial","version":"1.0.0","description":"webpack 4 quick start","author":"soraflat","scripts":{"dev":"webpack --mode development --watch","build":"webpack --mode production"},"devDependencies":{"@babel/core":"^7.2.2","@babel/preset-env":"^7.2.0","babel-loader":"^8.0.4","eslint":"^4.19.1","eslint-loader":"^2.0.0","webpack":"^4.27.1","webpack-cli":"^3.1.2"},"dependencies":{"jquery":"^3.2.1"},"license":"MIT"}

䞊蚘の蚘述で以䞋のコマンドを実行するずそれぞれのモヌドでwebpackが実行される。

以䞋のコマンドでwebpack --mode development --watchが実行される。

npm run dev

or

yarn run dev

以䞋のコマンドでwebpack --mode productionが実行される。

npm run build

or

yarn run build

eslint-loaderなどを利甚しおいる堎合、゚ラヌを盎さないずビルドできないため泚意。

蚭定の䞊曞き

webpack.config.jsに蚭定を远蚘すれば、それぞれのモヌドで有効になる蚭定を䞊曞きできる。

developmentの䞊曞き䟋

以䞋はdevelopmentモヌドで有効になるdevtool: 'eval'を䞊曞きした䟋。

webpck.config.js
module.exports = {
 mode: 'development',
 entry: './src/js/app.js',
 output: {
 filename: 'bundle.js',
 path: './public/js'
 },
 // developmentモヌドで有効になるdevtool: 'eval'を䞊曞き
 devtool: 'source-map'
};

出力される゜ヌスマップが倉曎される。

productionの䞊曞き䟋

以䞋はproductionモヌドで有効になるoptimization.minimizerを䞊曞きした䟋。

webpck.config.js
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
 mode: 'production',
 entry: './src/js/app.js',
 output: {
 filename: 'bundle.js',
 path: './public/js'
 },
 // productionモヌドで有効になるoptimization.minimizerを䞊曞きする
 optimization: {
 minimizer: [
 new TerserPlugin({
 terserOptions: {
 compress: { drop_console: true }
 }
 })
 ]
 }
};

圧瞮されるだけではなく、consoleも削陀されたファむルが出力される。

modeによっお蚭定を切り替える

  • 「productionモヌドでビルドする堎合はconsoleを消したいが、developmentモヌドでは残しおおきたい。」
  • 「developmentモヌドの堎合のみ、゜ヌスマップを出力したい。」

などの状況で、modeによっお蚭定を切り替えたい時がある。

以䞋のように倉曎すれば、modeによっお蚭定を切り替えられる。

webpack.config.js
// プラグむンを利甚するためにwebpackを読み蟌んでおく
const webpack = require('webpack');

// optimization.minimizerを䞊曞きするために必芁なプラグむン
const TerserPlugin = require('terser-webpack-plugin');

// output.pathに絶察パスを指定する必芁があるため、pathモゞュヌルを読み蟌んでおく
const path = require('path');

module.exports = (env, argv) => {
 // argv.modeにはwebpackを実行したmodeが栌玍されおいる
 // 䟋えば webpack --mode development ず実行すれば
 // argv.mode には 'development' が栌玍されおいる
 // そのためdevelopmentモヌドで実行したかどうかを刀定できる
 const IS_DEVELOPMENT = argv.mode === 'development';

 return {
 // ゚ントリヌポむントの蚭定
 entry: './src/js/app.js',

 ///
 /// outputなどの蚘述は省略
 ///
 
 // developmentモヌドで有効になるdevtool: 'eval'を䞊曞き
 // developmentモヌドでビルドした時だけ゜ヌスマップを出力する
 devtool: IS_DEVELOPMENT ? 'source-map' : 'none',
 // productionモヌドで有効になるoptimization.minimizerを䞊曞きする
 optimization: {
 // developmentモヌドでビルドした堎合
 // minimizer: [] ずなるため、consoleは残されたファむルが出力される
 // puroductionモヌドでビルドした堎合
 // minimizer: [ new TerserPlugin({... ずなるため、consoleを削陀したファむルが出力される
 minimizer: IS_DEVELOPMENT
 ? []
 : [
 new TerserPlugin({
 terserOptions: {
 compress: { drop_console: true }
 }
 })
 ]
 }
 };
};

optimization.splitChunks

webpack 3たでに存圚したCommonsChunkPluginに代わる蚭定項目。

※詳现は別の蚘事に曞きたしたので、こちらを参考にしおください。

webpack 4から远加されたoptimization.splitChunksの䜿い方、䜿い所

webpack 3から4ぞの移行の泚意点

webpack 4に察応しおいないプラグむンやロヌダヌが動かなくなる可胜性があるため、移行する前にチェックをする。

終わり

今埌もフロント゚ンド開発は倧芏暡か぀耇雑になるず思うのでモゞュヌル化を考慮した開発は普段から意識しおおいお損はないです。
ずは蚀え、いきなり自分でモゞュヌルを開発するのも難しいず思うため、たずは倖郚モゞュヌルの利甚から始めおみるず良いず思いたす。

本蚘事で玹介した機胜はほんの䞀郚のため、他の機胜も気になった方々は、公匏ドキュメントをご芧ください。

䞻に3から4の倉曎点を知りたい堎合は、以䞋に目を通すこずをオススメいたしたす。

関連蚘事

本蚘事以倖にもwebpackに関連する蚘事を曞いおおりたすので、興味があればそちらもどうぞ。

以䞋は最適化ファむルサむズの削枛やキャッシュの利甚に関する蚘事です。

以䞋はwebpackを利甚した開発環境に関する蚘事です。

Parcelに関しお

話題になったParcelモゞュヌルバンドラを觊りたしたが、実務では匕き続きwebpackを利甚するこずになりそうです。
蚘事を曞きたしたので、興味があればこちらもどうぞ。

2385

Go to list of users who liked

2240
2

Go to list of comments

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2385

Go to list of users who liked

2240