Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading to HtmlWebpackPlugin 4.0.4 makes HtmlWebpackExcludeAssetdPlugin stop to work #18

Open
jseto opened this issue Apr 6, 2020 · 12 comments

Comments

@jseto
Copy link

jseto commented Apr 6, 2020

Upgrading to HtmlWebpackPlugin 4.0.4 makes HtmlWebpackExcludeAssetdPlugin stop to work

Running on:

  • Ubuntu v18.04.4
  • Node v10.15.3
  • Webpack v4.42.1

This is the stack output

Error: The expected HtmlWebpackPlugin hook was not found! Ensure HtmlWebpackPlugin is installed and was initialized before this plugin. at HtmlWebpackExcludeAssetsPlugin.applyCompilation (/home/jseto/programing-projects/web/wish-to-go/node_modules/html-webpack-exclude-assets-plugin/index.js:25:13) at SyncHook.eval [as call] (eval at create (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1) at SyncHook.lazyCompileHook (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/Hook.js:154:20) at Compiler.newCompilation (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Compiler.js:631:26) at hooks.beforeCompile.callAsync.err (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Compiler.js:667:29) at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1) at AsyncSeriesHook.lazyCompileHook (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/Hook.js:154:20) at Compiler.compile (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Compiler.js:662:28) at compiler.hooks.watchRun.callAsync.err (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Watching.js:77:18) at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1) at AsyncSeriesHook.lazyCompileHook (/home/jseto/programing-projects/web/wish-to-go/node_modules/tapable/lib/Hook.js:154:20) at Watching._go (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Watching.js:41:32) at Watching.compiler.readRecords.err (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Watching.js:33:9) at Compiler.readRecords (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Compiler.js:529:11) at new Watching (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Watching.js:30:17) at Compiler.watch (/home/jseto/programing-projects/web/wish-to-go/node_modules/webpack/lib/Compiler.js:244:10)

@salsager
Copy link

salsager commented Apr 7, 2020

I've the same issue. I downgraded to html-webpack-plugin@3.2.0 and it works fine.

@tapz
Copy link

tapz commented Apr 12, 2020

I have the same problem and downgrading html-webpack-plugin to 3.2.0 helps.

Looks like the last changes to this plugin have been done 2 years ago, so I don't expect this to be fixed. Probably a good idea to find an alternative.

@tapz
Copy link

tapz commented Apr 12, 2020

The breaking change in html-webpack-plugin 4.0.0 probably is this:

hooks: The html-webpack-plugin doesn't add its hooks to the compilation object anymore

@devlegacy
Copy link

devlegacy commented Apr 14, 2020

Here a quick solution to the problem, you can change the plugin index.js file in the node_modules folder
At the moment I am handling it.

Tested with package.json

"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
// HtmlWebpackExcludeAssetsPlugin / index.js
'use strict';
var assert = require('assert');
const HtmlWebpackPlugin = require('html-webpack-plugin');

function HtmlWebpackExcludeAssetsPlugin (options) {
  assert.equal(options, undefined, 'The HtmlWebpackExcludeAssetsPlugin does not accept any options');
  this.PluginName = 'HtmlWebpackExcludeAssetsPlugin';
}

HtmlWebpackExcludeAssetsPlugin.prototype.apply = function (compiler) {
  if ('hooks' in compiler) {
    // v4 approach:
    compiler.hooks.compilation.tap(this.PluginName, this.applyCompilation.bind(this));
  } else {
    // legacy approach:
    // Hook into the html-webpack-plugin processing
    compiler.plugin('compilation', this.applyCompilation.bind(this));
  }
};

HtmlWebpackExcludeAssetsPlugin.prototype.applyCompilation = function applyCompilation (compilation) {
  var self = this;
  if ('hooks' in compilation) {
    // If our target hook is not present, throw a descriptive error
    if (HtmlWebpackPlugin.getHooks) {
      HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tapAsync(
        this.PluginName,
        registerCb
      );
    } else {
      if (!compilation.hooks.htmlWebpackPluginAlterAssetTags) {
        throw new Error('The expected HtmlWebpackPlugin hook was not found! Ensure HtmlWebpackPlugin is installed and' +
          ' was initialized before this plugin.');
      }
      compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync(this.PluginName, registerCb);
    }
  } else {
    compilation.plugin('html-webpack-plugin-alter-asset-tags', registerCb);
  }
  function registerCb (htmlPluginData, callback) {
    var excludeAssets = htmlPluginData.plugin.options.excludeAssets;
    // Skip if the plugin configuration didn't set `excludeAssets`
    if (!excludeAssets) {
      if (callback) {
        return callback(null, htmlPluginData);
      } else {
        return Promise.resolve(htmlPluginData);
      }
    }

    if (excludeAssets.constructor !== Array) {
      excludeAssets = [excludeAssets];
    }

    // Skip invalid RegExp patterns
    var excludePatterns = excludeAssets.filter(function (excludePattern) {
      return excludePattern.constructor === RegExp;
    });

    var result = self.processAssets(excludePatterns, htmlPluginData);
    if (callback) {
      callback(null, result);
    } else {
      return Promise.resolve(result);
    }
  }
};

HtmlWebpackExcludeAssetsPlugin.prototype.isExcluded = function (excludePatterns, assetPath) {
  return excludePatterns.filter(function (excludePattern) {
    return excludePattern.test(assetPath);
  }).length > 0;
};

HtmlWebpackExcludeAssetsPlugin.prototype.processAssets = function (excludePatterns, pluginData) {
  var self = this;
  var body = [];
  var head = [];
  let styles = [];
  let scripts = [];
  // console.log(pluginData.plugin);
  // console.log(pluginData);

  if( pluginData.head) {
    pluginData.head.forEach(function (tag) {
      if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
        head.push(tag);
      }
    });
    pluginData.body.forEach(function (tag) {
      if (!tag.attributes || !self.isExcluded(excludePatterns, tag.attributes.src || tag.attributes.href)) {
        body.push(tag);
      }
    });
    return { head: head, body: body, plugin: pluginData.plugin, chunks: pluginData.chunks, outputName: pluginData.outputName };
  }
  // pluginData.assetTags.styles = pluginData.assetTags.styles.filer(style => );
  pluginData.assetTags.styles.forEach(function (style) {
    if (!style.attributes || !self.isExcluded(excludePatterns, style.attributes.src || style.attributes.href)) {
      styles.push(style);
    }
  });
  pluginData.assetTags.scripts.forEach(function (script) {
    if (!script.attributes || !self.isExcluded(excludePatterns, script.attributes.src || script.attributes.href)) {
      scripts.push(script);
    }
  });
  pluginData.assetTags.styles = styles;
  pluginData.assetTags.scripts = scripts;

  console.log(pluginData.plugin.assetJson);
  return pluginData;


};

module.exports = HtmlWebpackExcludeAssetsPlugin;

@ianwalter
Copy link

@devlegacy Maybe you could submit a PR?

@iongion
Copy link

iongion commented Apr 29, 2020

Nice work!

@swimmadude66
Copy link

Hey all, I went ahead and made a drop-in replacement for this module at here which is compatible with latest webpack and html-webpack-plugin. I've developed a couple other plugins for html-webpack-plugin, so this one should be backwards compatible and support the exact same configuration as the current exclude-assets plugin. Check it out if you want, and please let me know if you find any issues or incompatibilities with the current config.

@jseto
Copy link
Author

jseto commented May 1, 2020

@swimmadude66 I had a look and looks promising. I will test it thoroughly and give feedback here.

I would prefer a PR to join the community netiquette, but I understand that if the original author didn't answer to this issue, a PR would be useless.

@swimmadude66
Copy link

I agree 100%. When I saw the last commit to this project was 2 years ago, I decided to work on a replacement just in case. No pressure to use mine, and I am not trying to claim its any better (in fact ideally it should be have the exact same way).

@ianwalter
Copy link

Yea I ended up just writing my own but haven't published it yet: https://github.com/ianwalter/exclude-assets-plugin/

@jseto
Copy link
Author

jseto commented May 1, 2020

Ok, thanks to @swimmadude66 and @ianwalter.

I'm thinking to close this issue since there are replacing projects from you both. What do you think?

@ianwalter don't forget to fill the readme ;)

@renaldas-kerpe-arria
Copy link

renaldas-kerpe-arria commented Nov 12, 2021

If anyone is still looking for a fix, switch to using html-webpack-skip-assets-plugin . Kudos to @swimmadude66 for implementing a replacement, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants