用于生产和缓存管理的 SystemJS 版本控制(requirejs urlArgs 替代方案)

SystemJS versioning for production and cache management (requirejs urlArgs alternative)

我想从 requirejs 迁移到 SystemJS,但是我找不到解决方案,因为 requirejs 有模块版本控制。 例如在生产环境中(ASP.Net 网站)我这样设置 RequireJS:

require.config({
            baseUrl: "@Url.Content("~/Scripts/")",
            urlArgs: "buildNumber=@(File.GetLastWriteTime(ViewContext.Controller.GetType().Assembly.Location).ToBinary().ToString() + typeof(Foundation.MvcApplication).Assembly.GetName().Version)",
            ...
});

保证在生产环境重新发布项目后重新加载该文件,并一直保持到重新加载。

但是,我没有找到针对 SystemJS 的任何解决方案(由于 SystemJS 管理更多类型的模块,我想迁移到它)。

有没有人在生产中使用过 SystemJS 并遇到同样的问题,你知道 SystemJS 中的 "urlArgs" 参数(或插件)吗?

长话短说:SystemJS 的 github 上存在关于 cache bust 的问题。但是事情还没有正式实施。目前有一个自定义的钩子,可以很容易地添加

var buildNumber = 1234, // made your own build number
    systemLocate = System.locate;
System.locate = function(load) {
  return Promise.resolve(systemLocate.call(this, load)).then(function(address) {
    return address + '?build='+buildNumber;
  });
}

编辑 修正拼写错误

我仍在使用 .19,出于我的目的,我想控制导入中实际特定文件的缓存,而不是通过每个文件或全局设置等,但实际上当我进行导入时我想控制它(就像您通常使用查询字符串的方式一样)。

所以只是对上面的内容进行了轻微的改编,我认为这适合很多想要这样做的人 - 你可以按照惯例在任何导入中包含 'NO-CACHE' 或其他内容,钩子将添加时间戳以打破缓存。这允许你从一个地方调用一个有缓存的模块,而没有从另一个地方调用它。此外,它还允许您在需要动态导入时随时中断缓存,甚至是动态导入。

var systemLocate = System.locate;
System.locate = function (load) {
    return Promise.resolve(systemLocate.call(this, load)).then(function (address) {
        if (address.includes('NO-CACHE'))
            return address.replace('NO-CACHE', '') + '?q=' + new Date(Date.now()).getTime();
        return address;
    });
};

// Example Import with NO-CACHE - can be placed anywhere in path
System.import('NO-CACHE../config.json!').then(config => {
    window.appVersion = config.version;
});