LoginSignup
3
1

More than 1 year has passed since last update.

はじめてのWebpack設定 本番用 開発用

Last updated at Posted at 2021-04-14

はじめに

個人開発を作成した時に、webpack設定の学習も兼ねて組み込んでみました。
今回は、組み込んだ内容を中心に解説していきます。
バージョンはwebpack4.44.2を使用しました。

webpackとは

webpackとは、複数のJSファイルを一つのモジュールバンドラ(ファイル)にまとめることを指します。
JSファイルだけでなく、CSSや画像ファイルもモジュールバンドラにまとめることが出来ます。

https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS6Wwa5VeyiwF0GLUaAwYhVJJ_kF-XWRY4y7A&usqp=CAU

用途・メリット

  • 用途
     ・BabelでJavaScriptをトランスパイルできる
     ・CSSのコンパイル
     ・画像圧縮
     などなど、プラグインを使用することでパフォーマンスの最適化に繋がる。

  • メリット
     色々な参考記事をみて、僕の主観的なメリットとしては
     ・ファイルサイズが少ないことで、通信量や保守性が上がる。
     ・ライブラリの依存関係を解決して出力してくれる。
     ・不要なコードや無駄のファイルを圧縮して、ファイルサイズを軽くする。

reactvueなどのフレームワークを使用していると、コンポーネント毎のファイルが増えると思います。そのファイル数を、一まとめにし以上の用途やメリットがあげられるかと思います。

使用する上で気をつけたこと。。

今回は、本番用と開発用をwebpack-mergeで分けて作業しました。
また、作業する上で以下のインストールしたものを使用しました。

インストールしたもの

  • webpack v4.44.2
  • webpack-cli v3.3.12
      ∟webpackコマンドでwebpackを使用するため

  • webpack-dev-server v3.11.0
      ∟ブラウザに表示し、ファイルの変更を監視

  • weboack-merge v5.7.3
      ∟開発用と本番用に分けることができる

  • clean-webpack-plugin v3.0.0
      ∟不要なファイルを削除

  • html-webpack-plugin v4.5.0
      ∟自動でバンドルされたファイルをhtmlに読み込む(開発途中で変更された時に、自動でかえてくれる)

  • image-webpack-plugin v6.0.0
      ∟画像を圧縮

  • tester-webpack-plugin v4.2.3
      ∟console.logを本番用のバンドル時に削除

  • file-loader v6.1.1
      ∟画像(jpg,pngなど)を出力

  • style-loader v1.3.0
      ∟CSSを出力

  • css-loader v4.3.0
      ∟CSSをcommonJSに変換

  • ts-loader v7.0.5
      ∟TypeScriptをトランスコンパイル、また静的コード分析・ES2015以降の構文に変換

ディレクトの構成

簡単なディレクトリの構成が以下になります。

┣━ /build
┃    ┣━ /images
┃    ┣━ /js
┃    ┃   ┗━ bundle.js
┃    ┗━ index.html
┣━ /public
┃    ┗━ index.html
┣━ /src
┃    ┣━ index.html
┃    ┗━ index.tsx ------エントリーポイント
┃
┣━ package.json
┣━ package-lock.json
┣━ webpack.common.js 
┣━ webpack.dev.js
┗━ webpack.prov.js

package.jsonのscripts管理

--config webpack.[dev or prod].jsを指定する。また、webpack-dev-serverを使用する際は、webpack-dev-serverを書き込む

package.json
"scripts": {
    "start": "webpack-dev-server --config webpack.dev.js",
    "test": "jest",
    "build": "webpack --config webpack.prod.js"
  },

共通設定 webpack.common.js

本番用と開発用に共通するファイルをwebpack.common.jsとして作成します。

webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = () => {
  return {
    entry: {
      bundle: "./src/index.tsx", //エントリーポイント
    },
    output: {
      path: path.resolve(__dirname, "build"), // バンドルファイルの指定
      filename: "js/[name].js", // nameはentryで指定したファイル名を作成
    },
    resolve: {
      extensions: [".ts", ".js", ".tsx", ".jsx"], // コンパイルする言語指定
    },

    module: {
      rules: [
          test: /\.css$/i,
          use: [
            // cssを出力するローダー
            "style-loader",
            // css をcommonJSに変換するローダー
            "css-loader",
          ],
        },
        {
          test: /\.tsx?$/,
          loader: "ts-loader", // TSでトランスコンパイル
          include: path.resolve(__dirname, "src"),
          exclude: /node_module/,
        },
        {
          test: /\.(jpg|png)$/, // 画像(jpg or png)を出力するローダー
          use: [
            {
              loader: "file-loader",
              options: {
                name: "[name].[contenthash].[ext]",
                outputPath: "images",
                publicPath: "/images",
              },
            },
            "image-webpack-loader", //画像を圧縮
          ],
        },
      ],
    },
    devtool: "source-map",
    plugins: [
      new HtmlWebpackPlugin({ template: "./src/index.html" }),
      new CleanWebpackPlugin(),
    ],
    //パフォーマンスヒントの表示方法を構成する
    performance: { hints: false }, // 250kBを超えるアセットなので、perfomaneceを追加
  };
};


開発用 development

共通設定webpack.common.jsを使用ため、webpack-mergeを読み込む。
開発用なので、modedevelopmentを指定。

webpack.dev.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const path = require("path");

module.exports = merge(common(), {
  mode: "development",
  // webpack-dev-serverの設定
  devServer: { 
    open: true, // ブラウザに表示するためtrueへ 
    contentBase: path.resolve(__dirname, "public"), // publicディレクトリのサーバーを開く
    port: "9000", // サーバーのポート番号
    historyApiFallback: true,// 存在しないパスをリクエストされた場合に、404を返さずにファイルを戻す
  },
  devtool: "cheap-module-eval-source-map", // ビルドの速度とデバックの品質を保つ
});

devtoolのソースマップについては、様々な設定があり種類毎にビルドの速度やデバックに品質が異なります。
今回は無難に、cheap-module-eval-source-mapを使用しました!
ちなみに公式サイトはこちらです。

本番用 production

本番用なので、modepriductionを指定。

webpack.prod.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = merge(common(), {
  mode: "production",
  //terser-webpack-pluginの設定
  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false, //falseでライセンスコメントを抽出し削除。 trueだと抽出したファイルを生成する
        terserOptions: {
          compress: {
            drop_console: true, //trueでconsole.logの削除
          },
        },
      }),
    ],
  },
});

参考記事

技術記事https://zenn.dev/nozomi_iida/articles/a4c75f79b754e9
公式https://webpack.js.org/

感想

ポートフォリオを作成する中で一から開発環境を作成することに意識し、webpackの重要性と役割を勉強しながらポートフォリオに組込み、作成しました。開発における品質を高めてくれることを実感しましたし共同開発時にとても役立つと思いました。次はwebpack v5に挑戦してみたいです!

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