Search code examples
webpackwebpack-2

How to run clean-webpack-plugin only when Flow compilation success?


I'm using clean-webpack-plugin to remove the /dist folder just before building and only when the compilation phase with Flow success.

The problem I have is that the clean plugin runs even when Flow throws error.

enter image description here

Is that possible to fix that (I mean when there is a compilation error, do not remove the "dist" folder)?

./src/app.js

function init(a: number) {
    //...
}
init("2");

./webpack.config.json

const path = require("path");
const webpack = require("webpack");
const flowTypeLoaderPlugin = require("flowtype-loader/plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = [{
    entry : "./src/app.js",
    output : {
        filename : "build.js",
        path : path.resolve(__dirname, "dist")
    },
    module : {
        loaders : [
            /*{
                test: /\.js$/,
                enforce: "pre",
                use: CleanWebpackPlugin(["dist"], {
                    root: "/dist",
                    verbose: true,
                    dry: true,
                    "watch": true
                    })
            },*/
            {
                test : /\.js$/,
                loader : "flowtype-loader",
                enforce : "pre",
                exclude : /node_modules/
            },
            {
                test : /\.jsx?$/,
                enforce : "pre",
                loader : "remove-flow-types-loader",
                include : path.join(__dirname, "src")
            }
        ]
    },
    plugins : [
        new flowTypeLoaderPlugin({cwd : path.resolve(__dirname, "src"), failOnError : true}),

        //Empty "dist" folder
        new CleanWebpackPlugin(["dist"], {
            root: "/",
            verbose: true,
            dry: true,
            "watch": true
        })
    ]
}];

Solution

  • One way this could be solved, is to modify the CleanWebpackPlugin's code by adding a "should-emit" condition. It has worked for me but I am not sure if it works in every possible case:

    CleanWebpackPlugin.prototype.apply = function(compiler) {
      var _this = this;
      if (compiler === undefined) {
        return clean.call(_this);
      } else {
        compiler.plugin("should-emit", compilation => {
          if (_this.options.watch) {
            compiler.plugin("compile", function(params) {
              clean.call(_this);
            });
          } else {
            return clean.call(_this);
          }
        });
      }
    };
    

    This also requires that you use another plugin in your webpack config file: NoEmitOnErrorsPlugin