LoginSignup
1
1

More than 3 years have passed since last update.

webpack5設定①

Last updated at Posted at 2021-06-14

はじめに

この記事はwebpackの導入未経験の筆者がYoutube動画【CodeMafia】プログラミング学習 フロントエンド開発(webpack編)の内容を参考に(動画内webpack4)をwebpack5で実装したことをまとめています。動画内の方が細かい説明もたくさんして下さってますのでぜひ見てみてください。
Babel7に関してはBabel 7 の主な変更点まとめも参考にさせていただきました。

開発環境

  • Visual Studio Code: v1.56.2
  • Node.js: 16.0.0
  • Webpack: v5.38.1
  • Babel: 7.14.5
  • yarn
  • npm

実装ソースコード

Webpackを導入

プロジェクトフォルダを作成してエディターで開たらまずpackage.json初期化

yarn init -y    

root直下にsrcフォルダを作成し、その中に

  • index.html
  • imagesフォルダ
  • app.js
  • sub.js

を作成する

次にwebpackを使えるようにする

yarn add webpack webpack webpack-cli --dev

root直下にwebpack.config.jsファイルを作成する

もしwebpack.example.jsというファイルで使用したい場合は下記のようにconfigオプションでフォルダを指定することで呼び出せる

yarn run webpack --mode development --config .\webpack.example.js

エントリーポイントの指定

webpack.config.js
module.exports = {
mode: "development",
  devtool: false,
  entry: "./src/app.js", 
// エントリーポイントが複数ある場合
// お互い依存関係がないファイルは並列に指定
// entry: ["./src/app.js", "./src/sub.js"]

// エントリーポイントも出力先も別で設定したい場合(本記事ではこちらで進めていきます)
   entry: {
    app: "./src/app.js",
    sub: "./src/sub.js",
  }
}

出力先の指定

webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: false,
  entry: "./src/app.js",
  output: {
    path: path.resolve(__dirname, "public"), // __dirnameは現在のディレクトリのパス、第二引数は作成されるフォルダ名
    filename: "bundle.js",
  },
};

出力先が複数ある場合は[name]という変数で指定する
(変数を指定するとentryで定義したkeyが割り振られる)

webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: false,
  entry: {
    app: "./src/app.js",
    sub: "./src/sub.js",
  },
  output: {
    path: path.resolve(__dirname, "public"), // __dirnameは現在のディレクトリのパス
    filename: "[name].js",
  },
};

これでpublicフォルダにapp.jsとsube.jsを作成されます

styleローダーの設定

loaderをインストール

yarn add --dev sass sass-loader css-loader style-loader

webpack.config.jsにloaderを設定

webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: false,
  entry: { app: "./src/app.js" },
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "[name].js",
  },
  module: { // ここから追加
    rules: [
      {
        test: /\.scss$/,
        use: [
          "style-loader", // loaderの記載は下から読まれるので各順番に注意
          "css-loader",
          "sass-loader",
        ],
      },
    ],
  },
};

ベンダープレフィックスの設定

postcss-loader autoprefixerを入れる

yarn add postcss-loader autoprefixer --dev

root直下にpostcss.config.jsファイル作成して以下を記入

postcss.config.js
module.exports = {
  plugins: [require("autoprefixer")],
};

webpack.config.jsにpostcss-loaderを追加

webpack.config.js
...省略  

  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          "style-loader",
          "css-loader",
          'postcss-loader',  // 追加
          "sass-loader",
        ],
 ...省略     

画像ローダー設定

file-loaderをインストール

yarn add file-loader --dev

webpack.config.jsにfile-loader設定
下記で使用している[name]の他に使える変数リスト

webpack.config.js
// ...省略
module: {
    rules: [
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
             // ここから
      {
        test: /\.(jpe?g|gif|png|svg|woff2?|ttf|ept)$/, // 使用する拡張子を全て記入。webfontも使用されている場合は記入する必要がある
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]", // [name]を変えることでpublicPahをhashにしたりできる
              outputPath: "images",
              publicPath: "images", // developer toolsのstyle などで表示されるurl
            },
          },
        ],
      },
      // ここまで
// ...省略

Babel設定

babelをインストール

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

webpack.config.jsにbabel-loader設定

webpack.config.js
// ...省略
  module: {
    rules: [
      // ここから
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/, // node_moduleは元からトランスパイルされているので除外
      },
             // ここまで
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
      },
// ...省略

root直下に.babelrcファイル作成して以下を記入(jsで書く場合はbabelrcファイルは作成しない)

.babelrc
{
    "presets": ["@babel/preset-env"]
}

.babelrcではなくjsファイルで書く場合(こっちの方が関数を使った複雑な設定ができる)
root直下にbabel.config.js作成

babel.config.js
module.exports = (api) => {
  api.cache(true);   // 設定しておくと2回目以降キャッシュが走ってビルド時間短縮できる

  return {
    presets: [
      [
        "@babel/preset-env",
        {
          targets: [                      // 対応させるブラウザの指定
            "last 1 version",          // 指定の仕方(https://github.com/browserslist/browserslist)
            "> 1%",
            "maintained node versions",
            "not dead",
          ],
        },
      ],
    ],
  };
};

トランスパイルを行う際に古いブラウザが持っていない機能を補う必要があるため以下のモジュール追加

yarn add core-js@3 regenerator-runtime

上記のモジュールは直接importして使うとファイルサイズが大きくパフォーマンスが悪くなるのでbabel.config.jsで以下のように設定

babel.config.js
module.exports = (api) => {
  api.cache(true);

  return {

    presets: [
      [
        "@babel/preset-env",
        {
          targets: [
            "last 1 version",
            "> 1%",
            "maintained node versions",
            "not dead",
          ],
          useBuiltIns: "usage", // 追加 regenerator-runtimeの必要な機能だけimportする
          corejs: { version: 3, proposals: true }, // 追加
        },
      ],
    ],
  };
};

Eslint設定

loaderをインストール
(以下、説明のためスクラッチで書いていくが yarn run eslint --init を使う方法もある)

yarn add eslint eslint-loader babel-eslint --dev

root直下に.eslintrc作成し以下を記入

.eslintrc
{
    "env": { // env設定ドキュメント(https://eslint.org/docs/user-guide/configuring/#specifying-environments)
        "browser": true,
        "es2017": true
    },
    "extends": "eslint:recommended", // recommendedはeslintがおすすめしているルールが自動で適用
    "parser": "babel-eslint",
    "parserOptions": {
        "sourceType": "module" // es6で導入されたmodule単位で管理
                               // defaltではscript管理になっている
    },
    "globals": {   // globalから使用されるpackageを記入
         "jQuery": "readonly",
                 "$": "readonly"
    },
    "rules": {
        // ここに記入したルールが優先される
        // ESLintルールリスト(https://eslint.org/docs/rules/)
    }
}

webpack.config.jsにloaderの設定

webpack.config.js
// ...省略
module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
      },
       // ここから追加
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, // lintに引っかかったところを自動でルールの形に整形する
        },
      },
      // ここまで
// ...省略

Pluginを使う

MiniCssExtractPluginを設定

MiniCssExtractPluginはjsファイルをバンドルする際にcssを分離して生成することで、変更がない場合はキャッシュを利用してくれる

MiniCssExtractPluginをinstall

yarn add mini-css-extract-plugin --dev

webpack.config.jsに追加

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 追加

module.exports = {
  mode: "development",
  devtool: false,
  entry: {
    app: "./src/app.js",
    sub: "./src/sub.js",
  },
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true,
        },
      },
      {
        test: /\.scss$/,
        use: [
          // "style-loader", <- 削除
          MiniCssExtractPlugin.loader, // 追加
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.(jpe?g|gif|png|svg|woff2?|ttf|ept)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              outputPath: "images",
              publicPath: "images",
            },
          },
        ],
      },
    ],
  },
  // ここから追加
  plugins: [
    new MiniCssExtractPlugin({
      filename: `[name].css`,
    }),
  ],
  // ここまで
};

HtmlWebpackPluginを設定

HtmlWebpackPluginはindex.htmlに自動でscriptタグをインジェクトする

html-webpack-pluginをinstall

yarn add html-webpack-plugin --dev

webpack.config.jsに追加

webpack.cofig.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 追加

// ...省略

  plugins: [
    new MiniCssExtractPlugin({
      filename: `[name].css`,
    }),
    // ここから追加
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      inject: "body",
    }),
    //ここまで
  ],
};

HTML内の画像を抽出する

html内の画像もバンドルするためにhtml-loaderを設定する
html-loaderは先ほど設定したHtmlWebpackPluginがないと機能しません。

loaderをinstall

yarn add --dev html-loader

webpack.config.jsにhtml-loader追加

webpack.config.js
// ...省略
        test: /\.(jpe?g|gif|png|svg|woff2?|ttf|ept)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              outputPath: "images",
              publicPath: "images",
            },
          },
        ],
      },
      // ここから追加
      {
        test: /\.html$/,
        use: ["html-loader"],
      },
      // ここまで
    ],
// ...省略

webpack5設定②に続く

1
1
0

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
1
1