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

2

9

I would like to migrate to SystemJS from requirejs however I am failing to find a solution as requirejs have for module versioning. For example in production (ASP.Net website) I have set RequireJS like this:

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

It guarantees that the file will be reloaded once the project is republished in the production environment, and kept that way until it is reloaded.

However, I did not find any solution for this for SystemJS (As SystemJS manage more types of modules, I would like to migrate to it).

Has anyone used SystemJS in production and had the same issue, do you know an "urlArgs" parameter (or plugin) in SystemJS?

Alcaeus answered 15/2, 2016 at 8:21 Comment(5)
I don't really understand you question? --- P.S. I am using only requireJS and caching everything up to 365 days. All working well, why do you need systemJS in the first place?Emcee
I've edited the post, it's only to know if anyone has found a parameter/plugin to have the same urlArgs behavior of RequireJS. SystemJS let us use many types of module definition, so I find it more "future-proof".Gracioso
I understand now, it seem like you can found your answer over here. #33333411Emcee
There is no urlArgs parameter or similar plugin in this answer.Gracioso
Terribly sorry for mistaken... I will instead prepare an answer for you really quick ;)Emcee
E
9

Long story short: there were issues on github of SystemJS about cache bust. But thing are not offically implemeted yet. At the moment there is a custom hook, which can be easily added

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;
  });
}

EDIT fix typo

Emcee answered 19/2, 2016 at 13:44 Comment(3)
In fact the maker of SystemJS said it was not going to be implemented on SystemJS, saying "caching should be handled at the server layers not the loader layer".Gracioso
Doesn’t work since 0.20: github.com/systemjs/systemjs/issues/1616Entrails
I have 0.19 and this method works great. Thanks a lot for sharing!Pouf
C
0

I'm on .19 still and for my purposes wanted to control caching for specific files actually in the import, not by a setting per file or globally, etc. but literally when I make the import I want to control it (like how you would normally do with Query Strings).

So just to offer a slight adaptation of the above that I think fits for a lot of people wanting to do it this way - you can just conventionally include 'NO-CACHE' or something in any import and the hook will add a timestamp to break cache. This allows you to call a module with cache from one place but without it from another. Also it let's you break cache anytime you need to on dynamic imports, even dynamically.

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;
});
Cheeseburger answered 26/9, 2019 at 18:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.