Javascript 防止RequireJS缓存所需脚本
RequireJS似乎在内部做了一些事情来缓存所需的javascript文件。如果我对其中一个必需的文件进行了更改,我必须重命名该文件才能应用更改 将版本号作为querystring参数附加到文件名末尾的常见技巧不适用于requirejsJavascript 防止RequireJS缓存所需脚本,javascript,jquery,requirejs,Javascript,Jquery,Requirejs,RequireJS似乎在内部做了一些事情来缓存所需的javascript文件。如果我对其中一个必需的文件进行了更改,我必须重命名该文件才能应用更改 将版本号作为querystring参数附加到文件名末尾的常见技巧不适用于requirejs 我要寻找的是一种方法来防止RequireJS所需脚本的这种内部缓存,而不必在每次更新脚本文件时重命名它们 跨平台解决方案: 我现在使用urlArgs:“bust=”+(new Date()).getTime()在开发过程中自动清除缓存,使用urlArgs:“b
我要寻找的是一种方法来防止RequireJS所需脚本的这种内部缓存,而不必在每次更新脚本文件时重命名它们
跨平台解决方案:
我现在使用urlArgs:“bust=”+(new Date()).getTime()
在开发过程中自动清除缓存,使用urlArgs:“bust=v2”
在发布更新后的所需脚本后增加硬编码版本数
注意:
@Dustin Getz在最近的回答中提到,当Javascript文件像这样不断刷新时,Chrome开发者工具将在调试期间删除断点。一种解决方法是编写调试器
在大多数Javascript调试器中触发断点的代码中
特定于服务器的解决方案:
有关可能更适合您的服务器环境(如Node或Apache)的特定解决方案,请参阅下面的一些答案。可以将RequireJS配置为向每个脚本URL追加一个值,以进行缓存破坏 从RequireJS文档()中: urlArgs:附加到需要JS的URL的额外查询字符串参数 用于获取资源。在浏览器或 服务器配置不正确 例如,将“v2”附加到所有脚本:
require.config({
urlArgs: "bust=v2"
});
出于开发目的,您可以通过附加时间戳强制RequireJS绕过缓存:
require.config({
urlArgs: "bust=" + (new Date()).getTime()
});
受此启发,我们使用以下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>
不要为此使用urlArgs!
要求脚本加载与http缓存头相关。(加载脚本时会动态插入一个
,这意味着请求看起来就像加载的任何旧资产一样。)
为您的javascript资产提供适当的HTTP头,以便在开发过程中禁用缓存
使用require的urlArgs意味着您设置的任何断点都不会在刷新过程中保留;您最终需要在代码中的任何地方放置调试器语句。糟糕。我使用urlArgs
在使用git sha进行生产升级的过程中对缓存资产进行破坏;然后我可以将我的资产设置为永久缓存,并保证永远不会有过时的资产
在开发过程中,我用一个复杂的配置模拟所有ajax请求,然后我就可以用一个简单的配置在javascript模式下为我的应用程序提供服务。对我来说,这已经扩展到一个相当大的“enterprisey”应用程序,它有数百个RESTfulWebService端点。我们甚至有一位签约设计师,他可以使用我们真正的生产代码库,而无需访问我们的后端代码。快速修复开发
对于开发,您可以在Chrome开发工具中禁用缓存。只有在“开发工具”对话框处于打开状态时,才会禁用缓存,因此您无需担心在每次进行常规浏览时切换此选项
注意:在生产中使用“urlArgs”是正确的解决方案,这样用户就可以获得最新的代码。但这使调试变得困难,因为chrome每次刷新都会使断点失效(因为每次都会提供一个“新”文件)。在生产环境中
urlArgs
会导致问题强>
requirejs的主要作者:
对于已部署的资产,我更倾向于将版本或散列作为整体
构建为构建目录,然后只需修改所使用的baseUrl
config
让项目将该版本目录用作baseUrl
。然后
没有其他文件更改,这有助于避免某些代理问题
不能缓存带有查询字符串的URL。
[设计我的风格。]
我听从这个建议
发展中
我更喜欢使用智能缓存可能频繁更改的文件的服务器:一个服务器,它会发出上次修改的,,并在适当时使用304响应自修改后的。即使是基于节点集的服务器,也可以直接提供静态文件。它不需要对我的浏览器执行任何操作,也不会弄乱断点。我从中提取了这段代码,并将其放入本地Apache Web服务器的一个单独的.conf文件中(在我的示例中为/etc/apache2/others/preventcaching.conf):
FileTag无
标题未设置ETag
标题集缓存控制“最大年龄=0,无缓存,无存储,必须重新验证”
标题集Pragma“无缓存”
标题集过期“1984年1月11日星期三05:00:00 GMT”
对于开发来说,这很好,无需更改代码。至于生产,我可能会使用@dvtoever的方法。urlArgs解决方案有问题。不幸的是,您无法控制您和用户web浏览器之间的所有代理服务器。不幸的是,有些代理服务器在缓存文件时会被配置为忽略URL参数。如果发生这种情况,JS文件的错误版本将交付给用户
我最终放弃了,直接进入require.js。如果您愿意修改requirejs库的版本,此解决方案可能适合您
您可以在此处看到修补程序:
添加后,您可以在require配置中执行以下操作:
var require = {
baseUrl: "/scripts/",
cacheSuffix: ".buildNumber"
}
使用生成系统或服务器环境将buildNumber
替换为修订id/软件版本/常用颜色
使用类似这样的命令:
require(["myModule"], function() {
// no-op;
});
将导致请求此文件:
http://yourserver.com/scripts/myModule.buildNumber.js
在我们的服务器环境中,我们使用url重写规则去除buildNumber,并提供正确的J
require(["myModule"], function() {
// no-op;
});
http://yourserver.com/scripts/myModule.buildNumber.js
var require = {
baseUrl: "/scripts/buildNumber."
};
http://yourserver.com/scripts/buildNumber.myModule.js
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 %}
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"
var load = requirejs.load;
requirejs.load = function (context, moduleId, url) {
url += "?v=" + oRevision[moduleId];
load(context, moduleId, url);
};
gulp.task('gulp-revision', function() {
var sManifestFileName = 'revision.js';
return gulp.src(aGulpPaths)
.pipe(rev())
.pipe(rev.manifest(sManifestFileName, {
transformer: {
stringify: function(a) {
var oAssetHashes = {};
for(var k in a) {
var key = (k.substr(0, k.length - 3));
var sHash = a[k].substr(a[k].indexOf(".") - 10, 10);
oAssetHashes[key] = sHash;
}
return "define([], function() { return " + JSON.stringify(oAssetHashes) + "; });"
}
}
}))
.pipe(gulp.dest('./'));
});
LoadFile(filePath){
const file = require(filePath);
const result = angular.copy(file);
return result;
}