こんにちは。まさきです。
今回はwebpackの主要な機能のひとつであるローダーの解説とインストール方法についてご紹介します。
ローダーとは
webpackはJavaScriptやCSS、画像を1つのファイルのまとめる(バンドル)することができます。
このときにCSSや画像ファイルは一度JavaScriptに変換されてから、JavaScriptファイルとして1つにまとめられます。
このCSSや画像ファイルをJavaScriptに変換するプログラムがローダーです。
それ以外にも最新のJavaScriptをどのブラウザでも動くJavaScriptに変換するBabelローダーや、ESLintのようなコードをチェックするローダーも存在します。
今回は以下のローダーについてインストール方法と使い方をご説明します。
- babel-loader
- css-loader/sass-loader
- url-loader/file-loader
なお説明はwebpackでプロジェクトを作成している前提で進めていきます。
webpackのプロジェクトの作り方や、そもそもwebpackってなんだろうって方は以前のこちらの記事をご覧ください。
各種使用方法
babel-loader
babelとは
冒頭ではbabelローダーは最新のJavaScriptをどのブラウザでも動くJavaScriptのコードに変換するローダーだと言いました。
厳密にはJavaScriptのES6以降のコードをES5のコードにトランスパイル(変換)するローダーです。
ES6以降のコードはブラウザによっては動かないものがあるので、そういったブラウザで使う場合はES5のコードに変換する必要があります。
ES6以降のコードの例としてはアロー関数やlet/constなどがあります。
//トランスパイル前
let addNum= (num1, num2) => {
return num1 + num2;
};
//トランスパイル後
let addNum = function(num1, num2){
return num1 + num2;
};
アロー関数の意味の説明は割愛しますが、このトランスパイル前とトランスパイル後のコードは同じ処理をしています。
トランスパイル前のコードで書いてbabelを使うとトランスパイル後のコードに変換されるのです。
babel-loaderのインストール方法
インストールするディレクトリに移動して以下の3つのコマンドを順番に実行します。
npm install --save-dev babel-loader
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env
私が実際に各種インストールしたときの画像を張っておきます。正常に完了したら同じような画面になると思います。
これでインストールできました。
実際にインストールされているかはpackage.jsonのdevDependenciesにインストールした3つのバージョンが追記されていることを確認します。
devDependenciesは–save-devコマンドでインストールしたものが記載されます。
インストールが済んだらwebpack.config.jsにbabelの設定を追加します。
webpack.config.jsを開いてmodulesに以下を追加します。
module:{
rules:[{
//ローダの処理対象ファイル
test:/\.js$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/js'),
use:[
{
//利用するローダー
loader: 'babel-loader',
//ローダーのオプション
options:{
presets: [['@babel/preset-env',{modules: false}]]
}
}
]
}]
}
念のため例として全体コードを乗せておきます。modulesがない場合はコードを参考に一番最後に追加してください。
//出力時指定するパスがOSによって異なるのを防ぐため必要
const path = require('path');
module.exports = {
//モードの設定(指定しないとwebpack実行時警告が出る)
mode: 'development',
//エントリーポイントの設定(app.js)
entry: './src/js/app.js',
//出力の設定(public/js/bundle.js)
output : {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public/js')
},
module:{
rules:[{
//ローダの処理対象ファイル
test:/\.js$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/js'),
use:[
{
//利用するローダー
loader: 'babel-loader',
//ローダーのオプション
options:{
presets: [['@babel/preset-env',{modules: false}]]
}
}
]
}]
}
};
実装方法
ではエントリーポイントのファイルに以下のコードを書きます。
let addNum= (num1, num2) => {
return num1 + num2;
};
コードを書いたらwebpackでビルドしてバンドルファイルを作成します。以下のビルドコマンドを実行してください。
npm run build
このようにビルドが終わるまで待ちます。
ビルドが終わったらバンドルファイルが出力されているbundle.jsを見てみます。
var addNum = function addNum(num1, num2) {\n return num1 + num2;\n};
このようにアロー関数とletが変換されていることが確認できました。
css-loader/sass-loader
css-loader/sass-loaderとは
こちらはcssファイルをjsファイルに変換するローダーです。
cssだけでなくscssやsaccもjsファイルに変換できます。
css-loader/sass-loaderのインストール方法
インストールするディレクトリに移動して以下の4つのコマンドを順番に実行します。
npm install --save-dev sass-loader
npm install --save-dev node-sass
npm install --save-dev css-loader
npm install --save-dev style-loader
私が実際に各種インストールしたときの画像を張っておきます。正常に完了したら同じような画面になると思います。
これでインストールできました。
実際にインストールされているかはpackage.jsonのdevDependenciesにインストールした4つのバージョンが追記されていることを確認します。
devDependenciesは–save-devコマンドでインストールしたものが記載されます。
インストールが済んだらwebpack.config.jsに設定を追加します。
webpack.config.jsを開いてmodulesに以下を追加します。
module:{
rules:[
{
//ローダの処理対象ファイル
test:/\.scss$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/scss'),
use:[
//利用するローダー
'style-loader','css-loader','sass-loader'
]
}
]
}
念のため例として全体コードを乗せておきます。modulesがない場合はコードを参考に一番最後に追加してください。
//出力時指定するパスがOSによって異なるのを防ぐため必要
const path = require('path');
module.exports = {
//モードの設定(指定しないとwebpack実行時警告が出る)
mode: 'development',
//エントリーポイントの設定(app.js)
entry: './src/js/app.js',
//出力の設定(public/js/bundle.js)
output : {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public/js')
},
module:{
rules:[
{
//ローダの処理対象ファイル
test:/\.js$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/js'),
use:[
{
//利用するローダー
loader: 'babel-loader',
//ローダーのオプション
options:{
presets: [['@babel/preset-env',{modules: false}]]
}
}
]
},
{
//ローダの処理対象ファイル
test:/\.scss$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/scss'),
use:[
//利用するローダー
'style-loader','css-loader','sass-loader'
]
}
]
}
};
ローダーは指定した順番の逆から実行されるので指定の順番に気をつけましょう。
今回はsass-loader→css-loader→style-loaderの順に実行されます。
実装方法
saccファイルを新規作成します。
src/scss/_variables.scssとsrc/scss/style.scssを作成します。
$black: #000000;
$white: #ffffff;
@import './variables';
body {
background: $black;
color: $white;
}
ではエントリーポイントのsrc/js/app.jsファイルを修正します。
import '../scss/style.scss';
index.htmlのHTMLも修正します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="public/js/bundle.js"></script>
</head>
<body>
<h1>using sass loader</h1>
</body>
</html>
ファイルを修正したらwebpackでビルドしてバンドルファイルを作成します。以下のビルドコマンドを実行してください。
npm run build
ビルドが終わったら先ほど修正したindex.htmlをブラウザで表示します。
sassファイルで指定した内容が反映されていることを確認できました。
url-loader/file-loader
url-loader/file-loaderとは
url-loaderを使うと画像をDataURLに変換できるのでJSファイルにバンドルできます。
これによりcssで使う画像もバンドルして事前に出力しておくことができます。
しかしこの場合、全ての画像をバンドルすればいいわけではありません。
DataURLはファイルサイズが大きくなってしまうデメリットがあるので、ファイルサイズが大きい画像はそのままの方がよいです。
ファイルサイズが小さい画像だけバンドルし、一定以上のファイルサイズの画像はバンドルせずそのまま出力するのが一般的です。
その場合はurl-loaderに加えてfile-loaderを使用します。
今回はurl-loaderで画像をバンドルする方法だけご説明します。
url-loaderのインストール方法
インストールするディレクトリに移動して以下5の5つのコマンドを順番に実行します。すでにインストールしているものはスキップしてください。
npm install --save-dev sass-loader
npm install --save-dev node-sass
npm install --save-dev css-loader
npm install --save-dev style-loader
npm install --save-dev url-loader
私が実際に各種インストールしたときの画像を張っておきます。正常に完了したら同じような画面になると思います。
これでインストールできました。
実際にインストールされているかはpackage.jsonのdevDependenciesにインストールした5つのバージョンが追記されていることを確認します。
devDependenciesは–save-devコマンドでインストールしたものが記載されます。
インストールが済んだらwebpack.config.jsに設定を追加します。
webpack.config.jsを開いてmodulesに以下を追加します。
module:{
rules:[
{
//ローダの処理対象ファイル
test:/\.(png|jpg|gif)$/i,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/images'),
//利用するローダー
loader: 'url-loader'
}
]
}
念のため例として全体コードを乗せておきます。modulesがない場合はコードを参考に一番最後に追加してください。
//出力時指定するパスがOSによって異なるのを防ぐため必要
const path = require('path');
module.exports = {
//モードの設定(指定しないとwebpack実行時警告が出る)
mode: 'development',
//エントリーポイントの設定(app.js)
entry: './src/js/app.js',
//出力の設定(public/js/bundle.js)
output : {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public/js')
},
module:{
rules:[
{
//ローダの処理対象ファイル
test:/\.js$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/js'),
use:[
{
//利用するローダー
loader: 'babel-loader',
//ローダーのオプション
options:{
presets: [['@babel/preset-env',{modules: false}]]
}
}
]
},
{
//ローダの処理対象ファイル
test:/\.scss$/,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/scss'),
use:[
//利用するローダー
'style-loader','css-loader','sass-loader'
]
},
{
//ローダの処理対象ファイル
test:/\.(png|jpg|gif)$/i,
//ローダの処理対象となるディレクトリ
include: path.resolve(__dirname, 'src/images'),
//利用するローダー
loader: 'url-loader'
}
]
}
};
実装方法
画像はsrc/images/icon.pngを配置します。icon.pngはアイコン画像なら何でもいいです。
今回はアイコンのフリー素材のサイトからダウンロードしました。
src/scss/style.scssを修正します。
@import './variables';
body {
background: $black;
color: $white;
}
h1 {
display: flex;
align-items: center;
font-size: 15px;
&:before{
content: '';
background: url('../images/icon.png') no-repeat;
background-size: 100%;
display: block;
margin-right: 5px;
width: 18px;
height: 18px;
}
}
ファイルを修正したらwebpackでビルドしてバンドルファイルを作成します。以下のビルドコマンドを実行してください。
npm run build
ビルドが終わったら先ほど修正したindex.htmlをブラウザで表示します。
アイコン画像が表示されています。
では画像がDataURLに変換されているかを確認するために、ブラウザの開発者ツールを開きましょう。
画像がDataURLに変換されていました。