Webpack5-react スキャフォールディングをゼロから構築するための実装手順 (ソースコード付き)

Webpack5-react スキャフォールディングをゼロから構築するための実装手順 (ソースコード付き)

ウェブパック5

最近、ようやく会社の技術インフラに集中する時間とエネルギーができました。そこで、まずは会社の SaaS システムをマイクロフロントエンド モデルに変換し、歴史から残された問題のいくつかを解決しました。

そして、webpack5がリリースされてから随分経ったので、そろそろ本番環境で使ってみようかなと思います。また、マイクロフロントエンド、webpack5、viteの普及を業界に広めていきたいと思っています。私の以前の記事を読んでいない友人は、記事の最後で探してみてください。本当に乾物が多いです。

公式スタート

webpack5 にアップグレードした後、どのような変更がありましたか?

  • 永続キャッシュによるパフォーマンスの向上
  • より優れた永続キャッシュアルゴリズムとデフォルトの動作を採用する
  • Tree Shaking とコード生成を最適化してバンドル サイズを削減 (Node.js ポリフィルを削除)
  • Webプラットフォームの互換性を向上
  • Webpack4を実現するために、互換性のない変更による不合理な状態を解消する
  • 将来の機能に備えて、Webpack 5をできるだけ長く使い続けられるように、今すぐに破壊的な変更を導入するようにしてください。
  • モジュール連合の追加

建築ガイド

この記事を読むときに、より良い改善が得られるよう、弊社(深圳明源クラウド スペース)で作成したスキャフォールディングを使用して、ワンクリックでプロジェクト テンプレートを生成することをお勧めします。

テンプレートを生成する手順:

npm i ykj-cli -g 
ykj init webpack5 (ここでは一般的なプロジェクトテンプレートを選択してください)
cd webpack5
糸 
糸開発

構築を開始する

まず、新しいフォルダを作成し、yarnを使用してプロジェクトを初期化します。

mkdir webpack5-demo
cd webpack5-デモ
糸初期化webpack5-demo
...最後まで入力してください

webpack webpack-cli の最新バージョンをダウンロードします。

糸を追加 webpack@next webpack-cli@next -D

次にReact react-dom17バージョンライブラリをインストールします

[email protected] [email protected] --save を追加します

次に、React公式のホットアップデートで推奨されているライブラリをインストールします。

糸を追加して、反応リフレッシュ -D

less css スタイル タグ postcss およびその他のスタイル処理ライブラリをインストールします (mini-css-extract-plugin は @next バージョンをインストールする必要があります)

yarn less less-loader css-loader style-loader mini-css-extract-plugin@next -D を追加します

関連するBabel依存関係をインストールする

糸を [email protected] に追加します @babel/core@next babel-loader@next @babel/preset-env@next -D

babelにはどのような具体的な設定が必要ですか?私のテンプレートを参照することをお勧めします

依存する準備が完了したら、プロジェクトの構築を開始します

プロジェクトのルートディレクトリにconfigフォルダを作成し、webpack構成ファイルを配置します。
configフォルダに4つの新しいファイルを作成します

paths.js//ストレージパスwebpack.base.js //基本設定webpack.dev.js//開発設定webpack.prod.js//本番環境設定

パス ファイルでは、変数を使用していくつかの主要なディレクトリを記録します。

定数パス = require('path');

モジュール.エクスポート = {
    // ソースディレクトリ src: path.resolve(__dirname, '../src'),

    // 構築後のリソース製品フォルダ build: path.resolve(__dirname, '../dist'),

    // 静的リソース public: path.resolve(__dirname, '../public'),
};

基本的なwebpack.base.js設定ファイルを記述し、依存関係を導入する

//webpack.base.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
HtmlWebpackPlugin は 'html-webpack-plugin' を必要とします。
定数パス = require('path');
定数paths = require('./paths');

入力フィールドと出力フィールドを記述します。

 エントリ: paths.src + 'index.tsx'、
 出力: {
        パス: path.resolve(__dirname, '../dist'),
        ファイル名: '[名前].[コンテンツハッシュ].js',
        パブリックパス: ''、
    },

ここで注目すべきは、webpack5 が contenthash アルゴリズムを最適化していることです。ここでは chunkhash と contenthash を選択できます。contenthash が推奨されます。

基本的なローダー構成を記述します。

    モジュール: {
        ルール:
            {
                使用: 'babel-loader'、
                テスト: /\.(ts|tsx)$/,
                除外: /node_modules/、
            },
            {
                使用: ['style-loader', 'css-loader', 'less-loader'],
                テスト: /\.(css|less)$/,
            },
            {
                タイプ: '資産'、
                テスト: /\.(png|svg|jpg|jpeg|gif)$/i,
            },
        ]、
    },

ここで注目すべきは、webpack5 は url-loader や file-loader を使用せずに、組み込みのアセットを使用して画像やフォント ファイルなどのリソースを処理できることです。

次に、プロジェクトではエイリアスを設定し、サフィックスを省略する必要があるため、最初に解決フィールドを設定します (TypeScript + React テクノロジー スタックを使用しています)。

 解決する: {
        拡張子: ['.ts', '.tsx', '.js', '.json', '.jsx'],
        エイリアス: {
            '@': パス.src、
            '@c': paths.src + '/components',
            '@m': paths.src + '/model',
            '@s': paths.src + '/services',
            '@t': paths.src + '/types',
        },
    },

プラグインに関しては、基本的な構成なので、クリーンなHTMLプラグインのみが必要です。

  プラグイン: [
        新しい CleanWebpackPlugin()、
        新しいHtmlWebpackプラグイン({
            テンプレート: './public/index.html',
        })、
    ]、

プロジェクトのルートディレクトリに新しいファイルbabel.config.jsを作成します。

const { argv } = require('yargs');
const isDev = argv.mode === '開発';
const プラグイン = [
    [
        'const-enum'、
        {
            変換: 'constObject',
        },
    ]、
    「ロダッシュ」、
    '@babel/plugin-transform-runtime',
    //インポート遅延読み込み '@babel/plugin-syntax-dynamic-import' をサポート、
    '@babel/plugin-transform-async-to-generator',
    '変換クラスプロパティ'、
    [
        '輸入'、
        {
            ライブラリ名: 'antd',
            ライブラリディレクトリ: 'es',
            style: true、// または 'css'
        },
        'antd',
    ]、
    [
        '輸入'、
        {
            ライブラリ名: 'ykj-ui',
            ライブラリディレクトリ: 'lib/components',
            style: true、// または 'css'
        },
        'ykj-ui',
    ]、
];
モジュール.エクスポート = (api) => {
    api.cache(true);
    戻る {
        プリセット: [
            [
                '@babel/プリセット環境',
                {
                    コアjs: 3.9、
                    useBuiltIns: '使用法',
                },
            ]、
            [
                '@babel/プリセット-react',
                {
                    ランタイム: '自動'、
                },
            ]、
            '@babel/preset-typescript',
        ]、
        プラグイン: isDev ? [...プラグイン、'react-refresh/babel'] : [...プラグイン]、
    };
};

このようにして、基本的な webpack 構成が準備されました。まずは整理してみましょう。

  • babelを使用してtsx tsおよびesの高レベル構文を処理する
  • ローダーを使用して、より少ない構文を処理する
  • プラグインを使用してHTMLを処理し、クリーンアップする
  • 解決フィールドを使用してエイリアスを設定し、ファイルサフィックスを省略します
  • 組み込みアセットを使用して、画像などの静的ファイルを処理します。

webpack.dev.js開発構成を記述する

依存関係の導入

ReactRefreshWebpackPlugin は、react.js で定義されています。
const { HotModuleReplacementPlugin } = require('webpack');
const { merge } = require('webpack-merge');
'./webpack.base' というコンストラクタを require します。

まず、ホットアップデート、マージ構成、基本構成、公式Reactホットアップデート依存関係を紹介し、次に構成を記述します。

定数devConfig = {
    モード: '開発'、
    開発サーバー: {
        ポート: 3000、
        コンテンツベース: '../dist',
        オープン: 真、
        ホット:本当、
    },
    ターゲット: 'ウェブ'、
    プラグイン: [新しい HotModuleReplacementPlugin()、新しい ReactRefreshWebpackPlugin()]、
    開発ツール: 'eval-cheap-module-source-map',
};

module.exports = merge(common, devConfig);

注意: ホットアップデート効果を得るには、target: 'web' を設定する必要があります。

開発モードでのdevtoolのベストプラクティスは次のとおりです: eval-cheap-module-source-map

このようにして、開発モードの構成が設定されました。public フォルダーに index.html を書き込むだけで、以前と同じように react プロジェクトの作成を開始できます。

webpack.prod.jsの本番構成を書き始める

依存関係を導入する:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { merge } = require('webpack-merge');
'./webpack.base' というコンストラクタを require します。

本番環境では CSS タグを抽出する必要があるため、less と CSS に特別な処理が必要です。1 つはスタイルの互換性の問題を処理する postcss で、もう 1 つは MiniCssExtractPlugin.loader です。

const prodConfig = {
    モード: 'production'、
    開発ツール: '隠しソースマップ',
    モジュール: {
        ルール:
            {
                テスト: /\.(css|less)$/,
                使用: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader'],
            },
        ]、
    },
    最適化:
        分割チャンク: {
            チャンク: 'すべて'、
            名前: 偽,
        },
    },
    プラグイン: [新しい MiniCssExtractPlugin()],
};
module.exports = merge(common, prodConfig);

本番用の構成も記載されています。

実稼働環境の開発ツールのベストプラクティスは、hidden-source-mapです。

スクリプトコマンドの記述

"ビルド": "webpack --config config/webpack.prod.js --mode production",
"dev": "webpack serve --config config/webpack.dev.js --mode development",

注: ホット アップデートは以前は webpack-dev-server でしたが、現在は webpack serve です。

コード品質管理プロセスを構成する

依存関係の追加

糸を追加 lint-staged @commitlint/cli @commitlint/config-conventional -D

コードを書いてテストプロセスを提出する

 「ハスキー」:{
        「フック」: {
            「事前コミット」: 「lint ステージング」、
            "コミットメッセージ": "commitlint -E HUSKY_GIT_PARAMS"
        }
    },
    「lintステージング」: {
        "src/**/*.{js,jsx,ts,tsx,json,css,less,md}": [
            「よりきれいに --write」、
            "eslint --fix",
            「git 追加」
        ]
    },
    「ブラウザリスト」: [
        「つまり >= 10」、
        "ff >= 30",
        "クロム >= 34",
        "サファリ >= 8",
        「オペラ >= 23」
    ]
}

eslint 設定を追加します:

//.eslintrc.js
モジュール.エクスポート = {
    ルート: true、
    パーサーオプション: {
        ecmaバージョン: 7,
        ソースタイプ: 'モジュール',
    },
    パーサー: '@typescript-eslint/parser',
    プラグイン: ['typescript', 'react'],
    環境: {
        ブラウザ: true、
        ノード: true、
        es6: 本当、
    },
    ルール:
        semi: ['error', 'always'], // このルールは一貫したセミコロンを強制します 'no-unused-vars': 'off', // 未使用の変数を許可しません 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 本番環境でデバッガーを無効にします
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', //本番環境でコンソールを無効にする
        'default-case': ['warn', { commentPattern: '^no default$' }], // Switch ステートメントに Default が必要です
        'dot-location': ['warn', 'property'], // doteqeqeq の前または後に強制的に改行します: ['error', 'allow-null'], // === と !== を使用する必要があります
        'new-parens': 'warn', // 引数なしのコンストラクタを呼び出すときは括弧が必要 'no-caller': 'error', // 呼び出し元または呼び出し先を無効にする
        'no-const-assign': 'error', //const で宣言された変数の変更を禁止します'no-dupe-args': 'error', //関数定義内の重複パラメータを禁止します'no-dupe-class-members': 'error', //クラス メンバー内の重複名を禁止します'no-dupe-keys': 'warn', //オブジェクト リテラル内の重複キーを禁止します'no-extend-native': 'warn', //ネイティブ オブジェクトの拡張を禁止します'no-extra-bind': 'warn', //不必要な関数バインディングを禁止します'no-fallthrough': 'error', //case ステートメントのフォールスルーを禁止します'no-func-assign': 'warn', //関数宣言の再割り当てを禁止します'no-implied-eval': 'error', //暗黙の eval() を無効にします
        'no-label-var': 'error', //変数と同じ名前のラベルを無効にする 'no-loop-func': 'error', //ループ内の関数を無効にする 'no-mixed-operators': [
            「警告」、
            {
                グループ: [
                    ['&', '|', '^', '~', '<<', '>>', '>>>'],
                    ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
                    ['&&', '||'],
                    ['in', 'instanceof'],
                ]、
                allowSamePrecedence: false、
            },
        ], // 異なる演算子の混在使用を無効にする 'no-multi-str': 'warn', // 複数行の文字列を無効にする (複数行が必要な場合は \n を使用する)
        'no-native-reassign': 'warn', //ローカルオブジェクトの再割り当てを無効にする'no-obj-calls': 'warn', //グローバルオブジェクトの関数としての呼び出しを無効にする'no-redeclare': 'error', //変数の再宣言を無効にする'no-script-url': 'warn', //スクリプト URL を無効にする
        'no-shadow-restricted-names': 'warn', //キーワードはシャドウできません 'no-sparse-arrays': 'warn', //スパース配列を無効にします 'no-this-before-super': 'warn', //コンストラクタで super() を呼び出す前に this または super の使用を無効にします
        'no-undef': 'error', // 宣言されていない変数を無効にする 'no-unexpected-multiline': 'warn', // 紛らわしい複数行の式を無効にする 'no-use-before-define': [
            「警告」、
            {
                関数: false、
                クラス: false、
                変数: false、
            },
        ], //定義前の使用を無効にする'no-with': 'error', //ステートメントで無効にするradix: 'error', //関数内で yield のないジェネレーター関数を無効にする'rest-spread-spacing': ['warn', 'never'], //スプレッド演算子とその式の間のスペースの制限を適用する'react/jsx-no-undef': 'error', //JSX で宣言されていない変数を無効にする'react/no-direct-mutation-state': 'error', //this.state への直接変更を無効にする'react/jsx-uses-react': 'warn', //React が誤って未使用としてマークされるのを防ぐ'no-alert': 0, //アラート確認プロンプトの使用を無効にする
        'no-duplicate-case': 2, //switch 内の case ラベルは繰り返すことができません'no-eq-null': 2, //null に == または != 演算子を使用しないでください'no-inner-declarations': [2, 'functions'], //ブロック ステートメントで宣言 (変数または関数) を使用しないでください
        'no-iterator': 2, // __iterator__ 属性の使用を無効にします 'no-negated-in-lhs': 2, // in 演算子の左側には、! を含めることはできません。
        'no-octal-escape': 2, // 8進エスケープシーケンスの使用を無効にします 'no-plusplus': 0, // ++、-- の使用を無効にします
        'no-self-compare': 2, // 自分自身を比較することはできません 'no-undef-init': 2, // 初期化時に変数に undefined を直接割り当てることはできません
        'no-unused-expressions': 2, // 無駄な式を許可しない 'no-useless-call': 2, // 不要な呼び出しを許可しない
        'init-declarations': 0, // 宣言時に初期値を割り当てる必要があります 'prefer-const': 0, // const が優先されます
        'use-isnan': 2, //比較時に NaN の使用を無効にし、isNaN() のみを使用する
        'vars-on-top': 2, //var はスコープの先頭に配置する必要があります},
};

ユニットテスト

新しいコマンド:

"test": "jest", //テストを実行 "test-c": "jest --coverage" //テストレポートを生成

jest とその他の依存関係をインストールします。

yarn に jest-environment-enzyme と ts-jest@next の酵素、enzyme-adapter-react-17、enzyme-to-json を @types/enzyme と @types/enzyme-adapter-react-17 と @types/enzyme-to-json -D で追加します。 

新しいフォルダテストを作成する

最初の単体テストを記述し、依存関係を導入します。

'../src/App' から App をインポートします。
'enzyme' から { mount, shallow } をインポートします。
'react' から React をインポートします。
import toJson from 'enzyme-to-json'; //スナップショットを作成する

その後、ユニットテストの作成を安心して開始できます。

このようにして、webpack5 のスキャフォールディングが構築されます。webpack に組み込まれている機能の中には、多くの設定を省き、見た目をシンプルにしてくれるものもあります。

これで、Webpack5-react スキャフォールドをゼロから構築する実装手順 (ソースコード付き) に関するこの記事は終了です。Webpack5-react スキャフォールドに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • webpack4.0 を使用して単一/複数ページのスキャフォールドを構築する方法 (jquery、react、vue、typescript)
  • webpack4.X をベースに React スキャフォールディングをゼロから構築する方法と手順
  • Webpack+react+antd スキャフォールディング最適化方法

<<:  Windows Server 2019 のセットアップ方法 (画像とテキスト付き)

>>:  MySQL オンラインリカバリ UNDO テーブルスペース 実戦記録

推薦する

vue+element で動的スキニングを実装するためのサンプルコード

プロジェクトのテーマがすべての人の美的感覚を満足できないこともあります。このとき、スキン変更機能は非...

MySQL の行レベルロックの詳細な例

序文ロックは、複数のスレッドを実行するときにリソースへのアクセスを強制的に制限するために使用される同...

JavaScriptの動作メカニズムの詳細な説明とイベントループについての簡単な説明

目次1. JavaScript がシングルスレッドなのはなぜですか? 2. タスクキュー3. イベン...

Reactでコンポーネントロジックを共有する3つの方法

簡単に説明すると、これら 3 つの方法は、レンダリング プロップ、高階コンポーネント、カスタム フッ...

Vue のクロスドメイン問題の処理と解決策の概要

ネットワークリクエストを送信すると、次の保存情報が表示されます。おめでとうございます。ドメインを越え...

Tomcat プロセスの CPU 使用率が高い場合のトラブルシューティング記録を記録する

この記事では主にTomcatプロセスを記録し、TCP接続が多すぎることによるCPU使用率の過剰のトラ...

ウェブサイトに最も必要なのは、ターゲットユーザーグループのエクスペリエンスを向上させることです。

「大河は東に流れ、波は歴代の英雄たちを洗い流した。古城の西側は三国時代の周朗の赤壁だと言われている...

時点に基づくMySQLクイックリカバリソリューション

なぜこのような記事を書いたかというと、数日前の夜、仕事が終わろうとしていたときに、業務側で突然、テー...

WeChatアプレットはシンプルな手書き署名コンポーネントを実装します

目次背景:必要:効果1. アイデア2. 実装1. ページとスタイル2. 初期化3. クリックすると4...

Vue プロジェクトの最初の画面のパフォーマンス最適化コンポーネントの実践ガイド

目次Vue ファースト スクリーン パフォーマンス最適化コンポーネント説明するインターセクションオブ...

CSSで背景ぼかしを設定する方法

ページを作成するときに、ページの見栄えを良くするために、背景画像を設定する必要があることがよくありま...

nginx で同時接続リクエストの数を制限する方法

導入同時接続数を制限するモジュールは http_limit_conn_module です。アドレス:...

K8S クラスターを構築し、Hyper-V で Docker をインストールする方法

Win10 システムをインストールしていて、k8s クラスターを構築する場合、Win10 に付属する...

n 個のコンテナ要素による無限スクロールの実装コード

シナリオ最大 10000 要素のリストを正しくレンダリングする方法。無限ドロップダウン読み込みテクノ...

MySQL マスタースレーブ同期、トランザクションロールバックの実装原理

ビンログBinLog は、データベース テーブル構造の変更 (テーブルの作成、変更など) とテーブル...