-
Notifications
You must be signed in to change notification settings - Fork 512
Reloading extracted css with hot module replacement #30
Comments
Why use |
Good point! :) |
@andreypopp how do you handle dev/production configuration changes? Just curious how other people do it, I'm using the |
@nickdima just |
@andreypopp it seems that if I require my css from my main js entry point the HMR works, but not if I want to have it as a separate bundle and load it via a script tag. |
These are my entries: entry:
common: ['webpack-dev-server/client?http://localhost:3001', 'webpack/hot/dev-server', './client.coffee']
styles: ['webpack-dev-server/client?http://localhost:3001', 'webpack/hot/dev-server','./app.scss'] If I leave only each one of them HMR works for any of them, but if I put them both HMR works only for |
We need to change this https://github.com/webpack/webpack/blob/master/hot/dev-server.js#L39 window.onmessage = function(event) { to something like Do you want to send a PR? |
I'll take a look. I'm a bit in the dark there, just starting out with HMR :) |
as workaround you can do:
Best is to use only one entry per HTML page... |
My goal is to have the |
@sokra I investigated the problem and now I see what you're saying about |
@nickdima Sorry if I'm not following something, but did you get HMR with the extract plugin working? Can you provide an example config? |
No, I just use the script loaded css in dev and extracted only in production. |
@nickdima any luck with this yet with Extract plugin? Shouldn't the CSS just reload and the browser pick up the changes or link tags don't work that :) |
@mmahalwy This doesn't work. You shoudn't use the extract-text-webpack-plugin in development. Better thread the extract-text-webpack-plugin as production optimiation for the
|
@nickdima i'm trying to get something similar working. Would you mind linking your |
@rxtphan it depends on you setup, what we did is we have an entry point for all our css (we use sass imports) that uses the |
@rxtphan @mmahalwy @mysterycommand et all, I ran into this "bug" too, wondering why my styles weren't reloading. Here's a solution that works:
|
After a while of googling, I came to the realization that having live-reload (or hmr), with sass, with source maps, is currently not possible with webpack. Can anyone please confirm this, or point me in the right direction on how to get this working? If I don't use extract-text-webpack-plugin, I can get hmr working just fine, but since that just puts the CSS inline in a |
Doesn't |
@sokra that does not work, however messing around a bit with it, it turns out that adding sourceMap to both sass, and css loader works: {
test: /\.scss$/,
loaders: [ 'style', 'css?sourceMap', 'sass?sourceMap' ]
} It does produce a bit of a weird output in Chrome about which file the rules belong to, but clicking on the line does reveal the correct scss file (with the correct line number). I'll open an issue on sass-loader, so that it has the correct information on how to enable source maps, so people don't get misled here. Thanks a lot! |
When I use autoprefixer-loader it produces even more weird source path: Here is my webpack config:
|
@sokra seems like saying "don't use extract-text in development" isn't a great solution for a few reasons: (1) There are big debugging benefits to having separate CSS files that I want on dev Would be great to get Hot Module Reload working from a stylesheet link tag. @nickdima looks like you solved the multiple hot server entry points, was there another reason you weren't able to get this working? |
None of these last few suggestions worked for me mainly due to webpack 2 not seeing that my style files were true dependencies of any javascript that required them. if (module.hot) {
var hotEmitter = require("webpack/hot/emitter");
hotEmitter.on("webpackHotUpdate", function(currentHash) {
document.querySelectorAll('link[href][rel=stylesheet]').forEach((link) => {
const nextStyleHref = link.href.replace(/(\?\d+)?$/, `?${Date.now()}`)
link.href = nextStyleHref
})
})
} |
@nathanboktae it works well for me, except it refreshes the styles each time I make a change regardless if it is a change in javascript or css. I am wondering if there is a way to check if change was made in css. Also, in chrome every time I make a change I see an annoying style flash. In firefox there is no such flash - it is all good. |
@mieszko4 In order to avoid that annoying style flash ( aka FOUT ). You could combine the solution I gave above with the event based solution provided by @nathanboktae like this: if (module.hot) {
const hotEmitter = require("webpack/hot/emitter");
const DEAD_CSS_TIMEOUT = 2000;
hotEmitter.on("webpackHotUpdate", function(currentHash) {
document.querySelectorAll("link[href][rel=stylesheet]").forEach((link) => {
const nextStyleHref = link.href.replace(/(\?\d+)?$/, `?${Date.now()}`);
const newLink = link.cloneNode();
newLink.href = nextStyleHref;
link.parentNode.appendChild(newLink);
setTimeout(() => {
link.parentNode.removeChild(link);
}, DEAD_CSS_TIMEOUT);
});
})
} Basically what this does, is to insert new links with the updated |
Thanx @helly0d! Your solution works well if there are no custom fonts in my case. I looked more into the problem and I realized that the flash is actually caused by redownloading custom fonts that I have defined in my scss. |
It seems that chrome does not redownload fonts if styles are defined in |
For the maintainers (@bebraw, @TheLarkInn, etc) the principle of keeping development and production as close as possible is extremely important, and a 2.5 year old issue with 85 comments figuring out how to do it is a testament to that. I would be great to have first class HMR support in |
@nathanboktae, @bebraw, @TheLarkInn It is not only about keeping developement and production as close as possible. |
@nathanboktae , well, you are right about second copy, but I don't think it's something bad. I wouldn't say that it's a bad solution. At least it works and doesn't have any issues mentioned in this thread. |
@milworm No, You still have flickering as you're just setting |
@nathanboktae @mieszko4 PR's are welcomed! 😄 ❤️ If you think you can have a fool proof non-breaking solution why not? The thing is that the team itself cannot and will not (currently) invest the time in tackling this vs the laundry list of user voted features that will take priority. However, it sounds that there are quite a few people here who believe that they would like this feature so I would love to see some collaboration and I'm happy to answer internal api questions, and foster any learning needed. |
I think this pr is great for starters: #457 |
@TheLarkInn thanks for recognizing the need, and of course the hardwork on WebPack. 👏 |
@nathanboktae well, the ajax-call takes around 15ms on macbook, so it doesn't seem to be a lot. |
There's no way built into webpack core to reload external stylesheets automatically with HMR. There is a work around however, involving the automatic insertion and removal of link tags within a `hotEmitter.on("webpackHotUpdate"...` function. Many people have looked for a solution for this, but the only answer is located in an issue thread near the very bottom: webpack-contrib/extract-text-webpack-plugin#30 It would be much more efficient and helpful for developers to see the solution directly on the docs page until a workaround is implemented into Webpack core.
Here's my updated loader config This configuration allows for Hot Module replacement with SCSS files using webpack dev server, and extracttextplugin for production mode to emit actual .css files. Dev server mode simulated using extracted CSS because it loads the files in the when I also don't use the stylesUrl property, I import the .scss file outside of the @component decorator so that the styles load in the global context, rather than scoped by component.
app.component.css
|
chain css-hot-loader with ExtractTextPlugin: I now have no Flash of Unstyled Content because of the extracted text, and my css hot reloads on save because of css-hot-loader |
HMR needs
|
I've created https://github.com/sheerun/extracted-loader that is dedicated to this use case. Usage: config.module.rules.push({
test: /\.css$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
/* Your configuration here */
}))
})
config.plugins.push(new ExtractTextPlugin('index.css')) No configuration necessary :) |
got disconnect... pathofexile.com not working :/
…On Sat, Dec 9, 2017 at 9:39 PM, Adam Stankiewicz ***@***.***> wrote:
I've created https://github.com/sheerun/extracted-loader that is
dedicated to this use case. Usage:
config.module.rules.push({
test: /\.css$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
/* Your configuration here */
}))
})
config.plugins.push(new ExtractTextPlugin('index.css'))
No configuration necessary :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#30 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AIAZGgJGLLaYLxuH51tX8UMoK5QevZdSks5s-uHvgaJpZM4CrsZZ>
.
|
Is it possible to have hot module replacement for an extracted css file that I load via a css link tag in my html's head tag?
I have HMR working for my javascript but not sure how to make it work for extracted css.
This is my css related config:
The text was updated successfully, but these errors were encountered: