DEV Community

Cover image for Improving developer experience ( part two ) with Webpack hooks
Nicholas Babu
Nicholas Babu

Posted on

Improving developer experience ( part two ) with Webpack hooks

Inspiration:
Sometimes when working on a large webpack project, your compiler might unwilingly decide to take a water-break|take a breath. Also known us hanging or deadlock, in computer terms; where two or more resources are waiting for a resource to be released so they can continue, but it's not, because of the same reason ( my turn >< no it's my turn ).

You try to reload your page, but your latest changes are still not reflected in the browser ( because your build script is stuck, maybe), so you CTLR + C to kill the watch script and rerun it a fresh.

What if there was a better way to tell, if your watch script has not been running for a while ( because it's stuck ), before doing the CTLR + C > re run script and repeat this over and over.

This blog is about that.

We are going to work on a project from a previous blog, and improve on that for an even better experience. Call it evolution if you may.

Clone the project from GitHub and run yarn : it fails because of an incompatible dev package :), lets remove that for a better alternative:

run yarn remove @squoosh/lib then yarn add sharp -D to install one of the recommended alternative,

Then in the webpack.config.js change ImageMinimizerPlugin.squooshMinify, to ImageMinimizerPlugin.sharpMinify, and re-run our watch script.

Next, lets improve on this.

We're going to create a simple webpack plugin, and tap into one of the compiler hooks; to output the time when the last compile happened.

We can then compare the last compiled at time, with the system time and then decide if we want to kill the watch script or look elsewhere, why the current changes in the source files are not reflected on the browser.

To start with, lets create a file at the root of our project directory named output-time.js. Then create a class named OutPutTime that defines apply as it's prototype method.

This method, contains the compiler as the argument, and with the compiler instance, we have access to it's hooks; which we can tap into.

We're going to tap into the done hook, and in this hook add the code necessary to output the current system time.

Below is the code that goes into this file ( no need to install any dependency, as they're already available or required by webpack ).

const { EOL } = require( 'os' )
const { createColors } = require( 'colorette' )
class OutPutTime {
    apply( compiler ) {
        compiler.hooks.done.tapAsync(
            'OutPutTime',
            ( stats, callback) => {
                const { bold, cyan, magenta } = createColors({ useColor: true })
                const now = new Date( Date.now() ).toLocaleTimeString()
                console.info(EOL)
                console.info(`[output-time] ${ bold( cyan('Last compiled at : ') ) } ${bold( magenta( now ) ) }`)
                console.info(EOL)
                callback()
            }
        )
    }
}

module.exports = OutPutTime
Enter fullscreen mode Exit fullscreen mode

Then at the top of our webpack.config.js require the file const OutPutTime = require("./output-time");

Then include our new plugin along with the new MiniCSSExtractPlugin() like so:

....

plugins: [
        new MiniCSSExtractPlugin(),
        new OutPutTime()
    ],
Enter fullscreen mode Exit fullscreen mode

After this, every time there are file changes, we will get a nice message ( Last compiled at : < compiled date > ) before the output of the information related to our assets ( files ).

Resources:

Top comments (0)