webpack-cleanup-plugin icon indicating copy to clipboard operation
webpack-cleanup-plugin copied to clipboard

Deleting more than it should. Sometimes!!!

Open KpjComp opened this issue 8 years ago • 1 comments

Hi,

I was using this plugin to keep things nice and clean in the dist folder, everything seemed to be working fine. Until at one point I refreshed the browser and got 404, and after digging deeper found out it had deleted more than it should. Unfortunately not sure why this happened as the hash was in the Asset list shown by webpack, and why this only happens sometimes.

One theory is that maybe there is some async calls causing a race condition, eg. I change a file, it compiles, I quickly change back. The hash would have gone back to old, but the delete is still going on and ends up deleting the hash we wanted. But looking at your code, from what I can tell your not using any async calls.

Anyway, I knocked up a simple version, that does this async, and I don't seem to have any issues so far. One advantage I think of doing this async too, is that if a hash does end up re-appearing after a fast re-compile, it might not even get deleted in the first place, as I'm tracking if a re-compile has started and then aborting the delete process. Also there is no rush to delete the files in the first place and I've placed delays in the delete, you could even add options to even delay starting the delete process to say 10 seconds etc.

I'm posting here, as it might be an idea for the maintainer here to implement something similar. Some notes on the code below, it's use async / await to keep things simple, I've used some simple Promise based functions that would be simple re-implement, eg. Promise based, deleteFile & wait.

class CleanUp {
  apply(compiler) {
    let that = this;
    compiler.plugin('compile', () => {
      that.isCompiling = true;
    });
    compiler.plugin('done', async (stats) => {
      that.isCompiling = false;
      if (compiler.outputFileSystem.constructor.name !== 'NodeOutputFileSystem') {
        return;
      }
      const assets = stats.toJson().assets.reduce((a,v) => (a[v.name]=true,a),{});
      const outputPath = compiler.options.output.path;
      assets['records.json'] = true;
      let dir = (await readDir(outputPath)).map((d)=>d.fn);
      for (let l = 0; l < dir.length; l ++) {
        if (that.isCompiling) {
          break;
        }
        let fn = dir[l];
        if (!assets[fn]) {
          await deleteFile(path.join(outputPath, fn));
          await wait(100);
        }
      }
    });
  }
}

KpjComp avatar Sep 15 '17 10:09 KpjComp

I also have this issue, I use WebpackCleanup and then CopyWebpackPlugin, but sometimes the CopyWebpack plugin will result in empty folders as WebpackCleanup somehow runs AFTER the copy was finished.

Cristy94 avatar Nov 16 '17 14:11 Cristy94