1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React18がリリースされたので、開発環境をゼロから構築してみる。【中編】

Last updated at Posted at 2022-04-13

前編からの続きです。

なぜWebpack設定ファイルを分割するのか?

webpackは、「JavaScript」「CSS」「SASS」「画像」などを

  • 1つ、または、複数のファイルにまとめる。
  • 出力されたファイルを圧縮・難読化する。

などの機能があります。

設定ファイルが複数あれば、

開発時にはJavaScript、CSSはソースマップ付きで読みやすく、リリースビルド時には、圧縮しファイルサイズを小さくする。

開発時には、圧縮関連のプラグインを読み込まずコンパイル時間を短くする。

など、開発時、リリースビルド時で設定を柔軟に変更することができます。

Webpack設定ファイルの分割

今回は、webpack.config.jsを

  • 共用
  • 開発版
  • リリース版

の3つに分割し、開発時は、

共用版 + 開発版

リリースビルド時は、

共用版 + リリース版

を使うようにします。

コマンドラインで作成された「webpack.config.js」は以下の通りです。

それに加え、前編で、リリースビルド用に

  • リリースビルド時に、console関数を除去するためのプラグイン
  • CSS圧縮プラグイン

を導入しました。

// Generated using webpack-cli https://github.com/webpack/webpack-cli

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const isProduction = process.env.NODE_ENV == "production";

const stylesHandler = MiniCssExtractPlugin.loader;

const config = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "public"),
  },
  devServer: {
    open: true,
    host: "localhost",
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "src/index.html",
    }),

    new MiniCssExtractPlugin(),

    // Add your plugins here
    // Learn more about plugins from https://webpack.js.org/configuration/plugins/
  ],
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/i,
        loader: "ts-loader",
        exclude: ["/node_modules/"],
      },
      {
        test: /\.css$/i,
        use: [stylesHandler, "css-loader"],
      },
      {
        test: /\.s[ac]ss$/i,
        use: [stylesHandler, "css-loader", "sass-loader"],
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
        type: "asset",
      },

      // Add your rules for custom modules here
      // Learn more about loaders from https://webpack.js.org/loaders/
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
};

module.exports = () => {
  if (isProduction) {
    config.mode = "production";
  } else {
    config.mode = "development";
  }
  return config;
};

webpack.config.jsを分割する準備

まずは、上記ファルをコピーし

  • webpack.config.common.js ---共用
  • webpack.config.dev.js --- 開発用
  • webpack.config.prod.js --- リリースビルド用

の3つのファイルを作成します。

共用部分

開発時、リリースビルド時に共通して必要なものは、

  • entryポイント
  • output
  • 出力先にindex.htmlファイルを作成するHtmlWebpackPlugin
  • モジュール部分から、cssとs[ac]ss部分以外
  • resolve

です。

モジュール部分の「css」「s[ac]ss」部分は、開発時とリリースビルド時で読み込むモジュールが違うため共通部分から削除し「webpack.config.dev.js」「webpack.config.prod.js」で使用します。

作成した「webpack.config.common.js」から不要な部分を削除したものです。

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "public"),
    assetModuleFilename: 'image/[name][ext][query]',
    clean: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/i,
        loader: "ts-loader",
        exclude: ["/node_modules/"],
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
        type: "asset",
      },

      // Add your rules for custom modules here
      // Learn more about loaders from https://webpack.js.org/loaders/
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
};

開発用

開発用には、先ほどのcssモジュール部でのcss関連、開発用サーバーのdevServer関連が共通部分に追加されます。

devServerは通常の「--open」コマンドだと規定のブラウザが開くため、Google Chromeが開くようにします。

Google Chromeは、OSにより記述がことなるためOS判定部分も追加しています。

共通部分にあるものを削除し、必要な部分を追加したものが以下となります。

const { merge } = require('webpack-merge');
const common = require('./webpack.config.common');
const os = require('os');

let devBrowser = 'Google Chrome';
switch (os.platform()) {
  case 'win32':
    devBrowser = 'chrome';
    break;
  case 'linux':
    devBrowser = 'google-chrome';
    break;
  default:
    break;
}

module.exports = merge(common, {
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.s[ac]ss$/i,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
  devtool: 'eval-source-map',
  devServer: {
    open: {
      app: {
        name: devBrowser,
      },
    },
    host: 'localhost',
    port: 3000,
    static: './public',
  },
});

リリースビルド用

リリースビルド用には、css関連を圧縮するモジュール、console関数を除去するプラグインをしようするようにしています。

const { merge } = require('webpack-merge');
const common = require('./webpack.config.common');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  plugins: [new MiniCssExtractPlugin(), new CssMinimizerPlugin()],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
      {
        test: /\.s[ac]ss$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        minify: TerserPlugin.uglifyJsMinify,
        terserOptions: {
          compress: {
            drop_console: true,
          },
        },
      }),
      new CssMinimizerPlugin(),
    ],
  },
});

テスト

webpackの設定ファイルをテストします。

開発用

npx webpack configtest ./webpack.config.dev.js
[webpack-cli] Validate '/Users/yaruo_react_redux/zero-start-react18/webpack.config.dev.js'.
[webpack-cli] There are no validation errors in the given webpack configuration.

リリースビルド用

npx webpack configtest ./webpack.config.prod.js
[webpack-cli] Validate '/Users/yaruo-react-redux/zero-start-react18/webpack.config.prod.js'.
[webpack-cli] There are no validation errors in the given webpack configuration.

スクリプト追加

package.jsonの「script」へ以下を追加します。

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.prod.js",
    "build:dev": "webpack --config webpack.config.dev.js",
    "build:prod": "webpack --config webpack.config.prod.js",
    "start": "webpack serve --config webpack.config.dev.js"
  },

Google Chromeで開くかを確認します。

npm run start

以上で、webpack設定ファイルを分割することができました。

ここまでの内容は、以下から取得できます。

git clone -b 04_webpack-config-split https://github.com/yaruo-react-redux/yaruo-start-template-react18.git

また、詳しく解説しているものは、こちらです。

←前編     後編→

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?