brunocodutra / webapp-webpack-plugin

[DEPRECATED] use favicons-webpack-plugin instead
https://www.npmjs.com/package/webapp-webpack-plugin
MIT License
125 stars 17 forks source link

Ability to tell HtmlWebpackPlugin to use separate WebApp webpack plugins #136

Closed luislobo closed 5 years ago

luislobo commented 6 years ago

I currently have two separate HtmlWebpackPlugin configurations, that generates two similar but different index.html files (one for each theme, and in the future could be more). Is it possible to configure WebApp WebPack plugin so I can also have two instances, each one tied to one of the HtmlWebPack plugins?

The idea is basically to generate different favicons for different index.html's as each one has it's own theme and css.

brunocodutra commented 6 years ago

This feature doesn't exist yet, but does seem reasonable. Now I wonder what's the best way to declare this relationship, any ideas?

luislobo commented 6 years ago

I had some ideas:

brunocodutra commented 6 years ago

Adding arbitrary stuff to other plugins' config is bad practice. With that respect the second option seems better, but that would likely shift to the end user the responsibility of adding arbitrary keys in html-webpack-plugin.

luislobo commented 6 years ago

@brunocodutra that would be OK. A user could use "title" for example to filter things out or other properties up to them

brunocodutra commented 6 years ago

True, it's certainly the better of the two options. Would you be interested in sending a PR for that?

luislobo commented 6 years ago

I was trying to, but got lost in the webpack plugin world... It would take me considerable time to start figuring out, specially since now the whole plugin process has been "redone", it's hard to find out a good source of truth for all of it.

brunocodutra commented 6 years ago

@luislobo sorry for the delay, I've been away for the past weeks.

This is the line you're looking for, there you have access to htmlPluginData.plugin.options which you can pass on to the predicate that decides wether to inject meta tags.

Your proposal essentially extends the current behavior, which means you can simply default the custom predicate to htmlPluginOptions => htmlPluginOptions.inject && htmlPluginOptions.favicons !== false in case it's not set by the user, thus keeping it backwards compatible, does that make sense?

luislobo commented 6 years ago

@brunocodutra No problem about the delay, each one does this at their own pace :) About what you mention, I knew about that behavior, but the problem/proposal here is a way to tell, in one single webpack config, that has two (or more) htmlPlugins, a webApp plugin to each one of them, so that there is a "relationship" between htmlPlugin1 (for example backend UI) and webApp1 (the backend webApp resources and config), and htmlPlugin2 with webApp2. In our case, it's the same app, but they belong to two different verticals, thus, they have different CSS+icon pack.

brunocodutra commented 6 years ago

@luislobo I was 100% sure I had answered, but alas I must have forgotten to send it.

What I was trying to say is that the behavior you describe may be implemented by extending the current logic that decides whether to inject html or not.

Essentially you could replace

const htmlPluginDataInject  = htmlPluginData.plugin.options.inject && htmlPluginData.plugin.options.favicons !== false;
if ( htmlPluginDataInject || this.options.inject === 'force') {
    // ...
}

by something like

const appliesToHtmlPlugin  = this.options.appliesTo(htmlPluginData.plugin);
if (appliesToHtmlPlugin) {
    // ...
}

where appliesTo is a user provided predicate that, given a specific instance of HtmlWebpackPlugin, decides whether to inject tags or not, for example

plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html',
    }),
    new WebappWebpackPlugin({
        logo: './src/logo.svg',
        appliesTo: htmlPlugin => htmlPlugin.options.template === './src/index.html',
    }),
],

If not set, appliesTo could default to the current behavior

htmlPlugin => htmlPlugin.options.inject && htmlPlugin.options.inject.favicons !== false

Does that work for your use case?

brunocodutra commented 6 years ago

A step further could even be to overload the already existing inject option, which besides a boolean or the string 'force', could also take the predicate described above.

luislobo commented 6 years ago

I'm totally fine with any of these approaches :)

brunocodutra commented 5 years ago

To summarize the discussion so far, this feature request proposes the configuration below would be valid and result in two separate html files, only one of which would have favicons injected as described by the predicate specified in inject.

plugins: [
    new HtmlWebpackPlugin({
        template: 'a.html.tmpl',
        filename: 'a.html',
    }),
    new HtmlWebpackPlugin({
        template: 'b.html.tmpl',
        filename: 'b.html',
    }),
    new WebappWebpackPlugin({
        logo: 'logo.svg',
        ibject: htmlPlugin => htmlPlugin.options.filename === 'a.html',
    }),
],
luislobo commented 5 years ago

Yes (you have a typo in the code, ibject instead of inject)