shellscape / webpack-manifest-plugin

webpack plugin for generating asset manifests
MIT License
1.43k stars 186 forks source link

Store custom hook in WeakMap for Webpack 5 compatability #191

Closed ian-craig closed 4 years ago

ian-craig commented 4 years ago

From Webpack 5, it's no longer possible to just assign new custom hooks onto the compiler.hooks object. The recommendation is to store these in a WeakMap keyed off the compiler instance.

https://github.com/webpack/changelog-v5/blob/master/README.md#hook-object-frozen

Running plugin v2.0.4 in Webpack v5.0.0-alpha.26 gives the following error:

TypeError: Cannot read property 'call' of undefined
    at ManifestPlugin.<anonymous> (...\node_modules\webpack-manifest-plugin\lib\plugin.js:191:53)
    at Hook.eval [as callAsync] (eval at create (...\node_modules\webpack\node_modules\tapable\lib\HookCodeFa
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (...\node_modules\webpack\node_modules\tapable\lib\Hook.js:18
    at Compiler.emitAssets (...\node_modules\webpack\lib\Compiler.js:507:19)
    at process.nextTick (...\node_modules\webpack\lib\Compiler.js:302:10)
    at process._tickCallback (internal/process/next_tick.js:61:11)

This change just moves the storage of webpackManifestPluginAfterEmit into a WeakMap.

Tested in Webpack v4.35.3 and v5.0.0-alpha.26.

Fixes #186

Update: I did a second pass over this and created a static method to expose custom hooks to other plugins, following the recommended approach and a similar implementation to fork-ts-checker-webpack-plugin.

I'd expect other plugins to use hooks as follows:

ManifestPlugin.getCompilerHooks(compiler).afterEmit.tap('ManifestPlugin', (manifest) => {
   //...
});

This new behavior is supported for Webpack 4+, but I've also preserved compiler.hooks.webpackManifestPluginAfterEmit in Webpack 4

mastilver commented 4 years ago

Hi @ian-craig

Could you update .travis.yml to test webpack@5 ?

codecov-io commented 4 years ago

Codecov Report

Merging #191 into master will not change coverage. The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #191   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           3      4    +1     
  Lines         115    129   +14     
  Branches       22     26    +4     
=====================================
+ Hits          115    129   +14
Impacted Files Coverage Δ
lib/plugin.js 100% <100%> (ø) :arrow_up:
spec/helpers/webpack-version-helpers.js 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 421fa29...8648e73. Read the comment docs.

gaurav5430 commented 3 years ago

Does this change the syntax for usage of the webpackManifestPluginAfterEmit in the consumers as well ?

We have been using this syntax in our own plugin to tap the manifest generation:

compiler.hooks.webpackManifestPluginAfterEmit.tap with version 2.2.0

do we need to change this ?