diff --git a/hotModuleReplacement.js b/hotModuleReplacement.js new file mode 100644 index 00000000..40bf24fb --- /dev/null +++ b/hotModuleReplacement.js @@ -0,0 +1,36 @@ +function forceRedraw(element) { + var n = document.createTextNode(' '); + var visibility = element.style.visibility; + element.appendChild(n); + element.style.visibility = 'hidden'; + setTimeout(function(){ + element.style.visibility = visibility; + n.parentNode.removeChild(n); + }, 20); +} + +function replaceStylesheet(styleSheet, url) { + // Wait until the extract module is complete + styleSheet.href = url; + setTimeout(function() { + console.log('[HMR]', 'Reload css: ', url); + forceRedraw(document.body); + }, 100); +} + +module.exports = function(compilationHash, outputFilename) { + if (document) { + var styleSheets = document.getElementsByTagName('link'); + for (var i = 0; i < styleSheets.length; i++) { + if (styleSheets[i].href) { + var hrefUrl = styleSheets[i].href.split('?'); + var href = hrefUrl[0]; + var hash = hrefUrl[1]; + if (hash !== compilationHash && href === document.location.origin + '/' + outputFilename) { + replaceStylesheet(styleSheets[i], href + '?' + compilationHash); + break; + } + } + } + } +} diff --git a/index.js b/index.js index 6c886a3f..a86c2515 100644 --- a/index.js +++ b/index.js @@ -298,6 +298,12 @@ ExtractTextPlugin.prototype.apply = function(compiler) { }); compilation.assets[file] = source; chunk.files.push(file); + + // Hot module replacement + extractedChunk.modules.forEach(function(module){ + var originalModule = module.getOriginalModule(); + originalModule._source._value = originalModule._source._value.replace('%%extracted-file%%', file); + }); } }, this); callback(); diff --git a/loader.js b/loader.js index b30d4922..1736a53d 100644 --- a/loader.js +++ b/loader.js @@ -105,8 +105,12 @@ module.exports.pitch = function(request) { }); }); this[__dirname](text, query); - if(text.locals && typeof resultSource !== "undefined") { - resultSource += "\nmodule.exports = " + JSON.stringify(text.locals) + ";"; + if (resultSource !== "undefined") { + if(text.locals) { + resultSource += "\nmodule.exports = " + JSON.stringify(text.locals) + ";"; + } + resultSource += '\nif(module.hot){require("' + require.resolve('./hotModuleReplacement.js') + '")' + + '("' + compilation.hash + '", "%%extracted-file%%");}' } } catch(e) { return callback(e);