webpackが静的リソースキャッシュを実装する方法

webpackが静的リソースキャッシュを実装する方法

導入

静的リソースのキャッシュはフロントエンドのパフォーマンス最適化のポイントであるため、フロントエンドの開発プロセスでは、キャッシュが最大限に利用されるのが一般的です (ここでは主に強力なキャッシュ)。この記事の話題に戻りますが、webpack でビルドされたプロジェクトでは、注意しないと、サーバーがキャッシュ戦略を設定しても、ビルドされたプロジェクトで静的リソースのキャッシュを実現できない可能性があります。では、webpack はキャッシュを使用する効果をどのように実現できるのでしょうか? この問題については以下で説明します。

複数の異なるハッシュを区別する

私たちは皆、webpack には各プロジェクトのビルドhash 、さまざまなエントリのchunkhash 、ファイル コンテンツのcontenthashなど、さまざまなハッシュ値があることを知っています。これほど多くのハッシュがある場合、それらの違いは何でしょうか?

ハッシュ

ハッシュは、webpack ビルド プロジェクト全体に関連しています。プロジェクト ファイルが「変更」されていない場合でも、ハッシュに対応する値はプロジェクトがビルドされるたびに異なります。

実際、これは変更されており、webpack がパッケージ化されてコンパイルされるたびに、webpack ランタイム コードが挿入され、プロジェクト全体に変更が加えられるため、ハッシュ値が毎回変更されます。

私のプロジェクト コードを例に、変更を加えずに 2 回のビルドを行う前と後のコードの比較を示します。

対応するプロジェクト ビルドのハッシュが 2 回変更されたことがわかります。ハッシュが毎回変わるため、この方法ではキャッシュを実現できないと推測できます。

チャンクハッシュ

Chunkhash は、その名前が示すように、webpack によってパッケージ化されたチャンクに関連しています。具体的には、webpack はエントリ構成ファイルの依存関係を分析し、それに基づいてエントリのチャンクを構築し、対応するハッシュ値を生成します。チャンクが異なればハッシュ値も異なります。通常、プロジェクトでは、パブリック依存ライブラリとプログラムエントリファイルを分離して別々にパッケージ化し、チャンクハッシュを使用してハッシュ値を生成します。パブリック依存ライブラリが変更されない限り、対応するチャンクハッシュは変更されないため、キャッシュの目的が達成されます。

通常、chunkhash はプロジェクトの webpack エントリに使用され、出力構成項目に具体的に反映されます。

モジュール.エクスポート = {
  エントリー: {
   アプリ: './src/main.js',
   ベンダー: ['react'、'redux'、'react-dom'、'react-redux'、'react-router-redux']
  },
  出力: {
    パス:path.join(__dirname, '/dist/js'),
    ファイル名: '[name].[chunkhash].js'
  }
 ...
}

最後に、アプリとベンダーのチャンクハッシュコンパイル結果は次のとおりです。

コンテンツハッシュ

Contenthash は、ファイル コンテンツによって生成されたハッシュ値を表します。コンテンツが異なると、異なる contenthash 値が生成されます。プロジェクトでは、プロジェクト内の CSS を参照用の対応する CSS ファイルに抽出するのが一般的です。たとえば、次のように webpack 構成で使用します。

モジュール.エクスポート = {
  ...
  プラグイン: [
     新しいExtractTextPlugin({
	ファイル名: 'static/[name]_[chunkhash:7].css',
	無効: false、
	すべてのチャンク: true
     })
  ...
  ]

上記の構成では、chunkhash が使用され、それに依存するチャンクと chunkhash が共有されるため、問題が発生します。

たとえば、上記のアプリ チャンクの例では、index.css ファイルに依存しています。index.css のハッシュは、アプリのチャンクハッシュに従います。アプリ ファイルが変更される限り、index.css ファイルが変更されなくても、そのハッシュ値も変更され、キャッシュが失敗します。

次に、extra-text-webpack-plugin のcontenthash値を使用して、CSS ファイルが配置されているモジュール内の他のファイルの内容が変更された場合でも、CSS ファイルの内容が変更されない限り、そのハッシュ値は変更されないことを保証できます。

js キャッシュの実装

webpack プラグインCommonsChunkPluginの主な機能は、webpack プロジェクト エントリ チャンクの共通部分を抽出することです。具体的な使用方法については詳しく説明しません。よくわからない場合は、webpack 公式サイトの紹介を参照してください。

このプラグインは、Webpack プロジェクトでよく使用される最適化機能であり、ほぼすべての Webpack プロジェクトで使用されます。このプラグインを使用する利点:

  • webpack のパッケージ化速度とプロジェクト サイズの改善: webpack エントリのチャンク ファイルからすべての共通コードを抽出してコード サイズを削減し、同時に webpack のパッケージ化速度を改善します。
  • キャッシュ メカニズムを活用する: 依存するパブリック モジュール ファイルは通常、ほとんど変更されないか、まったく変更されないため、独立したモジュール ファイルを抽出して長期間キャッシュすることができます。

ただし、プロジェクトでプラグインが誤って開かれると、上記の 2 番目のポイントは達成できません。その理由は次のとおりです。

変更されていないパブリック コードまたはライブラリ コードにパッケージ化されたエントリ チャンクは、他のビジネス コードの変更によって変更され、ページ上のロング キャッシュ メカニズムが失敗する原因になります。

それでは、 CommonsChunkPlugin正しく開きましょう。

CommonsChunkPlugin の誤った使用法

react、react-dom、react-router などのプロジェクトの共通ライブラリをビジネス コードから分離し、ベンダー チャンクとして抽出すると、webpack 構成は次のようになります。

webpack は、次のコードで定義されます。
定数パス = require('path');
モジュール.エクスポート = {
  エントリー: {
    アプリ: "./src/main.js",
    ベンダー: ["react","re​​act-dom", "redux", "react-redux", "react-router-redux"]
  },
  出力: {
    パス: path.resolve(__dirname, 'output'),
    ファイル名: "[name].[chunkhash].js"
  },
  プラグイン: [
    新しい webpack.optimize.CommonsChunkPlugin({names: ["vendor"]})
  ]
};

上記では、プロジェクトのいくつかの基本ライブラリが vendor と呼ばれるチャンクにパッケージ化され、ビジネス関連のコードは app と呼ばれるチャンクにパッケージ化されています。

webpack のパッケージ化とコンパイルの結果は次のとおりです。

ビジネス コード app.js を変更した後、再コンパイルの結果は次のようになります。

CommonsChunkPlugin の設定では、ビジネス コード アプリが変更されると、ライブラリ コードも変更され、ベンダーのチャンクハッシュも変更されることがわかります。このように、ベンダーの参照の名前が変更され、ブラウザー上のロング キャッシュ メカニズムが失敗する原因になります。

問題の原因

webpack がコンパイルされるたびにベンダーが変わる理由:

Webpack はビルドするたびにランタイム コードを生成します。ファイルが 1 つしかない場合は、ランタイム コードがそのファイルに直接詰め込まれます。ファイルが複数ある場合、ランタイム コードは共通ファイル、つまり上記の CommonsChunkPlugin によって構成されたベンダー チャンクに抽出されます。

グローバル webpackJsonp メソッドの定義やモジュール依存関係の維持など、コンパイルのたびに webpack によって生成されるランタイム コードについては、こちら >> を参照してください。

したがって、上記の webpack の CommonsChunkPlugin 構成では、これらのコードはコンパイルされるたびにベンダーにパッケージ化され、ベンダーのチャンクハッシュが毎回変更されることになります。

次に、ベンダー チャンクを構成して共通コード、つまり webpack ランタイム コードを抽出し、プロジェクトが依存する基本ライブラリ モジュールをビジネス モジュールから分離できるようにします。これらのファイルは変更されないため、これらのファイルはロング キャッシュの効果を実現できます。具体的な構成は以下のとおりです。

モジュール.エクスポート = {
  エントリー: {
    アプリ: "./app.js",
    ベンダー: ["react","re​​act-dom", "redux", "react-redux", "react-router-redux"]
  },
  ....
  プラグイン: [
    新しい webpack.optimize.CommonsChunkPlugin({names: ["vendor"]})、
    新しい webpack.optimize.CommonsChunkPlugin({
        名前: 'マニフェスト',
        チャンク: ['ベンダー']
    })
  ]
};

この方法では、業務アプリのコードが変更されても、プロジェクトが依存する基本ライブラリのベンダー チャンクは変更されません。抽出されたマニフェスト チャンクのみが毎回変更されますが、このファイルのサイズは非常に小さく、この方法はベンダーよりも大きなメリットがあります。以下のように表示されます。

アプリコードを変更した後のパッケージコンパイル結果は以下のようになります。ベンダーチャンクハッシュは変更されていないことがわかります。

webpack で CommonsChunkPlugin を設定する際に注意すべき点がいくつかあります。

1. webpack の出力項目を設定する場合、そのfilenamechunkFilenameは chunkhash を使用する必要があります。ハッシュを使用しないでください。そうしないと、上記の構成でも期待される効果が得られません。ハッシュとチャンクハッシュの違いについては、githubの回答を参照してください。

2. 画像やフォントなどの静的リソースを抽出するために使用されるfile-loaderの場合、構成されたハッシュは静的ファイルのコンテンツハッシュ値を表します。パッケージ化およびコンパイルされるたびに webpack によって生成されるハッシュ値ではありません。覚えておいてください。 ! !

3. 抽出された CSS スタイル ファイルには、 file-loaderの hash と同じ意味を持つcontenthashを使用する必要があります。これはチャンクハッシュにすることはできません。そうしないと、スタイル ファイルが抽出されるエントリ チャンクのチャンクハッシュと一致してしまい、キャッシュの目的が達成されません。

CSSキャッシュの実装

Webpack は、上で紹介した contenthash を使用して CSS キャッシュを実装します。hash 属性値は、実際にはextra-text-webpack-pluginによって計算されます。 CSSキャッシュを実装するには、次のようにcontenthashを使用します。

モジュール.エクスポート = {
  ...
  プラグイン: [
     新しいExtractTextPlugin({
	ファイル名: 'static/[name]_[contenthash:7].css',
	無効: false、
	すべてのチャンク: true
     })
  ...
  ]

画像/フォントのキャッシュを実装する

画像やフォントなどの静的リソースの場合、webpack を使用してビルドおよび抽出するときに、実際にはfile-loaderを使用して完了し、対応するファイル ハッシュ値は対応するfile-loaderによって計算されます。では、これらの静的ファイルにはどのようなハッシュ値が使用されるのでしょうか? 実は、それらはhash属性値です。次のコードに示すように:

モジュール.エクスポート = {
 ...
 ルール:
   ...
    {
      テスト: /\.(gif|png|jpe?g)(\?\S*)?$/,
      ローダー: require.resolve('url-loader'),
      オプション:
        制限: 10000、
        名前: path.posix.join('static', '[name]_[hash:7].[ext]')
      }
    },
    フォント:
      テスト: /\.otf|ttf|woff2?|eot(\?\S*)?$/,
      ローダー: require.resolve('url-loader'),
      オプション:
        制限: 10000、
        名前: path.posix.join('static', '[name]_[hash:7].[ext]')
      }
    }
 ]
}

上記では、ハッシュ属性値が使用されていることがわかります。このハッシュは、プロジェクトがビルドされるたびに webpack がビルドするハッシュではありません。これは、ファイルの内容に基づいて file-loader によって計算されます。webpack によってビルドされるハッシュと間違えないでください。

参照する

1. webpackのCommonsChunkPluginを開く正しい方法
2. Webpack ピット充填道路抽出独立ファイル(モジュール)
3. Webpackコード分割スキル
4. ファイル名のハッシュを処理するために webpack を使用していると聞きました。次に、生成したハッシュが正しいかどうかを確認することをお勧めします。
5. チャンクハッシュ
6. 複数のコモンズチャンク
7. Webpackを使用して永続キャッシュを実装する
8. Webpack のハッシュとチャンクアッシュの違い、および js と css のハッシュ フィンガープリント分離ソリューション

これで、webpack で静的リソース キャッシュを実装する方法についての記事は終了です。より関連性の高い webpack 静的リソース キャッシュ コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Electron-vueはwebpackを使用して複数ページのエントリファイルをパッケージ化します
  • webpackのモバイル適応ソリューションの概要
  • vue-cli を使用してプロジェクトを作成し、webpack でパッケージ化する方法
  • webpackでHMRを手動で実装するいくつかの方法
  • vue の webpack -v エラー解決の概要

<<:  dubbo での Zookeeper リクエストのタイムアウト問題: mysql8.0.15 に接続する mybatis+spring の構成

>>:  Linux で実行可能ファイルを実行するときに「そのようなファイルまたはディレクトリはありません」というプロンプトが表示される場合の解決策

推薦する

Reactにおける制御されたコンポーネントと制御されていないコンポーネントの簡単な分析

目次制御されていないコンポーネント制御コンポーネント知らせ結論は制御されていないコンポーネントフォー...

4つの柔軟なScssコンパイル出力スタイル

多くの人は、Scss を使用する瞬間からコンパイル方法を説明されてきました。したがって、コマンドのコ...

JSONデータをHTMLで表示する方法

背景:場合によっては、json データをページに直接表示する必要があります (たとえば、インターフェ...

MySQLのファジークエリの要約

1. 一般的な使用法: (1)%で使用する% は 1 つ以上の文字のワイルドカードを表します。たとえ...

Linux システム AutoFs 自動マウント サービスのインストールと構成

目次序文1. サービスプログラムをインストールする2. メイン設定ファイルを書く3. サブ構成ファイ...

ポータルサイト再設計のユーザーエクスペリエンス

<br />2006年10月12日のNetEaseの新ホームページの公開から、2008年...

dockerを使用してGrafana+Prometheus構成をデプロイする

docker-compose-monitor.yml バージョン: '2' ネットワ...

HTML 基本要約推奨事項 (テキスト形式)

HTMLテキスト書式タグ 標簽 描述 <b> 定義粗體文本 <em> 呈現...

MySQL が group by をサポートしない場合の解決策の概要

MySQL 5.7.x の最新バージョンをダウンロードしてインストールしました。デフォルトでは、on...

WeChat ミニプログラム ユーザー認証のベストプラクティス ガイド

序文WeChat アプレットを開発する際には、ユーザーの権限が必要なページを使用する必要があることが...

CSS変数var()の使い方を理解する必要があります

Web プロジェクトがどんどん大きくなると、CSS は天文学的な大きさと複雑さを増します。この問題を...

高度な CSS の 3 つの方法を使用して複数行の省略を実装するサンプル コード

序文これは古くからの要望ですが、オンラインで解決策を探している人はまだ多く、特に検索結果の上位にラン...

NFS サーバーの原理と、その構築、構成、展開の手順を簡単に分析します。

目次NFS サービスの概要NFS とは何ですか? NFS マウントの原則NFS サーバーはデータ転送...

スライダーを作成するためのネイティブ js ドラッグ アンド ドロップ機能のサンプル コード

ドラッグ アンド ドロップはフロントエンドでよく使われる機能であり、多くのエフェクトで js のドラ...