Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Allow passing html-template options for each entry in 'mains' #865

Closed
edmorley opened this issue May 10, 2018 · 5 comments
Closed

Allow passing html-template options for each entry in 'mains' #865

edmorley opened this issue May 10, 2018 · 5 comments
Assignees
Labels
Milestone

Comments

@edmorley
Copy link
Member

For multi-entrypoint projects, it's possible to add multiple entries to the Neutrino mains option, like so:

    mains: {
      index: 'entry-index.js',
      foo: 'entry-foo.js',
      bar: 'entry-bar.js',
    },

However in the web preset, the same html options property is used for each, which means there is no way to give the pages different titles or vary the template used.

For mozilla/treeherder's Neutrino v8 WIP, I'm currently working around this with:

    (neutrino) => {
      const entryHtmlOptions = {
        index: {
          // Page uses custom template instead of `html-webpack-template`'s
          template: 'index.html',
          inject: true,
        },
        foo: {
          title: 'Custom Page Title',
        },
        bar: {
          title: 'Another Page Title',
        },
      };
      Object.entries(entryHtmlOptions).forEach(([entry, options]) =>
        neutrino.config
          .plugin(`html-${entry}`)
          .tap(([defaultOptions]) => [{ ...defaultOptions, ...options }]));
    }

...but it seems likely that anyone using Neutrino's multi-entrypoint support is having to do something similar - so perhaps should be supported natively.

One way of doing so might be to permit the main's value to be an object (whilst still supporting the string form for the simple case). ie:

    mains: {
      index: {
        source: 'entry-index.js',
        html: {
          template: 'index.html',
          inject: true,
        },
      },
      foo: {
        source: 'entry-foo.js',
        html: {
          title: 'Custom Page Title',
        },
      },
      bar: {
        source: 'entry-bar.js',
        html: {
          title: 'Another Page Title',
        },
      },
    },

@mozilla-neutrino/core-contributors - thoughts?

@eliperelman
Copy link
Member

I like the approach, but would probably hope for a flatter structure rather than nesting in an html property. Maybe we should consider dropping html-webpack-template before doing this?

edmorley added a commit that referenced this issue Jun 7, 2018
By default `html-loader@0.x` has a default `attrs` of `['img:src']`,
which means only `<img src="...">` tags are followed when parsing
the HTML:
https://github.com/webpack-contrib/html-loader/blob/v0.5.5/README.md#usage
https://github.com/webpack-contrib/html-loader/blob/v0.5.5/index.js#L29

With this change, favicons are included too, and have all the benefits
of being included in the webpack build - such as being being inlined
by url-loader (if small enough), or else being copied to the output
directory automatically and given hashed filenames.

This matches the default that will be used in `html-loader` v1.0.0:
webpack-contrib/html-loader#17

...and saves projects from having to resort to the manual Neutrino
API to adjust the options used by `html-loader` (see #865).
@edmorley edmorley added this to the v9 milestone Jul 1, 2018
@tangdw
Copy link

tangdw commented Aug 8, 2018

like this
vue-cli3-pages

@edmorley edmorley self-assigned this Aug 20, 2018
edmorley added a commit that referenced this issue Aug 21, 2018
This adds support for defining each entry point in `mains` as an
object, where the path to the entry point is now defined under an
`entry` property, and any other properties can be used by presets
for page-specific options. (The short form using a string is still
supported.)

In the case of `@neutrinojs/web` (and presets that inherit from it),
these additional properties are then used to override the options
passed to `html-webpack-plugin`, allowing for page-specific
customisation of the generated HTML template.

For example:

```
module.exports = {
  options: {
    mains: {
      index: {
        entry: './index',
        // Options here take priority over the preset's `html` options below.
        title: 'Site Homepage',
      },
      admin: {
        entry: './admin',
        title: 'Admin Dashboard',
      },
      account: {
        entry: './user',
        inject: true,
        template: './my-custom-template.html',
      },
    }
  },
  use: ['@neutrinojs/web', {
    // Customise the defaults used for all pages.
    html: {
      minify: false,
    }
  }]
}
```

For a list of the available `html-webpack-plugin` options, see:
https://github.com/jantimon/html-webpack-plugin#options

Fixes #865.
@thany
Copy link

thany commented Aug 8, 2019

Exactly what I need, but if I use the entryHtmlOptions approach, how do I access those options in my mains? I was hoping they would go into process.env or even straight into window, but they are nowhere to be found... So how to use them? @edmorley

@timkelty
Copy link
Contributor

timkelty commented Aug 9, 2019

@thany additional properties for each main are passed directly to html-webpack-plugin and used to build the templates (example usage: #1029 (comment)).

If you are building your own templates and want access to those, they should be available as htmlWebpackPlugin.options within the template (https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates).

It sounds like you're trying to use them in your entry point, but this issue/PR solely deals with passing options to html-webpack-plugin.

As for setting things on process.env, you can do that with the EnvironmentPlugin via the env option in @neutrinojs/web. Similarly you can set window with other webpack plugins…but I don't think there's an out-of-the-box way to configure those plugins differently per main. They are for your entire webpack build.

@thany
Copy link

thany commented Aug 16, 2019

I must say I'm not that savvy with neutrino/webpack, but you're absolutely right. I got around it, and this was just a kick in the right direction. Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

5 participants