require.js - 如何在URL中设置所需模块的版本号?

4
我正在使用require.js在我的应用程序中引用JS模块。
我需要一种方法来通过不同的请求URL打破客户端缓存中新的JS模块。
例如,如果文件hello/there.js已经被客户端缓存,我可以更改文件名以强制浏览器获取新文件。
换句话说,对于模块hello/there,我想让require.js请求url hello/there___v1234___.js(文件名可能看起来不同,这只是一个示例),根据客户端可访问的版本字符串。
如何实现最佳效果?

那么你在服务器上有一个名为“there___v1234___.js”的文件? - epascarello
我使用重写规则,以便服务器提供正确的文件。 - Ovesh
4个回答

4
我对urlArgs解决方案感到非常沮丧,最终放弃了,并直接将我的自己的修复实现到require.js中。如果你愿意修改库的版本,这个修复会实现你的理想解决方案。
你可以在这里看到补丁:

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

添加后,您可以在require配置中执行以下操作:

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

使用您的构建系统或服务器环境,将buildNumber替换为修订ID或软件版本。
像这样使用require:
require(["myModule"], function() {
    // no-op;
});

将导致 require 请求此文件:

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

该补丁会忽略指定协议的任何脚本,并且不会影响任何非JS文件。
在我们的服务器环境中,我们使用URL重写规则来删除buildNumber并提供正确的JS文件。这样,我们实际上不必担心重命名所有JS文件。
这在我的环境中运行良好,但我意识到一些用户更喜欢前缀而不是后缀,很容易修改我的提交以适应您的需求。
以下是一些可能重复的问题: RequireJS和代理缓存 防止RequireJS缓存所需的脚本

3

好的,我为您搜索了“requirejs缓存破坏”并找到了这个现有的SO答案,其中说可以使用urlArgs参数配置requireJS,这只是一个部分解决方案,但可能足以满足您的即时需求。

话虽如此,缓存破坏问题充满挑战,许多“解决方案”实际上并没有完全解决问题。目前唯一可维护的方法(依我之见)是使用像Ruby on Rails资产管道或connect-assets或您选择的服务器端框架的等效系统。它们可以正确计算每个文件内容的校验和(通常是MD5或SHA1),并给您需要在HTML script标记中作为URL的文件名。因此,不要费心手动更改基于版本号的文件名,只需使用校验和,因为它们易于自动化且无懈可击。

据我所知,开箱即用的requirejs不能为您处理缓存破坏方面的问题。您可能需要阅读此Google组线程。否则,您可能需要将requirejs与其他工具/脚本配对,以获得良好的缓存破坏校验和。


就这个问题而言,文件命名并不是关键,关键是如何让require.js正确处理它。我会看一下你提供的论坛帖子。 - Ovesh
哦,而常规的requirejs缓存破坏解决方案对我来说并不好,因为添加参数意味着文件永远不会被缓存。我只想让浏览器在有新版本时获取文件,而不是在每个请求上获取。 - Ovesh
你真的读了我链接的答案吗?如果你使用像?v=2这样的静态参数,那么它将被很好地缓存。 - Peter Lyons
你确定吗?据我所记,参数总是禁用缓存。我错了吗? - Ovesh
我认为这里没有硬性规定或标准中固有的行为,但以apache为例,文档指出:“通常,带有查询字符串参数的请求会针对每个唯一的查询字符串单独缓存”。并不是说查询字符串的存在会禁用缓存,只是?v=24和?v=25被视为两个不同的资源。http://httpd.apache.org/docs/2.2/mod/mod_cache.html - Peter Lyons
显示剩余2条评论

2

按照requirejs的创建者所建议的方式进行操作:

var load = requirejs.load;
requirejs.load = function (context, moduleId, url) {
  // modify url here
  url = url.substring(0, url.lastIndexOf('.')) + '.' + VERSION + url.substring(url.lastIndexOf('.'));
  return load(context, moduleId, url);
};

https://github.com/jrburke/requirejs/wiki/Fine-grained-URL-control


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接