Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止RequireJS缓存所需脚本_Javascript_Jquery_Requirejs - Fatal编程技术网

Javascript 防止RequireJS缓存所需脚本

Javascript 防止RequireJS缓存所需脚本,javascript,jquery,requirejs,Javascript,Jquery,Requirejs,RequireJS似乎在内部做了一些事情来缓存所需的javascript文件。如果我对其中一个必需的文件进行了更改,我必须重命名该文件才能应用更改 将版本号作为querystring参数附加到文件名末尾的常见技巧不适用于requirejs 我要寻找的是一种方法来防止RequireJS所需脚本的这种内部缓存,而不必在每次更新脚本文件时重命名它们 跨平台解决方案: 我现在使用urlArgs:“bust=”+(new Date()).getTime()在开发过程中自动清除缓存,使用urlArgs:“b

RequireJS似乎在内部做了一些事情来缓存所需的javascript文件。如果我对其中一个必需的文件进行了更改,我必须重命名该文件才能应用更改

将版本号作为querystring参数附加到文件名末尾的常见技巧不适用于requirejs

我要寻找的是一种方法来防止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;
}