Javascript 使 require.js data-main 上的缓存过期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11088909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:24:23  来源:igfitidea点击:

Expire cache on require.js data-main

javascriptcachingrequirejsbrowser-cacheamd

提问by Jesse

I'm using require.js and r.js to package my AMD modules. I'm using jquery & requirejs via the following syntax:

我正在使用 require.js 和 r.js 来打包我的 AMD 模块。我通过以下语法使用 jquery 和 requirejs:

<script data-main="/js/client" src="/js/external/require-jquery.js"></script>

This all works great pre & post packaging, but I run into issues a lot where chrome & mobile safari hold on to the cached version of client.js. I'd like to add a cachebuster to client.js, but I can't seem to figure out how to do it using the above syntax.

这一切在打包前和打包后都非常有效,但我遇到了很多问题,即 chrome 和 mobile safari 保留了 client.js 的缓存版本。我想向 client.js 添加一个 cachebuster,但我似乎无法弄清楚如何使用上述语法来做到这一点。

I tried some variations of:

我尝试了一些变体:

<script data-main="js/client.js?b=busted" src="/js/external/require-jquery.js"></script>

but now require tries to get client.js from /, not /js, so it 404s.

但是现在 require 尝试从/,而不是获取 client.js /js,所以它是 404s。

I also tried adding

我也尝试添加

urlArgs : "bust="+new Date().getTime()

to require.config, but it appears to have no effect.

require.config,但它似乎没有效果。

I also tried adding the same value to app.build.js, but when it's in there, r.js no longer concatenates my js files, just uglifies them.

我也尝试将相同的值添加到app.build.js,但是当它在那里时,r.js 不再连接我的 js 文件,只是丑化它们。

What is the proper syntax to bust a require.js data-main script cache?

破坏 require.js 数据主脚本缓存的正确语法是什么?

回答by JBCP

How are you defining your require.config? I think for it to take effect before you import require.js, you need to code it like this:

你如何定义你的require.config?我认为要在导入 require.js 之前使其生效,您需要像这样编写代码:

<script type="text/javascript">
    var require = {
        baseUrl: "/scripts/",
        waitSeconds: 15,
        urlArgs : "bust="+new Date().getTime()
    };
</script>
<script data-main="app/main" src="/scripts/require.js"></script>

Specifically, a an object named 'require' must be constructed before you import require.js.

具体来说,在导入 require.js 之前必须构造一个名为“require”的对象。

UPDATE

更新

As Jesse points out in the comments below, there are a few enhancements you should apply to your require{} object for production use. The above example is cribbed from the RequireJS documentation and modified as little as possible to answer this question.

正如 Jesse 在下面的评论中指出的那样,您应该对 require{} 对象应用一些增强功能以​​供生产使用。{} 上面的示例摘自 RequireJS 文档并尽可能少地修改以回答这个问题。

Here are a few things to consider for production use:

以下是生产使用时需要考虑的一些事项:

  • Instead of using the current date-time as your cache-busting variable, you should use a build number from your development environment. This allows your clients to cache the Javascript between releases but will cause them to refresh their cache whenever you do a software update.
  • Jesse also uses the require{}'s ability to specify dependencies instead of using the data-main attribute of the script. I don't know if that is strictly better, but I think it is cleaner looking.
  • Adjust the waitSeconds based on your needs. I used the example value from the RequireJS documentation, but you should adjust the value or omit it, based on your needs.
  • 您应该使用开发环境中的内部版本号,而不是使用当前日期时间作为缓存破坏变量。这允许您的客户端在版本之间缓存 Javascript,但会导致他们在您进行软件更新时刷新其缓存。
  • Jesse 还使用 require{} 的功能来指定依赖项,而不是使用脚本的 data-main 属性。我不知道这是否更好,但我认为它看起来更干净。
  • 根据您的需要调整waitSeconds。我使用了 RequireJS 文档中的示例值,但您应该根据您的需要调整该值或省略它。

So if you apply these techniques, your code might look like:

因此,如果您应用这些技术,您的代码可能如下所示:

<script type="text/javascript">
    var require = {
        baseUrl: "/scripts/",
        waitSeconds: 15,
        urlArgs : "bust="+{{buildNumber}},
        deps : ['app/main']
    };
</script>
<script src="/scripts/require.js?bust={{buildNumber}}"></script>

Note, in this case {{buildNumber}} is a value supplied by the server.

请注意,在这种情况下,{{buildNumber}} 是服务器提供的值。

UPDATE 2

更新 2

The urlArgs cache bust solution has problems. Unfortunately you cannot control all proxy servers that might be between you and your user's web browser. Some of these proxy servers can be unfortunately configured to ignore URL parameters when caching files. If this happens, the wrong version of your JS file will be delivered to your user.

urlArgs 缓存破坏解决方案有问题。不幸的是,您无法控制您和用户的 Web 浏览器之间可能存在的所有代理服务器。不幸的是,其中一些代理服务器配置为在缓存文件时忽略 URL 参数。如果发生这种情况,您的 JS 文件的错误版本将交付给您的用户。

I would recommend using a buildNumberinyour Javascript filename request, like buildNumber.myModule.js(prefix) or myModule.buildNumber.js (postfix). You can use the prefix style by modifying the baseUrl:

我建议buildNumber您的 Javascript 文件名请求中使用 a ,例如buildNumber.myModule.js(prefix) 或 myModule.buildNumber.js (postfix)。您可以通过修改 baseUrl 来使用前缀样式:

baseUrl: "/scripts/buildNumber",

Note the lack of a '/' at the end of the baseUrl.

请注意 baseUrl 末尾缺少“/”。

You will need to use a modified version of require.js to use the postfix solution. You can read more about this here: https://stackoverflow.com/a/21619359/1017787

您将需要使用 require.js 的修改版本才能使用 postfix 解决方案。您可以在此处阅读更多相关信息:https: //stackoverflow.com/a/21619359/1017787

Obviously in either case you will want to use some solution to replace buildNumberwith some type of version number that changes with each release.

显然,在任何一种情况下,您都希望使用某种解决方案来替换buildNumber随每个版本而变化的某种类型的版本号。

回答by Alexee

Here is my solution (for emergency) :

这是我的解决方案(紧急情况):

  1. Find the following code in require.js:
  1. 在 require.js 中找到以下代码:

Development version

开发版

//Join the path parts together, then figure out if baseUrl is needed.
url = syms.join('/');
url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js'));
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;

OR

或者

Production version

量产版

e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||c?"":".js");
  1. and add ?v=x.0after the .js

    url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js?v=1.0'));

    OR

    (/^data\:|\?/.test(d)||c?"":".js?v=1.0");

  1. 并在?v=x.0之后添加.js

    url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js?v=1.0'));

    或者

    (/^data\:|\?/.test(d)||c?"":".js?v=1.0");