Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webpack hot module replacement: css without refresh

Tags:

So far I've been using livereload so that whenever I change JS or templates, the page refreshes, and when I change CSS, it would hotswap the new CSS without a refresh.

I'm trying out webpack now and nearly got to the same behaviour, with one exception: when the CSS changes, it refreshes the whole window. Is it possible to make it hotswap the CSS without refresh?

Config so far:

var webpackConfig = {
    entry: ["webpack/hot/dev-server", __dirname + '/app/scripts/app.js'],
    debug: true,
    output: {
        path: __dirname + '/app',
        filename: 'scripts/build.js'
    },
    devtool: 'source-map',
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new htmlWebpackPlugin({
            template: __dirname + '/app/index.html',
            inject: 'body',
            hash: true,
            config: config
        }),
        new webpack.ProvidePlugin({
            'angular': 'angular'
        }),
        new ExtractTextPlugin("styles.css")
    ],
    module: {
        loaders: [
            {
                test: /\.scss$/,
                loader: "style!css!sass?includePaths[]=" + __dirname + "/app/bower_components/compass-mixins/lib&includePaths[]=" + __dirname + '/instance/sth/styles&includePaths[]=' + __dirname + '/app/scripts'
            }
        ]
    }
};
like image 410
Bart van den Burg Avatar asked Jun 14 '15 18:06

Bart van den Burg


People also ask

What is Webpack hot module replacement?

Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways: Retain application state which is lost during a full reload. Save valuable development time by only updating what's changed.

What is Webpack_hmr?

Hot Module Replacement (or HMR) is one of the most useful features offered by webpack. It allows all kinds of modules to be updated at runtime without the need for a full refresh. This page focuses on implementation while the concepts page gives more details on how it works and why it's useful.


2 Answers

This is one of the downsides of using ExtractTextPlugin as stated in the project README. You can resolve the issue by splitting up your configuration. Ie. have separate configuration for development without it and one for production with it.

like image 81
Juho Vepsäläinen Avatar answered Oct 02 '22 12:10

Juho Vepsäläinen


There's actually a simple way to do this. I'm using sass-loader with extract-text-plugin that produces css files.

What you need to do is add id to your css include

  <link id="js-style" type="text/css" rel="stylesheet" href="/static/main.css">

Now, you need to ensure when HMR happens you update url with current version/timestamp. You can do this in such way:

import '../style/main.scss'
if (module.hot) {
  module.hot.accept('../style/main.scss', () => {
    const baseStyle = window.document.getElementById('js-style')
    baseStyle.setAttribute('href', '/static/main.css?v=' + new Date().valueOf)
  })
}

So whenever css changes, we'll fix url of css include to reload it.

like image 38
Hatch Avatar answered Oct 02 '22 10:10

Hatch