🐡

Webpack5でFontAwesome-freeを利用する

2021/03/14に公開

備忘録かねて、環境構築のたびに少し引っかかるので書きます。

前提

この記事の内容は下記環境で試しています。

webpack: 5.24.4
webpack-cli: 4.5.0
node: 14.15.1
npm: 6.14.8

npmでインストールする

npmでFontAwesomeをインストールし利用するためには、下記3つの手順を踏みます。

  1. npm installする
  2. エントリーポイントとなるFontAwesome-freeのパッケージ+jsファイルに必要なweight分のパッケージをimportする
  3. 使用する箇所でCDNでの利用と同じように使う

1. npm installする [Doc]

terminal
npm install --save @fortawesome/fontawesome-free

2. エントリーポイントとなるjsファイルにFontAwesome-freeのパッケージ+必要なモジュールをimportする

src/index.js
import '@fortawesome/fontawesome-free/js/fontawesome';
import '@fortawesome/fontawesome-free/js/solid';
import '@fortawesome/fontawesome-free/js/regular';

こちらのサイトを参考にさせていただきました。

3. 使用する箇所でCDNでの利用と同じように使う

index.ejs
<a href="#" class="c-like-button"><i class="fas fa-heart"></i></a>

つまずいた箇所

上記手順で使おうとしたところ、下記のエラー文が出て使用したいアイコンが表示されない事態に…。

terminal
Uncaught TypeError: Cannot read property 'locals' of undefined

その時のpackage.jsonとwebpack.config.jsはこんな感じ。

package.json
...
"devDependencies": {
    "@babel/core": "^7.13.8",
    "@babel/preset-env": "^7.13.9",
    "babel-loader": "^8.2.2",
    "core-js": "^3.9.1",
    "css-loader": "^5.1.1",
    "ejs-plain-loader": "^1.4.1",
    "html-loader": "^2.1.1",
    "html-webpack-plugin": "^5.3.0",
    "mini-css-extract-plugin": "^1.3.9",
    "regenerator-runtime": "^0.13.7",
    "resolve-url-loader": "^3.1.2",
    "sass": "^1.32.8",
    "sass-loader": "^11.0.1",
    "style-loader": "^2.0.0",
    "vue-loader": "^15.9.6",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.15.2"
  }
...
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
...

module.exports = {
  entry: "./src/index.js",
  ...
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          "vue-style-loader",
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              esModule: false,
            },
          },
        ],
      },
      ...
    ],
  },
  plugins: [
    ...
    new MiniCssExtractPlugin({
      filename: "style.css",
    }),
  ],
...

調べると、 MiniCSSExtractPlugin が関係しているようでした。
参考にした記事はこちら
ローディングの際のoptionを下記のように修正したところ、無事表示されました!

webpack.config.js
...
{
    loader: MiniCssExtractPlugin.loader,
    options: {
      esModule: false,
    },
  },
...

このoptionは、ローダーが読み込む際にES Module構文で処理するかどうかを設定しているもので、デフォルトでtrueが設定されているとのこと。
これをfalseにすることで、CommonJSの構文で利用可能になるということかと理解しました。

この辺りの知識が浅いですが、何か間違っていたらご指摘いただけたら嬉しいです。

Discussion