webpack-version-file icon indicating copy to clipboard operation
webpack-version-file copied to clipboard

File gets deleted when `webpackConfiguration.output.clean` is `true`

Open LukeSavefrogs opened this issue 1 year ago • 1 comments

Problem

When using webpack-version-file in a Webpack configuration with output.clean set to true, the output file gets deleted right after Webpack finishes the compilation.

Workaround

Setting output.clean to false solves the problem.

Maybe is related to #3?

LukeSavefrogs avatar Jan 16 '23 15:01 LukeSavefrogs

The problem is that webpack-version-file writes the output file immediately in its apply() function, instead of waiting until after the directory has been cleaned.

If you are using the clean-webpack-plugin, the clean step is done during the emit Hook (see https://github.com/johnagan/clean-webpack-plugin/blob/master/src/clean-webpack-plugin.ts#L186), which comes later. I'm guessing that output.clean is similar.

In order to fix this problem, we have two options:

  1. Add the version output file to the compilation assets.

  2. Write the file directly (which ensures no other plugins will modify it during their compilations) -- after the clean step has completed. The clean step is done during the emit Hook, so let's use the afterEmit hook. Here's an example (this is overly simplistic and requires that BUILD_ROOT is defined and version is passed in via the constructor):

class VersionPlugin
{
  constructor(version)
  {
    this.version = version;
  }

  apply(compiler)
  {
    compiler.hooks.afterEmit.tap('VersionPlugin', () => {
      require('fs').writeFileSync(path.resolve(BUILD_ROOT, 'version.txt'), this.version);
    });
  }
}

Then, in your build, add new VersionPlugin(version) to the list of plugins. That's what I did.

For more info, take a look at the Hooks documentation or the source code (https://github.com/webpack/webpack/blob/main/lib/Compiler.js), where you can see the code that invokes all the hooks.

joswhite avatar Mar 31 '23 15:03 joswhite