制御の維持:WebpackとReactのガイド、Pt。 2

公開: 2022-03-11

このReact-Webpackチュートリアルの最初の部分では、ローダーを構成して最適化を実行する方法について説明しました。 次に、特定のReact/Webpack構成のユースケースに関連するより高度な手法について説明します。

TypeScriptとReactwithWebpack:Babelを入力してください

ReactプロジェクトでTypeScriptを使用する方法はいくつかあります。 ts-loaderは良いオプションですが、多くのライブラリがコンパイル時の最適化を実行するためにBabelプラグインを公開しているため、 @babel/preset-typescriptを使用してTypeScriptをトランスパイルする方法に焦点を当てたいと思います。 TypeScriptファイルの処理に加えて、styled-componentsやreact-intlなどのさまざまなライブラリによって提供されるBabelプラグインを使用できるようになります。

最初に行う必要があるのは、TypeScriptとBabelの依存関係をインストールすることです。

 npm install -D typescript @babel/preset-typescript @types/react @types/react-dom

次に、コマンドラインプログラムtscを使用してTypeScript構成ファイルを生成します。

 ./node_modules/.bin/tsc -init --lib dom --jsx react --isolatedModules

上記のコマンドは、ブラウザ環境のコードを記述するのに適したtsconfig.jsonを生成します。 --isolatedModulesオプションは、作成するコードが@babel/plugin-transform-typescriptと互換性があることを確認するいくつかの制約を適用します。 このオプションは、Babelが変換できない方法でコードを記述しているときにIDEが警告するために用意しておくと便利です。

次に、新しいプリセットを導入して、 babel.config.jsを更新します。

 @@ -6,7 +6,8 @@ module.exports = { modules: false } ], - "@babel/preset-react" + "@babel/preset-react", + "@babel/preset-typescript" ], plugins: [ "@babel/plugin-transform-runtime",

そして、 webpack.config.js.tsファイル拡張子を有効にします。

 @@ -11,7 +11,7 @@ module.exports = function(_env, argv) { return { devtool: isDevelopment && "cheap-module-source-map", - entry: "./src/index.js", + entry: "./src/index.tsx", output: { path: path.resolve(__dirname, "dist"), filename: "assets/js/[name].[contenthash:8].js", @@ -20,7 +20,7 @@ module.exports = function(_env, argv) { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", @@ -61,6 +61,9 @@ module.exports = function(_env, argv) { } ] }, + resolve: { + extensions: [".js", ".jsx", ".ts", ".tsx"] + }, plugins: [ isProduction && new MiniCssExtractPlugin({

上記の構成は、コードをトランスパイルするのに十分ですが、実際には検証されません。 fork-ts-checker-webpack-pluginを使用して、別の並列プロセスで型チェックを実行する必要があります。

まず、それをインストールする必要があります:

 npm install -D fork-ts-checker-webpack-plugin

次に、それをwebpack.config.jspluginsセクションに追加します。

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -78,6 +79,9 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new ForkTsCheckerWebpackPlugin({ + async: false }) ].filter(Boolean), optimization: {

async: falseを指定すると、Webpackが無効なコードを発行するのを防ぎ、開発サーバーの実行時にオーバーレイにコンパイルエラーを表示します。

注:注目を集めているバベルマクロにも興味があるかもしれません。

CSS、Webpackを介して拡張

前回の記事では、 css-loaderを使用した基本的なスタイリングについて説明しました。 この構成を改善する方法はいくつかあります。

提案された構成は、CSSモジュール、Sass、およびPostCSSテクノロジーを利用します。 それらはいくつかの点で互いに補完し合っていますが、それらすべてを同時に使用する必要はありません。 最終的なセットアップでは、上記のすべてのプラグインが有効になります。「必要ない」と確信できる場合は、何かを除外するのはあなたに任せます。

CSSモジュール

CSSモジュールは、CSSクラスごとにランダム化された一意の名前を生成することにより、CSSファイルのグローバルスコープの問題に対処します。 CSSモジュールを使用するJavaScriptファイルの観点から、元のクラス名とランダム化されたクラス名の間の関連付けは、ローダーによってエクスポートされたオブジェクトによって表されます。 偶発的な衝突をほとんど不可能にする方法で、CSSファイルで指定されたクラスを見つけて使用することができます。

CSSモジュールのサポートはすでにcss-loaderに含まれています。 次に、CSSモジュールがいつ使用されているかを明示するために、新しいルールを追加する必要があります。

 @@ -33,11 +33,25 @@ module.exports = function(_env, argv) { }, { test: /\.css$/, use: [ isProduction ? MiniCssExtractPlugin.loader : "style-loader", "css-loader" ] }, + { + test: /\.module.css$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + modules: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

これにより、 .module.cssで終わるファイルは、CSSモジュールを有効にして処理されます。

PostCSS

PostCSSは、CSS構文の拡張、最適化の実行、または古いブラウザーへのフォールバックの提供に使用できるプラグインの膨大なライブラリーを備えた拡張可能なCSS処理フレームワークです。

まず、必要な依存関係をインストールします。

 npm install -D postcss-loader postcss-import postcss-preset-env

そして、CSS構成を更新します。

 @@ -47,9 +47,11 @@ module.exports = function(_env, argv) { { loader: "css-loader", options: { - modules: true + modules: true, + importLoaders: 1 } - } + }, + "postcss-loader" ] }, {

次のプラグインを使用してPostCSSを構成します。

  • postcss-import :PostCSSが@importステートメントを処理できるようにします
  • postcss-preset-env :ほとんどのブラウザで最新のCSS機能をサポートするためにポリフィルを適用します

postcss.config.jsというファイルを作成し、次のファイルを入力します。

 module.exports = { plugins: { "postcss-import": {}, "postcss-preset-env": {} } };

PostCSSプラグインディレクトリで、役立つと思われる他の拡張機能を確認して、構成に追加できます。

Sass / SCSS

Sassはもう1つの人気のあるCSS処理フレームワークです。 PostCSSとは異なり、Sassには「バッテリーが含まれています」が付属しています。 箱から出して、Sassは、下位互換性のためにネストされたルール、ミックスイン、および書き換えルールのサポートを提供します。 PostCSSは標準のCSS構文を維持することを目的としていますが、Sass構文はCSS仕様とは異なる場合があります。 それにもかかわらず、Sassは非常にユビキタスなソリューションであるため、CSSのオーサリングにSassを使用する方が簡単なオプションかもしれませんが、要件によって異なります。

まず、必要な依存関係をインストールします。

 npm install -D sass-loader node-sass resolve-url-loader

次に、新しいローダーをWebpack構成に追加します。

 @@ -38,6 +38,25 @@ module.exports = function(_env, argv) { "css-loader" ] }, + { + test: /\.s[ac]ss$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2 + } + }, + "resolve-url-loader", + { + loader: "sass-loader", + options: { + sourceMap: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

上記のスニペットでいくつかの問題に先制的に対処しました。

  1. @import ed Sassファイルからの相対インポートを機能させるために、 sass-loader loaderの後にresolve-url-loaderを導入しました。

  2. css-loaderimportLoadersオプションを指定して、後続のローダーを使用して@import import-edファイルを処理します。

上記の構成では、前に説明したPostCSSおよびCSSモジュールに加えて、Sass/SCSSを使用してスタイルの作成を開始できます。 これらのオプションはすべて同時に有効にすることができますが、同じプロジェクト内ですべてを使用する必要はないため、要件に最適な1つのツールを選択できます。

Webワーカー

Webワーカーは、最新のWebの強力な概念です。 これにより、高価な計算をメインスレッドからオフロードできます。 Webワーカーは慎重に使用し、イベントループ内のインテリジェントなスケジューリングでは最適化できないもののために予約する必要があります。 Webワーカーを使用することは、長い同期操作を最適化するための良い候補です。

Webpackを使用すると、 worker-loaderを使用してWebワーカーを簡単に使用できます。worker-loaderは、ワーカーファイルを出力ディレクトリにバンドルし、コンシューマーファイルにワーカークラスを提供します。

まず、 worker-loaderをインストールする必要があります:

 npm install -D worker-loader

次に、それを構成ファイルに追加します。

 @@ -31,6 +31,10 @@ module.exports = function(_env, argv) { } } }, + { + test: /\.worker\.js$/, + loader: "worker-loader" + }, { test: /\.css$/, use: [

これで、Webワーカーの使用を開始するために必要なのは、通常のワーカーAPIを実装する.worker.jsで終わるファイルからインポートされたクラスをインスタンス化することだけです。

サービスワーカー

サービスワーカーは、高度な最適化手法とユーザーエクスペリエンスの向上を可能にします。 ユーザーがネットワーク接続を失ったときに、アプリをオフラインで動作させることができます。 また、アップデートをプッシュした後でも、アプリを瞬時に読み込むことができます。

Webpackを使用すると、workbox-webpack-pluginモジュールを使用してアプリのServiceWorkerを簡単に構成できます。 まず、それをインストールする必要があります:

 npm install -D workbox-webpack-plugin

次に、プラグインをWebpack構成のpluginsセクションに追加します。

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const WorkboxPlugin = require("workbox-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -75,6 +76,11 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new WorkboxPlugin.GenerateSW({ + swDest: "service-worker.js", + clientsClaim: true, + skipWaiting: true }) ].filter(Boolean), optimization: {

上記の構成では、次のオプションを使用します。

  • swDestは、生成されたワーカーファイルの出力ファイル名を指定します。
  • clientsClaimは、登録直後にページを制御し、次のページのリロードを待つのではなく、キャッシュされたリソースの提供を開始するようにServiceWorkerに指示します。
  • skipWaitingは、すべてのアクティブなインスタンスが破棄されるのを待つのではなく、ServiceWorkerの更新をすぐに有効にします。

後者の2つのオプションがデフォルトではないのには十分な理由があります。 同時に有効にすると、時間に敏感な状況でグリッチが発生する可能性があるため、構成でこれらのオプションを有効にしておくかどうかを意識的に決定する必要があります。

最後に、ユーザーがアプリを開いたときにServiceWorkerを登録する必要があります。

 @@ -2,3 +2,9 @@ import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<h3>React App</h3>, document.getElementById("root")); + +if ("serviceWorker" in navigator) { + window.addEventListener("load", () => { + navigator.serviceWorker.register("/service-worker.js"); + }); +}

サービスワーカーは、アプリにオフライン機能を追加する以上のことができます。 Service Workerの動作をより高度に制御する必要がある場合は、代わりにInjectManifestプラグインを使用できます。 独自のServiceWorkerファイルを作成することで、APIリクエストのキャッシュを有効にしたり、プッシュ通知などのServiceWorkerによって有効にされた他の機能を使用したりすることもできます。 Workboxの機能の詳細については、公式ドキュメントの「高度なレシピ」セクションを参照してください。

Advanced React Webpack Config:プロジェクトに優位性を与える

Webpackチュートリアルシリーズのこの第2部では、最も一般的なReactのユースケースを超えてWebpack構成を拡張するために必要な知識を身に付ける必要があります。 この情報がお役に立てば幸いです。また、プロジェクトに固有の目標を達成するために、パーソナライズされた構成を自信を持って拡張できることを願っています。

いつものように、GitHubで完全な構成ファイルを見つけることができ、Webpackのドキュメントとそのプラグインのセクションを参照して、目標に適用できるその他のレシピを見つけることができます。 読んでくれてありがとう!