stephencookdev / speed-measure-webpack-plugin

⏱ See how fast (or not) your plugins and loaders are, so you can optimise your builds
MIT License
2.42k stars 79 forks source link

Using Proxy of 'compilation' break plugins relies on other Plugin #198

Open icy0307 opened 1 year ago

icy0307 commented 1 year ago

webpack Plugins can provide hooks for other Plugins; take html-webpack-plugin for example, we can write a custom plugin depending on it

// If your plugin is direct dependent to the html webpack plugin:
const HtmlWebpackPlugin = require('html-webpack-plugin');
// If your plugin is using html-webpack-plugin as an optional dependency
// you can use https://github.com/tallesl/node-safe-require instead:
const HtmlWebpackPlugin = require('safe-require')('html-webpack-plugin');

class MyPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
      console.log('The compiler is starting a new compilation...')

      // Static Plugin interface |compilation |HOOK NAME | register listener 
      HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
        'MyPlugin', // <-- Set a meaningful name here for stacktraces
        (data, cb) => {
          // Manipulate the content
          data.html += 'The Magic Footer'
          // Tell webpack to move on
          cb(null, data)
        }
      )
    })
  }
}

module.exports = MyPlugin

However, this kind of plugin ceases to work if using [speed-measure-webpack-plugin](https://github.com/stephencookdev/speed-measure-webpack-plugin) together. Because every time speed-measure-webpack-plugin wrap a plugin, it wraps its inside compilation provide by tap method to a new proxy project. And every time, this object is a new proxy project, instead of returning memorized one.

So plugins that provide other plugins would not be working anymore, because the need compilation object as different keys for different compile processes. Hooks that tapped into would never be found.

/**
 * Returns all public hooks of the html webpack plugin for the given compilation
 *
 * @param {WebpackCompilation} compilation
 * @returns {HtmlWebpackPluginHooks}
 */
function getHtmlWebpackPluginHooks (compilation) {
  let hooks = htmlWebpackPluginHooksMap.get(compilation);
  // Setup the hooks only once
  if (hooks === undefined) {
    hooks = createHtmlWebpackPluginHooks();
    htmlWebpackPluginHooksMap.set(compilation, hooks);
  }
  return hooks;
}
Y-Bingo commented 1 year ago

I've got the same problem.

sxxhlx commented 1 year ago

I've got the same problem too.