プログラミング

【備忘録】webpackのローダーとプラグインまとめ

【備忘録】webpackのローダーとプラグインまとめ

こんにちは!
webpackの学習を一通り終えたので、インプットするために、備忘録を書いていきます。
いろんなローダーやプラグインがあり、インストールするたび設定を付け加えたりと、1度だけでは間違いなく覚えられないので、今後使って行きそうなものをピックアップしてまとめて行きます。

自分用の備忘録となりますので、間違っていることもありますが、その場合は
ドキュメントも貼っておきますので、確認してみてください。

ちなみに、webpack4での学習でしたので、webpack4について書いています。

前回のwebpackをインストールまで終わっていること前提です。

【備忘録】VSCodeにwebpackをインストールするまでに必要なこと【備忘録】VSCodeにwebpackをインストールするまでに必要なこと こんにちは! 今回はVSCodeでwebpackを導入する...

記事の流れ
・開発用と本番用の設定
・JavaScriptのファイルを圧縮
・ソースマップの生成
・ディレクトリを綺麗に掃除
・HTMLの出力
・開発サーバー
・複数のファイルの出力
・ファイルの分割
・キャッシュ対策
・babelについて
・対象ブラウザを指定する
・ポリフィルについて
・eslintについて
・コードの整形
・Sassのバンドル
・CSSを個別に出力
・CSS用のの便利ツール
・CSSの圧縮
・画像を出力
・HTMLの画像を出力
・画像を圧縮

では備忘録を書いていきます。

 

開発用と本番用の設定 webpack-merge

用途
開発用と本番用を共通の設定でマージさせる。

インストールしたバージョン:5.0.9
最新バージョン:5.8.0
npmコマンド:npm install –save-dev webpack-merge@5.0.9

ドキュメント
https://www.npmjs.com/package/webpack-merge

設定の詳細
https://v4.webpack.js.org/configuration/mode/

webpack.common共通の設定

const path = require('path');

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

webpack.dev開発用の設定

const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

module.exports = merge(commonConfig, {
  mode: 'development',
  watch: true,
});

module.exportsで開発用の設定と共通設定をマージする。
watchをtrueにすことでファイルを監視するモードが有効になる。

webpack.prod本番用の設定

const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

module.exports = merge(commonConfig, {
  mode: 'production',
});

package.jsonの更新

  "scripts": {
    "dev": "webpack --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },

npm run devのコマンドで開発用が実行される
npm run buildのコマンドで本番用が実行される

ファイルを圧縮 terser-webpack-plugin

用途
JavaScriptファイルを圧縮する。

インストールしたバージョン:3.0.8
最新バージョン:5.2.5
npmコマンド:npm install –save-dev terser-webpack-plugin@3.0.8

ドキュメント
https://www.npmjs.com/package/terser-webpack-plugin

webpack.prod本番用の設定に追加

const TerserPlugin = require('terser-webpack-plugin');

module.exports = merge(commonConfig, {
  mode: 'production',
  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
        terserOptions: {
          compress: {
            drop_console: true,
          },
        },
      }),
    ],
  },
});

extractComments
falseでライブラリのライセンスコメントを生成されないようにする。
xxx.LICENSE.txtが生成されなくなる。

terserOptionsのdrop_console
trueでコンソールが削除される。

terserOptionsの詳細な設定
https://github.com/terser/terser#minify-options

ソースマップの生成

webpack.dev開発用の設定に追加

ドキュメント:https://v4.webpack.js.org/configuration/devtool/

module.exports = merge(commonConfig, {
  devtool: 'cheap-module-eval-source-map',
});

開発時は
eval
eval-source-map
cheap-eval-source-map
cheap-module-eval-source-map
が推奨されている。

本番用は
source-map
※ユーザーがソースマップにアクセスできないようにサーバー構成をする必要がある。
hidden-source-map
nosources-source-map
が推奨されている。

ディレクトリを綺麗に掃除 clean-webpack-plugin

用途
生成先ディレクトリを綺麗に掃除してくれるプラグイン。
不要なファイルなどを消してくれる。

インストールしたバージョン:3.0.0
最新バージョン:4.0.0

ドキュメント
https://www.npmjs.com/package/clean-webpack-plugin

webpack.common共通の設定に追加

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['**/*', '!**.html'],
    }),
  ],
};

cleanOnceBeforeBuildPatterns
指定することで、削除対象を指定できる。
htmlを削除しないようにしている。

html-webpack-pluginを利用する場合オプションは不要。

HTML出力 html-webpack-plugin

用途
webpackでHTMLを自動で出力してくれる。

インストールしたバージョン:4.3.0
最新バージョン:4.0.0

ドキュメント
https://www.npmjs.com/package/html-webpack-plugin

webpack.common共通の設定に追加

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/html/index.html',
    }),
  ],
};

template
指定することで、HTMLのなどをテンプレートできる。
index.htmlに出力する、バンドルを読み込んだ HTMLを出力する

開発サーバー webpack-dev-server

用途
webpackでの開発サーバーを立ち上げることができる。

インストールしたバージョン:3.11.0
最新バージョン:4.0.0

ドキュメント
https://webpack.js.org/configuration/dev-server/

package.jsonに追加

  "scripts": {
    "start": "webpack-dev-server --config webpack.dev.js",
  },

npm startのコマンドでサーバーが起動する

webpack.dev開発用の設定に追加

const path = require('path');

module.exports = merge(commonConfig, {
  devServer: {
    open: true,
    port: 9000,
    contentBase: path.resolve(__dirname, 'public'),
  },
});

open
trueで自動的にブラウザが開かれる。
contentBase
コンテンツのルートディレクトpublic/index.htmlが開かれる。

consoleに[WDS] Live Reloading enabled.が表示されていれば、有効になっている。

ターミナルで『Control』+『C』で停止できる。

複数のファイルの出力

webpack.common共通の設定を更新

module.exports = {  
    entry: {
        app: './src/js/app.js',
    another: './src/js/another.js',
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'js/[name].bundle.js',
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: './src/html/index.html',
      chunks: ['app'],
    }),
    new HtmlWebpackPlugin({
      filename: 'another.html',
      template: './src/html/another.html',
      chunks: ['another'],
    }),
  ],
  };
};

entry
追加したファイルを追加記述をする。
filenameの[name]はentryに指定した名前が入る。
今回の場合index.bundle.jsと another.bundle.js が出力される。
bundleはなくても別の名前でも可。

プラグインのfailenameは何も指定しないと、index.htmlが出力されるので、出力したい名前を指定する。

chunks
エントリーポイント名を指定することでwebpackから出力されたどのファイルから読み込むか指定できる。
指定しないと、複数のファイルが1つになって出力される。

ファイルを分割 splitChunksPlugin

用途
ファイルを分割して出力するプラグイン

ドキュメント
https://v4.webpack.js.org/plugins/split-chunks-plugin/

解説
https://qiita.com/soarflat/items/1b5aa7163c087a91877d

webpack.common共通の設定に追加

module.exports = {
  output: {
    chunkFilename: 'js/[name].js',
  },
  optimization: {
    splitChunks: {
      chunks: 'initial',
      cacheGroups: {
        vendor: {
          test: /node_modules/,
          name: 'vendor',
        },
        vendorsModules: {
          test: /src[\\/]js[\\/]modules/,
          name: 'vendor-modules',
          minSize: 0,
          minChunks: 2,
        },
      },
    },
  },

splitChunks
splitChunksの設定を行う。

chunks
分割する対象の設定。
async
デフォルトの設定
動的にインポートしているモジュール
import(”)でインポートしているもの

initial
静的にインポートしているモジュール
import 文を宣言的にインポートしているもの

all
すべて

cacheGroups
複数のファイルを出力する設定

vendorとvendorsModules
任意の名前をつけられる。

test
どのディレクトリを対象とするか

name
出力するファイル名
filename: ‘js/[name].bundle.js’,で出力されるため、
vender.bundle.jsと出力される。
chunkFilename: ‘js/[name].js’,を記述することで
優先されるのでvender.jsと出力される。
必要に応じて設定を変える。

minSize
モジュールの最小サイズ
デフォルトは30kb未満は分割の対象にならない

minChunks
モジュールがいくつの場所で使われていれば対象とするか。

キャッシュ対策

出力するファイル名を変えることでキャッシュ対策ができる。
webpack.common共通の設定を更新

module.exports = {
  output: {
    filename: 'js/[name].[contenthash].js',
    chunkFilename: 'js/[name].[contenthash].js',
  },
 },

[contenthash]
出力するファイルごとに固有の名前をつける。
ファイルを更新するたびつけてくれる。

babelについて babel-loader、@babel/core、@babel/preset-env

babel-loader
用途
JavaScriptのコンパイラ
古い書き方に変換する。

インストールしたバージョン:8.1.0
最新バージョン:4.0.0

ドキュメント
https://www.npmjs.com/package/babel-loader

@babel/core
用途
babelの本体

インストールしたバージョン:7.10.5
最新バージョン:7.16.0

ドキュメント
https://www.npmjs.com/package/@babel/core

詳細
https://babeljs.io/docs/en/babel-core

@babel/preset-env
用途
babelプラグインの設定(プリセット)

インストールしたバージョン:7.10.4
最新バージョン:7.16.4

ドキュメント
https://www.npmjs.com/package/@babel/preset-env

詳細
https://babeljs.io/docs/en/babel-preset-env

webpack.common共通の設定に追加
※書き方が複数ある

module.exports = { 
 module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
};

test
ローダーの処理対象になるファイルを正規表現で記述

exclude
ローダーの処理対象から外すディレクトリ

loader
利用するローダー

babel.config.jsを作成
設定ファイルに関しては、webpackの設定ファイルに書いても使えるが
分けたほうが見栄えがいい。

module.exports = {
  presets: ['@babel/preset-env'],
};

presets
利用するプリセットを記述

対象ブラウザを指定する.browserslistrc

.browserslistrc
対象ブラウザを指定する設定ファイル

用途
指定したブラウザだけを変換できる。
すべて変換しなくていいため、ファイルサイズを軽くできる。
異なるツール間で共通に使える。
ツールによっての重複や記述漏れなどをなくせる。

どのように変換されるかの確認
Babel Try it out

指定できるブラウザ
https://github.com/browserslist/browserslist#browsers-data-updating

.browserslistrcを作成

ie 11

ポリフィルについて core-js、regenerator-runtime

core-js
用途
ブラウザに関数がない場合、polyfillから関数を使うことができる。

インストールしたバージョン:3.6.5
最新バージョン:3.19.3

ドキュメント
https://www.npmjs.com/package/core-js

regenerator-runtime
用途
async/awaiの構文を使えるようにする。

インストールしたバージョン:0.13.7
最新バージョン:0.13.9

ドキュメント
https://www.npmjs.com/package/regenerator-runtime

babel.config.jsに追加

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'usage',
        corejs: 3,
        debug: true,
      },
    ],
  ],
};

useBuiltIns
必要なポリフィルのみを取り込みたい場合、usageを指定する

corejs
利用するポリフィルのバージョンの指定をする
指定しなかった場合、バージョン2が適用される。

debug
ポリフィルが含まれているかどうかを確認する
必要がなければ書かなくてもいい。

eslintについて eslint-loader、eslint

eslintについて
https://eslint.org/

eslint-loader
用途
eslintを走らせることができるツール

インストールしたバージョン:4.0.2
最新バージョン:4.0.2

ドキュメント
https://www.npmjs.com/package/eslint-loader

補足
eslint-loaderを使わなくても
pakage.jsonに直接記述したり、拡張機能を使えば
eslintだけインストールされている場合使える。

eslint
用途
JavaScriptのための静的検証ツール
コードを実行する前に明らかなバグを見つけたり、括弧やスペースの使い方などのスタイルを統一する

インストールしたバージョン:7.5.0
最新バージョン:8.4.1

ドキュメント
https://www.npmjs.com/package/eslint

.eslintrc.jsを作成

module.exports = {
  root: true,
  env: {
    browser: true,
    es2020: true,
  },
  parserOptions: {
    sourceType: 'module',
       //ecmaVersion: 11,
  },
  extends: [
    'eslint:recommended',
  ],
  rules: {
    'prefer-const': 'error',
  },
};

root
設定ファイルを探しに行く
trueにすると、これより親階層の設定ファイルを探しにいかない
デフォルトの場合すべての階層を探しに行く
(他の階層にある.eslintrc.jsの設定が適用される)

env
検証するJavaScriptの環境を設定。

browsser
trueにするとconsole.log などを利用してもエラーが発生しなくなる

es2020
trueにするES2020までの構文を利用してもエラーが発生しない。parserOptions.ecmaVersion11が自動でセットされる。

parserOptions
ECMAScriptのバージョンをサポートする設定

sourceType
moduleにするとES Modulesを利用してもエラーが発生しなくなる
import/exportが使える。

extends
外部で提供されている設定を利用する
eslintがおすすめしている設定を利用している。

rules
ルールを指定する。
更新をしない変数の宣言に、const 以外を利用した場合はエラーになる設定をしている。
extendsのルールとrulesで重複した場合、rulesが優先される。

ルールについて
https://eslint.org/docs/rules/

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
        options: {
          fix: true,
        },
      },
    ],
  },
};

enforce
ローダーのカテゴリーを指定する。
preにするとpreが指定されていないローダーよりも早く処理が実行される
(babelで変換される前のコードで検証するため)

test
ローダーの処理対象ファイル指定

exclude
指定したモジュールの除外

loader
利用するローダーの指定

options
eslint-loaderのオプションの設定

fix
一部のエラーを自動修正

コードの整形 prettier、eslint-config-prettier、eslint-plugin-prettier

prettier
用途
コードを整形する

インストールしたバージョン:2.0.5
最新バージョン:2.5.1

ドキュメント
https://www.npmjs.com/package/prettier

eslint-config-prettier
用途
eslintの整形に関する設定をすべて無効にする設定

インストールしたバージョン:6.11.0
最新バージョン:8.3.0

ドキュメント
https://www.npmjs.com/package/eslint-config-prettier

eslint-plugin-prettier
eslintでprettierを実行するプラグイン

インストールしたバージョン:3.1.4
最新バージョン:4.0.0

ドキュメント
https://www.npmjs.com/package/eslint-plugin-prettier

.eslintrc.jsに追加

module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:prettier/recommended',
  ],
};

plugin:prettier/recommendedはextendsの最後に記述する

.prettierrc.jsを作成

module.exports = {
  singleQuote: true,
};

singleQuote
文字列の表現がシングルクウォートになる。

設定できるルール
https://prettier.io/docs/en/options.html

Sassのバンドル sass-loader、node-sass、css-loader、style-loader

sass-loader
用途
sassをcssにコンパイルする

インストールしたバージョン:8.0.2
最新バージョン:12.4.0

ドキュメント
https://www.npmjs.com/package/sass-loader

node-sass
用途
nodeでsassを使えるようにする

インストールしたバージョン:4.14.1
最新バージョン:7.0.0

ドキュメント
https://www.npmjs.com/package/node-sass

css-loader
用途
cssをモジュールに変換する

インストールしたバージョン:3.5.3
最新バージョン:6.5.1

ドキュメント
https://www.npmjs.com/package/css-loader

style-loader
用途
バンドルしたcssをhtmlに挿入する

インストールしたバージョン:1.2.1
最新バージョン:3.3.1

ドキュメント
https://www.npmjs.com/package/style-loader

(style-loaderは不要になる)

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
};

sass-loader→css-loader→style-loader
の順で実行される。

コンパイル→モジュール→htmlに挿入

CSSを個別に出力 mini-css-extract-plugin

mini-css-extract-plugin
用途
sassをcssにコンパイルする

インストールしたバージョン:0.9.0
最新バージョン:2.4.5

ドキュメント
https://www.npmjs.com/package/mini-css-extract-plugin

style-loaderが不要になるため、uninstallコマンドで削除

webpack.common共通の設定に追加

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: './css/[name].[contenthash].css',
    }),
  ],
};

filename
出力するファイル名を記述する。
outputのpbulicに出力される。

[name]
エントリーポイント

[contenthash]
キャッシュ対策

CSS用の便利ツール postcss-loader、autoprefixer

postcss-loader
用途
CSSツールを作るためのフレームワーク

インストールしたバージョン:3.0.0
最新バージョン:6.2.1

ドキュメント
https://www.npmjs.com/package/postcss-loader

autoprefixer
用途
自動的にベンダープレフィックスを付け、対象ブラウザによって構文を変換をする

インストールしたバージョン:9.8.5
最新バージョン:10.4.0

ドキュメント
https://www.npmjs.com/package/autoprefixer

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [ MiniCssExtractPlugin.loader, 'css-loader','postcss-loader','sass-loader'],
      },
    ],
  },
};

postcss.config.jsonを作成

module.exports = {
  plugins: [require('autoprefixer')],
};

plugins
webpackで使うプラグインを指定する

ブラウザの指定はいくつかやり方があるが
.browserslistrc.に対象ブラウザを記載する。

CSSの圧縮 optimize-css-assets-webpack-plugin

optimize-css-assets-webpack-plugin
用途
cssnanoを用いて、CSSを圧縮(最適化)する。

インストールしたバージョン:5.0.3
最新バージョン:6.0.1

どのように最適化されるか
https://cssnano.co/

ドキュメント
https://www.npmjs.com/package/optimize-css-assets-webpack-plugin

postcss製のプラグインのため、postcssにcssnanoに設定を記述して、
optimize-css-assets-webpack-pluginをインストールしなくても使える。

webpack.prod本番用の設定に追加

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = merge(commonConfig, {
  optimization: {
    minimizer: [
            new TerserPlugin({}),
      new OptimizeCSSAssetsPlugin({}),
    ],
  },
});

オプションの指定はしないため、デフォルトで動作する


new
TerserPluginの設定がないとJavaScriptが圧縮されない。
optimizationのminimizerの設定が優先されてしまうため、デフォルトにある
TerserwebpackPluginが実行されなくなる。

画像を出力 file-loader

file-loader
用途
指定した場所に画像を出力する。

インストールしたバージョン:6.0.0
最新バージョン:6.2.0

ドキュメント
https://www.npmjs.com/package/file-loader

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|gif|png|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[contenthash].[ext]',
          outputPath: 'images',
          publicPath: '/images',
        },
      },
    ],
  },
};

test
画像が対象なので、画像の拡張子を記述

loader
使用するローダーの指定

name
出力するファイル名

[name]
バンドル前の名前

[contenthash]
キャッシュ対策

[ext]
バンドル前のファイルの拡張子

outputPath
画像の出力先
デフォルトでは output.path に指定したパス( public)に出力されるが指定することでpublic/images と出力される。

publicpath
出力されるCSSなどに使われている画像の出力先
プロジェクトによっては、画像が別サーバーに使われることもあるため、
出力先を変えることもある。

HTMLの画像を出力 html-loader

html-loader
用途
HTMLで使われている画像を出力させる。
webpackはデフォルトの状態だと、loadshを使っているため、htmlの画像を検知できない為、画像が出力されない。

インストールしたバージョン:1.1.0
最新バージョン:3.0.1

ドキュメント
https://www.npmjs.com/package/html-loader

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
    ],
  },
};

画像を圧縮 image-webpack-loader

image-webpack-loader
用途
画像を圧縮する。

インストールしたバージョン:6.0.0
最新バージョン:8.0.1

ドキュメント
https://www.npmjs.com/package/image-webpack-loader

webpack.common共通の設定に追加

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|gif|png|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[contenthash].[ext]',
              outputPath: 'images',
              publicPath: '/images',
            },
          },
          'image-webpack-loader',
        ],
      },
    ],
  },
};

複数のローダーを使えるようにuseを使う書き方に変える。
optionsを指定すれば圧縮率を指定できる。
指定しない場合デフォルトの設定になる。

loader: 'image-webpack-loader',
optios: {
 mozjpeg: {
  quality: 10,
 },
},

quality
画像の精度を指定

まとめ

開発用と本番用の設定 webpack-merge
ファイルを圧縮 terser-webpack-plugin
ソースマップの生成
ディレクトリを綺麗に掃除 clean-webpack-plugin
HTML出力 html-webpack-plugin
開発サーバー webpack-dev-server
複数のファイルの出力
ファイルを分割 splitChunksPlugin
キャッシュ対策
babelについて babel-loader、@babel/core、@babel/preset-env
対象ブラウザを指定する.browserslistrc
ポリフィルについて core-js、regenerator-runtime
eslintについて eslint-loader、eslint
コードの整形 prettier、eslint-config-prettier、eslint-plugin-prettier
sassのバンドル sass-loader、node-sass、css-loader、style-loader
CSSを個別に出力 mini-css-extract-plugin
CSS用の便利ツール postcss-loader、autoprefixer
CSSの圧縮 optimize-css-assets-webpack-plugin
画像を出力 file-loader
HTMLの画像を出力 html-loader
画像を圧縮 image-webpack-loader

についてでした。

今回はwebpackの学習をしたので総まとめでした。
自分用の備忘録なので、よくわからないとこともあるかもしれません笑
英語を読み解く力があれば、ドキュメントを見て理解できるかも。

webpack4での学習なので、今後webpack5に対応したやり方も自分で調べてまとめてみたいですね。

今までは、ファアイルを1つにまとめたりとか圧縮をしたことがなかったので、今後webpackを使ったサイト制作ができそうです。

というわけで
それでは!