HMR: See Changes without Reloading

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

If you use Webpack's dev-server, then as soon as it detects a change, our page automatically reloads. Cool... but not cool enough! Find your terminal, hit Control + C to stop Encore, then re-run the dev server with a --hot option.

yarn dev-server --hot

That stands for hot module replacement. Once that finishes... I'll move over and reload the page one time just to be safe.

Let's do the same trick: add two exclamation points, then quick! Go back to the browser! Woh! It's there... but I didn't even see it reload! And no matter how fast you are, you'll see the update but you'll never see a page refresh: it's just not happening anymore! How cool is that? Webpack is able to dynamically update the JavaScript without reloading. It even keeps any Vue data the same.

This hot module replacement thing doesn't work with all JavaScript, but it does work well with Vue and React.

Disabling CSS Extraction

But... there's one tiny problem. Don't worry it's not a big deal. Back in our editor, at the bottom, let's make a CSS change: I'm pretty sure a designer just told me that the hover background should be pink.

This time, back on the browser, hmm: the style did not update. But if we refresh, it is there. HMR isn't working for styles.

This is easy to fix by disabling a feature in Encore. Let me show you. Open up webpack.config.js and go all the way to the bottom so we can use an if statement. Here, say if not Encore.isProduction() - a nice flag to see if we're building our assets for production or not - then Encore.disableCssExtraction().

... lines 1 - 91
if (!Encore.isProduction()) {
Encore.disableCssExtraction();
}
... lines 95 - 97

CSS extraction means that any CSS that Webpack finds should be extracted into an external CSS file. That's why a products.css file is being output. When you disable CSS extraction, it tells Webpack not to do this anymore. Instead, it embeds the CSS into the JavaScript. Then, when the JavaScript loads, it adds the CSS as style tags on the page.

I'll explain that a bit more in a minute... but let's see how our page changes first. Because we updated our Webpack config, at your terminal, stop Encore and restart it:

yarn dev-server --hot

Now, refresh the page. Did you see that? It looks the same, but it was unstyled for just a second. If you view the HTML source, there are no CSS link tags anymore. The CSS is being added by our JavaScript files. And because it takes a moment for those to load, our page looks ugly for an instant.

Two important things about this. First, disabling CSS extraction should only ever be done in dev mode: you always want real CSS files on production. And second, the only reason we're going to all the trouble of disabling CSS extraction at all, is because hot module replacement only works when it's disabled. Hopefully, someday, that won't be the case... and we won't need to do this.

The end result is pretty sweet though. Our hover links are still pink but now let's change them to green. And... yes! You could see it change from pink to green almost instantly. If we remove the extra background entirely... that time it was faster than me!

I'm going to do the rest of the tutorial using the dev-server with hot module replacement because I love it! But it did require some work - like using http:// or getting the ssl certificate setup and disabling CSS extraction.

Your situation may require even more work. If it does, consider using yarn watch instead. The dev-server is supposed to make your life easier. If it doesn't leave it behind.

Next, let's really start organizing our app - and making it more realistic - by splitting our code into several new components.

Leave a comment!

This course is also built to work with Vue 3!

What JavaScript libraries does this tutorial use?

// package.json
{
    "devDependencies": {
        "@symfony/webpack-encore": "^0.30.0", // 0.30.2
        "axios": "^0.19.2", // 0.19.2
        "bootstrap": "^4.4.1", // 4.5.0
        "core-js": "^3.0.0", // 3.6.5
        "eslint": "^6.7.2", // 6.8.0
        "eslint-config-airbnb-base": "^14.0.0", // 14.1.0
        "eslint-plugin-import": "^2.19.1", // 2.20.2
        "eslint-plugin-vue": "^6.0.1", // 6.2.2
        "node-sass": "^4.13.0", // 4.14.1
        "regenerator-runtime": "^0.13.2", // 0.13.5
        "sass-loader": "^8.0.0", // 8.0.2
        "vue": "^2.6.11", // 2.6.11
        "vue-loader": "^15.9.1", // 15.9.2
        "vue-template-compiler": "^2.6.11", // 2.6.11
        "webpack-notifier": "^1.6.0" // 1.8.0
    }
}