ES6モジュールを使用すると、次のように単一のエントリポイントを作成できます。
// main.js
import foo from 'foo';
foo()
<script src="scripts/main.js" type="module"></script>
foo.jsはブラウザのキャッシュに保存されます。これは、新しいバージョンのfoo.jsを本番環境にプッシュするまで望ましいです。
ブラウザーにjsファイルの新しいバージョンを取得するように強制するために、一意のIDを持つクエリ文字列パラメーターを追加することは一般的な方法です(foo.js?cb = 1234)
Es6モジュールパターンを使用してこれをどのように実現できますか?
救出へのHTTPヘッダー。ファイルのチェックサムである ETag を使用してファイルを提供します。 S3はそれを行います デフォルトでは 例では。ファイルを再度インポートしようとすると、ブラウザーはファイルを要求し、今度はETagを " if-none-match "ヘッダーに添付します。サーバーはETagが現在のファイルと一致するかどうかを確認しますそして、304 Not Modifiedで帯域幅と時間を節約するか、ファイルの新しいコンテンツ(新しいETagを含む)を送り返します。
これにより、プロジェクト内の単一のファイルを変更した場合、ユーザーは他のすべてのモジュールのコンテンツ全体をダウンロードする必要がなくなります。短い_max-age
_ヘッダーも追加することをお勧めします。これにより、同じモジュールが短時間に2回リクエストされた場合、追加のリクエストは発生しません。
キャッシュ無効化を追加する場合(例:バンドルを使用して?x = {randomNumber}を追加するか、すべてのファイル名にチェックサムを追加する)、ユーザーはすべての新しいプロジェクトバージョンで必要なすべてのファイルの完全なコンテンツをダウンロードする必要があります。
どちらのシナリオでも、とにかく各ファイルに対してリクエストを実行します(カスケードでインポートされたファイルは新しいリクエストを生成し、etagsを使用する場合、少なくとも小さな304で終了します)。これを回避するには、動的インポートを使用できますe.g if (userClickedOnSomethingAndINeedToLoadSomeMoreStuff) { import('./someModule').then('...') }
私の観点からは 動的インポート がここでの解決策となり得ます。
手順1)gulpまたはwebpackを使用してマニフェストファイルを作成します。そこで、次のようなマッピングがあります。
export default {
"/vendor/lib-a.mjs": "/vendor/lib-a-1234.mjs",
"/vendor/lib-b.mjs": "/vendor/lib-b-1234.mjs"
};
ステップ2)パスを解決するファイル関数を作成する
import manifest from './manifest.js';
const busted (file) => {
return manifest[file];
};
export default busted;
ステップ3)動的インポートを使用する
import busted from '../busted.js';
import(busted('/vendor/lib-b.mjs'))
.then((module) => {
module.default();
});
Chrome=で少し試してみれば、機能します。相対パスの処理は、ここではトリッキーな部分です。
現時点では考えただけですが、weboackですべての分割されたバンドルにコンテンツハッシュを挿入し、そのハッシュをインポートステートメントに書き込むことができるはずです。私はそれがデフォルトで2番目を行うと思います。
クエリ文字列を含まない、これらすべてのソリューションが1つあります。モジュールファイルが/modules/
にあるとします。モジュールをインポートするときに、相対モジュール解決./
または../
を使用してから、サーバー側のパスを書き直してバージョン番号を含めます。 /modules/x.x.x/
などを使用し、パスを/modules/
に書き換えます。これで、最初のモジュールに<script type="module" src="/modules/1.1.2/foo.mjs"></script>
を含めることで、モジュールのグローバルバージョン番号を取得できます。
または、パスを書き換えることができない場合は、開発中にファイルをフォルダー/modules/version/
に入れ、version
フォルダーの名前をバージョン番号に変更し、公開時にスクリプトタグのパスを更新します。
相対パスの使用は私にとってはうまくいきます:
import foo from './foo';
または
import foo from './../modules/foo';
の代わりに
import foo from '/js/modules/foo';
以前の回答で指摘されているようにETagを使用するか、またはLast-Modified
と関連してIf-Modified-Since
を使用することができます。
考えられるシナリオは次のとおりです。
Last-Modified: Sat, 28 Mar 2020 18:12:45 GMT
およびCache-Control: max-age=60
で応答します。If-Modified-Since: Sat, 28 Mar 2020 18:12:45 GMT
ヘッダーを含むリクエストを送信します。サーバーはこの値をチェックし、200
応答が発行されます。304
"変更なし"ステータスを空のボディで発行します。私はこれでApacheサーバー用に設定されました:
<IfModule headers_module>
<FilesMatch "\.(js|mjs)$">
Header set Cache-Control "public, must-revalidate, max-age=3600"
Header unset ETag
</FilesMatch>
</IfModule>
max-age
をお好みに設定できます。
ETagの設定を解除する必要があります。それ以外の場合、Apacheは毎回200 OK
で応答し続けます( バグです )。また、変更日に基づくキャッシュを使用する場合は必要ありません。