43

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

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

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

我尝试了一些变体:

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

但现在需要尝试从/而不是404s 获取 client.js /js

我也尝试添加

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

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

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

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

4

2 回答 2

76

你是如何定义你的 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>

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

更新

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

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

  • 您应该使用开发环境中的内部版本号,而不是使用当前日期时间作为缓存清除变量。这允许您的客户端在版本之间缓存 Javascript,但会导致他们在您进行软件更新时刷新其缓存。
  • Jesse 还使用 require{} 的功能来指定依赖项,而不是使用脚本的 data-main 属性。我不知道这是否更好,但我认为它看起来更干净。
  • 根据您的需要调整 waitSeconds。我使用了 RequireJS 文档中的示例值,但您应该根据需要调整或省略该值。

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

<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>

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

更新 2

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

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

baseUrl: "/scripts/buildNumber",

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

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

显然,在任何一种情况下,您都需要使用某种解决方案来替换buildNumber某些类型的版本号,这些版本号会随着每个版本的发布而改变。

于 2012-07-30T15:28:12.660 回答
-2

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

  1. 在 require.js 中找到以下代码:

开发版

//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;

或者

生产版

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. 并在?v=x.0之后添加.js

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

    或者

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

于 2017-01-09T10:02:11.503 回答