systemjs / plugin-css

CSS loader plugin
MIT License
92 stars 60 forks source link

feat(hot-reload): add support for hot-reloading #73

Closed frankwallis closed 6 years ago

frankwallis commented 8 years ago

This adds support for hot-reloading css when using systemjs-hot-reloader in the browser. It forces the link tags to update by adding a query parameter to the source url. For back-compatibility when the link tag is first created it is assigned the url without a query parameter.

For an example setup see here, feedback welcome, thanks

guybedford commented 8 years ago

Amazing thanks!

Does this line - https://github.com/systemjs/plugin-css/pull/73/files#diff-2b85e238ffb3010183809ed616d824bfR85 not interfere with the re-injection here? It should?

guybedford commented 8 years ago

There's a feature of this plugin that if a user has manually included the CSS file with a link tag, we don't do the injection. This was mainly to support use cases where Bootstrap users wanted to be able to include bootstrap with a link tag and then be sure a CSS require wouldn't double-up the CSS load.

frankwallis commented 8 years ago

I will do some testing around this feature - do we want the hot-reloader to completely ignore these files or to only reload them the second time around?

guybedford commented 8 years ago

For the CSS plugin to take ownership of future hot-reloads of those files sounds like a nice feature to me. Thanks so much for looking into this. Feel free to ping me on gitter as well if you want to discuss anything more here too.

shovemedia commented 8 years ago

This pull request is possibly out-of-date(?) I was able to get css hot reloading with systemjs-hot-reloader:

var pathTransform = function(filename){
    //transform hot reload filesystem event path to url path
    var out = filename.replace(/\.\.\/somePath\//, '');
    return out;
};

var hr = new HotReloader.default('http://localhost:9999', pathTransform);

hr.on('change', (file) => {
    System.normalize(file)
    .then(function(url){
        if (url.substr(url.length - 7, 7) == '.css.js')
        {
            var cssUrl = url.substr(0, url.length - 3);

            System.import('css')
            .then(function(cssPlugin) {
                cssPlugin.fetch({address:cssUrl});
            });
        }
    });
});
capaj commented 8 years ago

@shovemedia this looks brilliant.

divramod commented 7 years ago

@shovemedia can you please say, where i have to put this code?

shovemedia commented 7 years ago

@divramod I've since abandoned this approach for webpack (sorry!) but this was in my top-level main.js wrapped in some simple logic to only be enabled when in development / debugging mode:

    if (typeof SystemJS !== 'undefined' && location.origin.match(/localhost/)) {
        SystemJS.trace = true;
        SystemJS.import('systemjs-hot-reloader').then(function(HotReloader){
//code snippet above
                }
        }
divramod commented 7 years ago

@shovemedia thx for the fast reply and the tipp where to place it.

can you please send me an example/github-link/plunker where you got the css reloading running?

the css isn't refreshing for me, although the event is triggered.