合わせて是非お読み下さい。
WebpackではJavaScriptなどの依存関係があるモジュールを1つのファイルとしてバンドル(まとめて)くれる非常に便利なモジュールバンドラーです。
JSのモジュールバンドラーと言えばWebpackと言われる程のツールです。
JavaScriptに関係なく、HTMLやCSSなどもバンドルが容易となっております。
Webpackを扱うには『Node.js』のパッケージマネージャであるnpmを通してインストールします。
『npm init』コマンドを使用し、プロジェクトの初期化をし『package.json』を生成します。
その後、npm installで『webpack webpack-cli』パッケージをインストールします
これはWebpackでの操作をするための様々なコマンドを提供するものです。
なので『webpack webpack-cli』をインストールしなければWebpackを扱う事もできません。
Webpackを構成する場合、オプションとして適用される4つの主要な概念があります。
• entry
• output
• loaders(ローダー)
• Plugins(プラグイン)
これからの基礎は他のモジュールバンドラーといくつかの類似点を共有していることにも注意して下さい。
依存関係のエントリポイントを指定・配置方法などの構成する出力オブジェクトおよび外部プラグインの追加のプラグインオブジェクト定義などです。
entryとoutput
Webpackを使用しJavaScriptのモジュールをバンドルする際のエントリポイント
バンドルされる前のデフォルトでは基本的には『src/index.js』として配置します。(HTMLファイルなども含む)
module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'my-bundle.js', } };
entryの設定をした場合では何がどうなっているのか これは設定した際、上記でしたら単一エントリとなっています。
『./src/index.js』がエントリポイントなので、index.jsファイルをバンドルし、バンドルされたファイル指定の名前が『my-bundle.js』指定なので『dist/my-bundle.js』として出力します。
複数のエントリファイルへのパスを含む配列を持てるマルチエントリタイプに指定する事も可能です。
entry: [ './src/index.js', './src/index2.js' ],
webpack設定ファイルでの『output 』で良く使用するプロパティoutput.pathプロパティの『path.resolve(__dirname, 'dist')』メソッドではバンドルされた際の出力先であるディレクトリの絶対パス指定となります。
output: { path: path.resolve(__dirname, 'dist'), //ディレクトリの絶対パス }
つまり『__dirname』はNode.jsに元々あるグローバル変数となっており、現在実行中であるコードが格納されているので容易に『絶対パス』指定する事が可能となります。
本来は絶対パスで指定したディレクトリは事前にビルドする前に作成しときます、指定した名前で設定はしたが作成されていない場合はbuild時に自動で設定された名前でディレクトリと一緒にバンドルされたファイルも生成されます。
別ので『path.join』があります。
これはNode.jsの標準モジュール『 path』が提供する『path.join』メソッドとなります。
唯一のメリットはmacやwindowsなどの開発環境によって( /が¥ )になったりするのを防ぐ事です。
基本的には『__dirname』をお勧め致します。
『output.filename』プロパティでは、出力した際の『ファイル名』を指定し設定します。
output: { //outputプロパティ filename: 'my-bundle.js', //出力した際のファイル名 }
output.filenameは基本的には文字列で指定し設定していきますが、テンプレート用もあります。
[name]プロパティが存在します、これはkeyとして指定します『 [name].js』。
こちらを指定した場合、出力時のファイル名は『bundle.js』というファイル名としてバンドルされます。
output: { //outputプロパティ filename: '[name].js', //出力時はbundle.js }
Loaders ローダー
デフォルトでは、webpackはJavaScriptファイルとJSONファイルのみを理解するため、それ以外の他のファイルはバンドルすることはできません、例えばCSSファイルなど。
他のタイプのファイルを処理し有効なモジュールに『変換』するために、webpackはローダーを使用します。
ローダーは、JavaScript以外のモジュールのソースコードを変換し、依存関係に追加(バンドル)する前にそれらのファイルを前処理できるようにします。
ローダーを使用すれば、JavaScriptモジュールから直接CSSファイルをインポートも容易となります。
ESコードのトランスパイルだけではなく、スタイルの処理、ESLintを使用した様々な用途に活用できる柔軟性を兼ね備えています。
推奨オプションの場合では、ローダーを適用するファイルタイプを指定したりします。
その方法は、 moduleプロパティに『rules配列』を作成し、オブジェクト内のローダーを指定します。
各ローダーには、ローダーを適用するアセットに一致する2つのプロパティを使用し設定します。
単一の場合
module: { rules: [ //rules配列 { //設定 test: /\.(jpe?g|png|gif|)$/, //testプロパティ use: ['file-loader'], //useプロパティ }, ], },
『test』は処理対象の拡張子を正規表現で指定し変換をするファイル指定となります。
『use』は変換する時に使用されるローダー指定で配列・文字列などで指定します。
どのローダーを使用していくかを『use』で決めていきます。
ローダーを複数指定も可能となります。
module: { rules: [ //rules配列 { //設定 test: /\.(jpe?g|png|gif)$/, use: ['file-loader'], }, { //追加 test: /\.scss$/, use: [ 'style-loader', //cssをhtmlにstyleタグとして出力 'css-loader', // jsにバンドル 'sass-loader' // cssに変換、コンパイル ] } ], },
webpackでCSSを使用する方法は後ほど説明致します。
これら以外に複数のプロパティがあります、例えば『UseEntry』プロパティでは、『use』内で指定するもので関数やオブジェクトで指定していきます。
babel-loader
Babelを使用すると、まだサポートされていないコードがバニラJavaScriptにトランスパイルされ、すべての環境(ブラウザなど)が解釈できるようになります。
別の言い方にしますと、JavaScriptコードを最新のECMA構文からES5(古いコード)にトランスパイルするためとなります、つまり変換ツールとなります。
babelではそもそも、モジュールを1つにまとめる(バンドル)機能はありません。
ですので基本的にはwebpackとセットで扱う場合はこのbabel-loaderを使用していきます。
Babelを実行するには、コマンドラインに2つの主要な依存関係(モジュール)をインストールする必要があります。
例えば『@babel/core』『@babel/preset-env』など。
インストール後は『package.json』と『webpack.config.js』を調整(必要な場合)する必要があります、これらの変更には以前にインストールしたすべてのパッケージが含まれます。
『webpack.config.js』ではローダーの追加設定をしなければいけません。
module: { rules: [ { test: /\. js$/, exclude: /node_modules/, use: [ { 'babel-loader', presets: [ '@babel/preset-env', ] } ], }, ], },
package.jsonにもBabelプリセットの追加が必要です。
{ ... "babel": { "presets": [ "@babel/preset-env" ] }, ... }
targets を指定していないので、ES5の構文に変換するためのこれら設定が必要となります。
Babel構成を別の『.babelrc』構成ファイルに抽出することです。
このファイルは、プロジェクトのルートディレクトリに作成します。
{ "presets": [ "@babel/preset-env" ] }
こうする事で、先程のように『package.json』と『webpack.config.js』での構成をする必要はなくなりbabelrcファイルに統合すると、JavaScriptソースコードを実行できるようになります。
css-loader/style-loader
webpackでCSSを扱っていきたい場合は、ファイルを変換するための『css-loader』が必要となります。
もちろんCSSだけではありません、『.ts』『.scss』も含みます。
css-loaderは、webpackがアプリケーションで参照されているすべてのcssファイルからcssを収集し、それを文字列に入れるのに役立つnpmモジュールとなっております。
『style-loader』は何に使用するのか
これはcss-loaderによって生成された出力文字列を取得してから『index.html』ファイルのstyleタグ内に配置します。
2つのローダーのインストール
npm install css-loader style-loader --save-dev
webpackでcssコードをコンパイルとバンドルをするには『webpack.config.js』でcss-loaderとstyle-loaderを設定しなければいけません。
『rule』を使用するためのを追加します。webpack.config.jsのプロパティで下記のように構成致します。
module.exports = { module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] } ] }, .... .... }
『test』は処理対象のcssファイル指定です。
『use』プロパティで複数指定したローダーは最後から最初の順番に適用されるのご注意下さい。
上記であればcss-loader → style-loader となります。
『css-loader』を使用しコンパイルしてから、css-loaderの出力で『style-loader』を使用します。
ファイルに直接インポートの際は非常に簡単です。 これはインラインメソッドによる方法です。
エントリポイントである『index.js』で作成したcssファイルをインポートします。
import './style.css';
p { color: red; background-color: #000; }
cssでの扱い方は今後、個別で記事に致します。
Plugins(プラグイン)
webpackでプラグインを使用すると、コードがバンドルされているときにローダーが実行できなかったことを実行させる事が可能になります。
カスタマイズを提供します。
プラグインを使用する場合、『webpack.config.js 』で『 require() 』を使用しプラグインを読み込みます
『plugins 』プロパティの配列に設定追加します。
指定方法は『new演算子』でインスタンスを生成し引数にオプションを指定していきます。
いくつかのプラグインで例を解説します。
• HtmlWebpackPlugin
npm install --save-dev html-webpack-plugin
HtmlWebpackPluginはコンパイル時に、生成された JavaScriptファイルなどが読み込まれ表示するHTMLファイルが自動で生成されます。
『webpack.config.js 』内で『require()』を使用し読み込みます。
const HTMLWebpackPlugin = require('html-webpack-plugin')
簡単な方法は先程仰ったように、作成したインスタンスをplugins配列の 1 つとして渡すだけとなります。
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, plugins: [ new HTMLWebpackPlugin(), ] }
webpackコマンドでビルドした時、output.path内のディレクトリに『index.html』が作られます。
またその『.html』ファイルは[name].js、が読み込まれる記載のある状態で作られますので
インスタンスを作る際にはいくつか渡せるオプションがあります。
new HTMLWebpackPlugin({ filename: 'default.html` })
ファイル名である名前の指定する設定。
new HTMLWebpackPlugin({ filename: 'default.html`, title: 'my_blog' })
『title』設定する事により、HTMLファイル内の『titleタグ』内を任意のテキストに変更が可能です。
この他にテンプレートにしたいファイルとして設定する事も容易となっています。
• MiniCssExtractPlugin
npm install --save-dev mini-css-extarct-plugin
MiniCssExtractPluginを使用すると、CSSを別ファイルとして書き出し出力する事が可能なプラグインとなります。
『MiniCssExtractPlugin』をrequire()を使用し『webpack.config.js 』内で読み込みます。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /\.css/, use: [ { loader: MiniCssExtractPlugin.loader }, { loader: 'css-loader' } ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'style.css' //ファイル名の指定 }) ],
ビルドするとdistディレクトリ内に新しく『CSSファイル』が生成され追加されます。
css-loaderはCSSをJavaScriptに変換となります。
変更されたCSSはMiniCssExtractPlugin.loaderでCSSを抽出して別ファイルとして出力していき
new MiniCssExtractPlugin()でファイル名を指定します。
これはファイルが追加されただけなので、読み込みの際はHTMLファイルでリンクとして読み込むのは忘れないように気をつけて下さい。
例えばですがこのプラグインであれば、SassをCSSに変換した際に、別ファイルとして生成したりなどが可能となります。
プラグインのオプションについて
pluginsプロパティでオプションを指定することが可能で様々なオプションがあります。
今回では紹介しなかった『favicon』これはファビコンのパスを指定するもので文字列として指定します。
『meta』オプション、その名の通りmetaタグをHTMLに挿入する指定となります、こちらはオブジェクトとして設定します。
他にも真偽値でブラウザのキャッシュ更新をさせるかなどのオプションもあります。
webpack-dev-server
webpackでは 『webpack-dev-server』を使用し開発サーバー環境を簡単に立ち上げが容易となっております。
Webpack開発サーバーもNPM経由でインストールする必要がある別個のパッケージです。
npm i --save-dev webpack-dev-server
Webpack開発サーバーは開発にのみ使用する必要があります
変更に対する即時性のリロードと即時のフィードバックを提供することにより、開発時間を短縮するためのすばらしいツールです。
ファイルの変更を自動的に監視し、保存時にバンドルを自動的に更新致します、ライブサーバーを使用している間はバンドルはフォルダーではなくメモリ(RAM)のdistに存在するため、はるかに高速に更新できます。
ファイル変更した際の確認をする際は、webpackでのコマンドまたは『package.json』のscriptsのフィールドに追加しそれらを実行しビルドまたはブラウザの確認をします。
webpack構成にプロパティ追加します。
module.exports = { ... devServer: { static: './dist/html', }, ... };
『static』はサーバーで表示させるファイルの場合指定となります。
上記でしたら『./dist』フォルダにある『HTMLファイル』の指定です。
フォルダ指定がない場合、デフォルトでは『public』となります。
コマンドを実行します
npx webpack --open --mode development
デフォルトでは、webpackは『ポート8080』で提供します。
『--mode』オプションは必ず指定下さい。
でないとエラー警告が表示されます。
『--open』は自動的にブラウザを開いてページを表示するためのオプションとなります。
『--watch』オプション使用すると、ファイル変更されると自動的に webpack コマンドを実行するようになります。※ブラウザ反映はありません。
開発サーバーの停止は『control + c』で止められます。
『NPM Scripts』でのコマンドでこれよりも簡単にサーバーを起動する方法の『package.json』の設定も解説します。
"scripts": { "start": "webpack-dev-server --mode development", "build": "webpack --mode production" },
開発サーバーの立ち上げの際は『npm start』
npm start
ビルド時は『npm run build』
npm run build
もちろんですが『--open』設定をしておけば『npm start』コマンドで自動でブラウザが立ち上がるようになります。
本日はここまでにしておきます。
webpackは、多くのプロジェクトで使用されるJavaScriptツールチェーンの重要な部分であることがわかったかと思います。
柔軟で拡張可能な性質で実現できることを垣間見ていって下さい。
Webpackが解決する問題および構成ファイルのセットアップ手順をよりよく理解できることを願っております。
最後まで読んで頂きありがとうございました。