terser / html-minifier-terser

actively maintained fork of html-minifier - minify HTML, CSS and JS code using terser - supports ES6 code
https://terser.org/html-minifier-terser
MIT License
376 stars 30 forks source link

Implement a synchronous `minify` method in v6+ #78

Closed xavierfoucrier closed 3 years ago

xavierfoucrier commented 3 years ago

Hi @DanielRuf,

Is there a possibility to implement/bring back a minify() method for doing minification stuff synchronously? In my case, I have a webpack setup that uses html-minifier-terser inside a plugin that call his own hooks synchronously... that's why I am unable to call it asynchronously. I don't want to be "stucked" in the future in version 5+.

I really understand the point of implementing async/await, but it makes the plugin impossible to use in some cases.

Working with node@16.2.0, npm@7.21.1 and html-minifier-terser@6.0.2 at this moment of writing.

DanielRuf commented 3 years ago

Hi @xavierfoucrier,

would an IIFE not work in your case to wrap the async / await part? Generally we can not go back because ot he new terser API which is promise based.

Maintaining two major versions is not an option for me.

Other webpack contributors and maintainers needed the upgrade to terser 5, see https://github.com/terser/html-minifier-terser/issues/46 and the relevant PR at https://github.com/terser/html-minifier-terser/pull/63

Initially I was against the upgrade for several reasons but more and more people where asking when the new version with terser 5 is released.

And also see these related issues in terser: https://github.com/terser/terser/issues/1026 https://github.com/terser/terser/issues/801 https://github.com/terser/terser/issues/772

xavierfoucrier commented 3 years ago

Hi @DanielRuf,

Yes I fully understand your position, same for the terser team and efforts of Alexander Akait to upgrade/improve webpack plugins. This is a very good thing of course.

I have tried a lot of things, but unfortunately, every time I encounter an ERR_INVALID_ARG_TYPE error when compiling:

image

My webpack (short) configuration that work great with v5 looks like this:

module.exports = () => ({
  plugins: [
    new Plugin({
      onEnd: (html) => {
        return HtmlMinifierTerser.minify(html);
      }
    }),
  ],
});
DanielRuf commented 3 years ago
new Plugin({

It depends on what your plugin does but there are also the compiler hooks, tapAsync / tapPromise and so on.

So far I've never seen onEnd so you might have what the Plugin does with this parameter.

https://webpack.js.org/contribute/writing-a-plugin/#synchronous-hooks

DanielRuf commented 3 years ago

You will probably have to resolve the promise and use a callback.

xavierfoucrier commented 3 years ago

It was just a base example. It's the HandleBars plugin with the onBeforeSave build in hook. It compiles Handlebars templates and at the end I want to do custom stuff, like minification.

xavierfoucrier commented 3 years ago

Hi @DanielRuf,

Even with a regular Promise or async/await it doesn't seem's to work...

Short configuration to show you:

const HandlebarsPlugin = require('handlebars-webpack-plugin');

module.exports = () => ({
  ...
  plugins: [
    new HandlebarsPlugin({
      onBeforeSave: (Handlebars, html) => {
        return Promise.resolve(HtmlMinifierTerser.minify(html));
      }
    }),
  ],
});

May be it's related to how HandlebarsPlugin manage the hook's call...

sibiraj-s commented 3 years ago

You may need HtmlMinimizerWebpackPlugin rather than consuming this package directly.

module.exports = {
  plugins: [
    new HandlebarsPlugin()
  ],
  optimization: {
    minimizer: [
      new HtmlMinimizerPlugin({
        test: /\.foo\.html/i,
        minimizeroptions: {} // you can pass the options for html-minifier-terser here.
      }),
    ],
  },
};
xavierfoucrier commented 3 years ago

Hi @sibiraj-s,

I noticed yesterday you joined the html-minifier-terser team, that's cool :+1:

Unfortunately, I already had a look at HtmlMinimizerWebpackPlugin, but he doesn't seem to be "compatible" with HandlebarsPlugin: the outputted HTML is still not minified properly at the end, and the only way I found was to use the onBeforeSave hook to fix.

Anyway, I am closing the issue - because as explained by @DanielRuf Terser won't implement sync again - and I will stick with v5 until I find a way to improve this part in my project.

Thanks everyone, and good luck @DanielRuf for the next adventures! :wink: