303

RequireJSは、必要なjavascriptファイルをキャッシュする何かを内部的に実行しているようです。必要なファイルの1つに変更を加えた場合、変更を適用するには、ファイルの名前を変更する必要があります。

ファイル名の最後にクエリ文字列パラメータとしてバージョン番号を追加する一般的なトリックは、requirejsでは機能しません<script src="jsfile.js?v2"></script>

私が探しているのは、スクリプトファイルが更新されるたびに名前を変更することなく、RequireJSに必要なスクリプトのこの内部キャッシュを防ぐ方法です。

クロスプラットフォームソリューション:

現在urlArgs: "bust=" + (new Date()).getTime()、開発中の自動キャッシュバスティングとurlArgs: "bust=v2"、更新された必要なスクリプトをロールアウトした後にハードコードされたバージョン番号をインクリメントする本番環境に使用しています。

ノート:

@Dustin Getzは最近の回答で、Javascriptファイルがこのように継続的に更新されると、ChromeDeveloperToolsがデバッグ中にブレークポイントをドロップすると述べています。回避策の1つはdebugger;、ほとんどのJavascriptデバッガーでブレークポイントをトリガーするコードを記述することです。

サーバー固有のソリューション:

NodeやApacheなどのサーバー環境でより適切に機能する可能性のある特定のソリューションについては、以下の回答のいくつかを参照してください。

4

12 に答える 12

461

RequireJSは、キャッシュ無効化のために各スクリプトURLに値を追加するように構成できます。

RequireJSドキュメント(http://requirejs.org/docs/api.html#config)から:

urlArgs:RequireJSがリソースをフェッチするために使用するURLに追加される追加のクエリ文字列引数。ブラウザまたはサーバーが正しく構成されていない場合にバストをキャッシュするのに最も役立ちます。

例、すべてのスクリプトに「v2」を追加します。

require.config({
    urlArgs: "bust=v2"
});

開発の目的で、タイムスタンプを追加することにより、RequireJSにキャッシュをバイパスさせることができます。

require.config({
    urlArgs: "bust=" + (new Date()).getTime()
});
于 2011-12-12T19:46:58.427 に答える
54

これには urlArgs を使用しないでください。

スクリプトの読み込みが http キャッシュ ヘッダーを尊重することを要求します。(スクリプトは動的に挿入された で<script>読み込まれます。つまり、リクエストは古いアセットが読み込まれるように見えます。)

適切な HTTP ヘッダーを使用して JavaScript アセットを提供し、開発中にキャッシュを無効にします。

require の urlArgs を使用すると、設定したブレークポイントは更新後も保持されません。debuggerコードのいたるところにステートメントを配置する必要があります。悪い。私はurlArgs、git sha を使用して本番環境のアップグレード中にアセットをキャッシュ無効化するために使用します。次に、資産を永久にキャッシュするように設定し、古い資産が決してないことを保証できます。

開発では、複雑なmockjax構成を使用してすべての ajax リクエストをモックし、 10 行の python http サーバーを使用して、すべてのキャッシュをオフにして、javascript のみのモードでアプリを提供できます。これにより、何百もの安らかなWebサービスエンドポイントを持つ非常に大規模な「エンタープライズ」アプリケーションにスケールアップしました. バックエンドコードへのアクセスを許可せずに、実際の製品コードベースで作業できる契約デザイナーさえいます。

于 2013-02-25T22:56:50.713 に答える
24

urlArgs ソリューションには問題があります。残念ながら、あなたとユーザーの Web ブラウザの間にある可能性のあるすべてのプロキシ サーバーを制御することはできません。残念ながら、これらのプロキシ サーバーの一部は、ファイルをキャッシュするときに URL パラメーターを無視するように構成できます。これが発生すると、間違ったバージョンの JS ファイルがユーザーに配信されます。

私は最終的にあきらめて、独自の修正をrequire.jsに直接実装しました。ご使用のバージョンの requirejs ライブラリを変更する場合は、このソリューションが役立つ可能性があります。

ここでパッチを見ることができます:

https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67

追加したら、必要な構成で次のようなことができます。

var require = {
    baseUrl: "/scripts/",
    cacheSuffix: ".buildNumber"
}

ビルド システムまたはサーバー環境を使用buildNumberして、リビジョン ID / ソフトウェア バージョン / お気に入りの色に置き換えます。

次のように require を使用します。

require(["myModule"], function() {
    // no-op;
});

このファイルを要求する必要があります。

http://yourserver.com/scripts/myModule.buildNumber.js

サーバー環境では、URL 書き換えルールを使用して buildNumber を取り除き、正しい JS ファイルを提供します。このようにして、すべての JS ファイルの名前を変更することを実際に心配する必要はありません。

パッチはプロトコルを指定するスクリプトを無視し、JS 以外のファイルには影響しません。

これは私の環境ではうまく機能しますが、一部のユーザーはサフィックスよりもプレフィックスを好むことを認識しています。ニーズに合わせてコミットを簡単に変更できるはずです。

アップデート:

プル リクエストの議論で、requirejs の作成者は、これがリビジョン番号をプレフィックスとして付ける解決策として機能する可能性があることを示唆しています。

var require = {
    baseUrl: "/scripts/buildNumber."
};

私はこれを試していませんが、これは次の URL を要求することを意味します。

http://yourserver.com/scripts/buildNumber.myModule.js

これは、プレフィックスを使用できる多くの人にとって非常にうまく機能する可能性があります。

重複する可能性のあるいくつかの質問を次に示します。

RequireJS とプロキシ キャッシング

require.js - URL の一部として必要なモジュールのバージョンを設定するにはどうすればよいですか?

于 2014-02-07T04:29:02.643 に答える
19

require.js data-main の Expire cache に触発されて、デプロイ スクリプトを次の Ant タスクで更新しました。

<target name="deployWebsite">
    <untar src="${temp.dir}/website.tar.gz" dest="${website.dir}" compression="gzip" />       
    <!-- fetch latest buildNumber from build agent -->
    <replace file="${website.dir}/js/main.js" token="@Revision@" value="${buildNumber}" />
</target>

main.js の先頭は次のようになります。

require.config({
    baseUrl: '/js',
    urlArgs: 'bust=@Revision@',
    ...
});
于 2012-09-12T08:28:24.610 に答える
11

生産中

urlArgs問題を引き起こす可能性があります!

requirejs の主要な作成者は、以下を使用しないことを好みますurlArgs

デプロイされたアセットの場合、ビルド全体のバージョンまたはハッシュをビルド ディレクトリとして配置baseUrlし、プロジェクトに使用される構成を変更して、そのバージョン管理されたディレクトリをbaseUrl. その後、他のファイルは変更されず、クエリ文字列を含む URL がキャッシュされない可能性があるプロキシの問題を回避するのに役立ちます。

【スタイリングマイン】

私はこのアドバイスに従います。

開発中

私は、頻繁に変更される可能性のあるファイルをインテリジェントにキャッシュするサーバーを使用することを好みます。適切な場合に 304 をLast-Modified発行して応答するサーバーです。静的ファイルを提供するノードの高速If-Modified-Sinceセットに基づくサーバーでさえ、これをすぐに実行できます。ブラウザに対して何もする必要はなく、ブレークポイントを台無しにすることもありません。

于 2013-11-01T16:09:12.910 に答える
7

このスニペットをAskApacheから取得し、ローカルの Apache Web サーバーの別の .conf ファイル (私の場合は /etc/apache2/others/preventcaching.conf) に入れました。

<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</FilesMatch>

開発の場合、これはコードを変更する必要なく正常に機能します。制作に関しては、@dvtoever のアプローチを使用するかもしれません。

于 2013-12-09T20:00:30.533 に答える
6

開発のためのクイックフィックス

開発の場合、Chrome Dev Tools でキャッシュを無効にすることができます( Disabling Chrome cache for website development )。キャッシュの無効化は、開発ツール ダイアログが開いている場合にのみ行われるため、通常のブラウジングを行うたびにこのオプションを切り替えることを心配する必要はありません。

注: ' urlArgs ' を使用することは、ユーザーが最新のコードを取得できるように、実稼働環境で適切なソリューションです。ただし、クロムは更新のたびにブレークポイントを無効にするため、デバッグが困難になります (毎回「新しい」ファイルが提供されるため)。

于 2013-08-29T15:27:26.210 に答える
2

これは私がDjango / Flaskで行う方法です(他の言語/ VCSシステムに簡単に適応できます):

あなたのconfig.py(私はこれをpython3で使用しているので、python2でエンコーディングを微調整する必要があるかもしれません)

import subprocess
GIT_HASH = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')

次に、テンプレートで:

{% if config.DEBUG %}
     require.config({urlArgs: "bust=" + (new Date().getTime())});
{% else %}
    require.config({urlArgs: "bust=" + {{ config.GIT_HASH|tojson }}});
{% endif %}
  • 手動のビルド プロセスは不要
  • アプリの起動時に一度だけ実行され、オブジェクトgit rev-parse HEADに保存されますconfig
于 2014-11-26T14:14:02.463 に答える
-2

これは、@ phil mccullの受け入れられた回答に追加されています。

私は彼の方法を使用していますが、ビルド前に実行する T4 テンプレートを作成してプロセスを自動化しています。

ビルド前のコマンド:

set textTemplatingPath="%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
if %textTemplatingPath%=="\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe" set textTemplatingPath="%CommonProgramFiles%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
%textTemplatingPath% "$(ProjectDir)CacheBuster.tt"

ここに画像の説明を入力

T4 テンプレート:

ここに画像の説明を入力

生成されたファイル: ここに画像の説明を入力

require.config.js が読み込まれる前に変数に保存します。 ここに画像の説明を入力

require.config.js での参照:

ここに画像の説明を入力

于 2016-01-09T01:36:37.883 に答える