9

The main goal of this post is to get extra informations about error/warning management while writing a Webpack plugin.

I've seen in the Webpack plug-in documentation that it's possible to pass an err parameter to the timing based plug-in interface (in the callback), but there is no further explanations on how it's impacting Webpack life-cycle, its build process and how to use it. It doesn't explain either if there is a way to manage errors with the other type of plug-in interface.

Anyway as a first try, on a 'emit' life-cycle step, I've tried to either pass to the err parameter a new Error('An error has occurred') or simply a 'An error has occured' value, but in either cases it indeed displayed the given err parameter in the console as is (I.E. sadly without any error specific colouration), and webpack-sev-server got stuck :

  function WpAggregationPlugin() {
    this.startTime = Date.now();
    this.prevTimestamps = {};
  }

  WpAggregationPlugin.prototype.apply = function(compiler) {
    compiler.plugin( 'emit', (compilation, callback) => {

      var changedFiles = Object.keys(compilation.fileTimestamps).filter( watchfile => 
        this.prevTimestamps[watchfile] &&
        (this.prevTimestamps[watchfile] < (compilation.fileTimestamps[watchfile] || Infinity)) )

      // compilation.errors.push(new Error('...'))

      this.prevTimestamps = compilation.fileTimestamps;

      if( changedFiles.length <= 0 ) {
        callback()
      } else {
        process.stdout.write( `File modification detected :\n${JSON.stringify(changedFiles, null, 4)}\n` )
        callback( '...' )
      }
    } );
  };

  module.exports = WpAggregationPlugin;

So it needed an extra callback call the following way in order to have Webpack build process resumed :

  ...
      if( changedFiles.length <= 0 ) {
        callback()
      } else {
        process.stdout.write( `File modification detected :\n${JSON.stringify(changedFiles, null, 4)}\n` )
        callback( '...' )
        callback()       // EXTRA CALL
      }
  ...

Unfortunately, this way, I simply end-up displaying uncoloured strings to stdout without impacting Webpack life-cycle in any way.

What I'm trying to achieve is, upon my error cases, to display red error messages and to prevent the bundle build process to end in a valid state until a new build eventually have my plug-in running without errors.

About warning management I guess it has to be performed either by calling process.stdout.write() with the right colouring directly within the plug-in itself or, feeding some warning collection in the compilation parameter ... but alike what I've reported so far in this SO question ... it's only guessing :p

For the record, I ask this question because I've written a tiny build tool whose goal is to aggregate in one file all translations scattered around in an applications. It's in order to have our clients dealing with a single translation file instead of dozens.

It can be run in a "one shoot" mode or in watch mode, but I guess the best would be to integrate this directly as a plug-in in the Webpack build process.

So feel free to give me your point of view about this "architectural" choice as, been a newcomer to Webpack, I definitely don't embrace the whole potential of it and I'm maybe misleading according to what can/should be done with it (as a side note of course as it's not the main reason of this post ;)

Thanks in advance for your tips and tricks about it ;) !

Lemmy
  • 291
  • 2
  • 12

2 Answers2

19

I've finally sorted this out after half a day of webpack code debugging.

The real deal is to feed the webpack compilation's error collection this way :

compilation.errors.push( new Error( 'explain why the build failed' ) )

And of course don't forget to callback() no matter your plug-in fail or not.

This errors.push will :

  • prevent the webpack-dev-server to deal the bundle
  • have the error message displayed in red on the stdout
  • have the error message reported in the webpack header part on the client/browser side ... instead of your app !!! (if you accessed it thru http://yourDN:yourPort/webpack-dev-server of course)

The latest point is just perfect to enforce your devs to fix there errors before resuming there coding session ;)

Just a pity that webpack documentation is so lame ... I definitely hope the Webpack 2 won't have those puzzling doc drawbacks :p

Lemmy
  • 291
  • 2
  • 12
0

I'm currently writing a Webpack plugin and hit the same issue. I tried looking at some existing plugin for reference, but came to the same conclusion as you: there's no infrastructure for this. Taking extract-text-webpack-plugin as an example:

https://github.com/webpack-contrib/extract-text-webpack-plugin/blob/master/index.js

It basically uses console.warn and throw new Error to handle stuff. You can push errors to the compilation object, but I don't know how that's handled and that's obviously not available to some entry points.

saboya
  • 51
  • 2
  • 3
  • I've finally sorted this out : The real deal is to `compilation.errors.push( new Error( 'explain why the build failed' ) )` and of course don't forget to `callback()` no matter your plug-in fail or not. This `errors.push` will prevent the bundles been dealt by the webpack-dev-server, will be displayed in red on the command line and on top of that if you access to your app thanks to `http://yourDN:yourPort/webpac-dev-server`, you'll have this error reported on client side in the webpack header part. Perfect to force your dev to fix there errors before coding further ;) – Lemmy Mar 05 '17 at 12:06