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

Add support for multiple entry-points #367

Closed
edmorley opened this issue Oct 20, 2017 · 7 comments
Closed

Add support for multiple entry-points #367

edmorley opened this issue Oct 20, 2017 · 7 comments
Milestone

Comments

@edmorley
Copy link
Member

edmorley commented Oct 20, 2017

In #326 the ability to manually use multiple instances of certain types of middleware (including neutrino-middleware-html-template) was added, which helped reduce the boilerplate mentioned there.

However configuring Neutrino to use multiple entry-points is still pretty painful, due to the number of other parts of the build that reference neutrino.options.entry.

For example one has to:

  1. Remove or modify the existing index entrypoint
  2. Remove or modify the existing html plugin (from neutrino-middleware-html-template)
  3. Create entrypoints and HTML plugins for each desired page, remembering to set the chunks option to html-webpack-plugin correctly (ie: using the same hardcoded vendor/runtimes names as in neutrino-middleware-chunk. These names have changed between Neutrino versions, so having to keep them in sync is a pain).
  4. If using neutrino-middleware-dev-server (such as via neutrino-preset-{react,web}, remember to prepend webpack/hot/dev-server (if options.hot) or else webpack-dev-server/client to each entrypoint.
  5. If using neutrino-preset-react, remember to prepend react-hot-loader/patch to each entrypoint.
  6. If using neutrino-middleware-pwa remember to append the relevant PWA script.

...plus account for any other customisations that third-party middleware might make.

This results in a lot of boilerplate, and increases the potential for it to get out of sync with Neutrino.

I was thinking perhaps the Neutrino API could be made to support neutrino.options.entry being either a string or an object, with the string case behaving as it does now, and the object being used like so:

  options: {
    entry: {
      index: './index.js',
      foo: './foo.js',
      bar: './bar.js'
    }
  }

The middleware would then be made to iterate the entrypoints when making modifications. For example neutrino-middleware-html-template would act as it does now, except use plugin names of html-index, html-foo etc, and also set the chunks property correctly. And neutrino-preset-react would add the react hot loader to all entrypoints etc.

One question would be whether all consumers of neutrino.options.entry would have to handle both forms, or whether internally the string shorthand form should get converted to the object form with just one index key.

Thoughts?

@eliperelman
Copy link
Member

I like this idea, but I am concerned about the precedent for an inconsistent entry. At the least, this should probably be normalized into an object, but maybe we can do better with a more explicit API?

neutrino.options.entries
  .add('index.js')
  .add('otherpage.js');

// Then entry consumers can always iterate over all the entries
neutrino.options.entries.forEach((entry) => {
  neutrino.use(htmlTemplate, { pluginId: `html-${entry}` });
});

🤔

@edmorley
Copy link
Member Author

Ah yes that sounds good too.

I also forgot to mention one point - the reason why I hadn't suggested that people iterate neutrino.config.entryPoints.values() directly, was that it includes vendor/manifest, which most of the time will want to be excluded. However your proposal sounds like it will still be only including the user-provided entry points, so should be fine :-)

@eliperelman
Copy link
Member

You raise another point about the conflation of entry options and webpack entry points. How can we make this clearer, less confusing, more intuitive to users? Maybe we should consider renaming options.entry to something like options.pages?

@eliperelman
Copy link
Member

I say this so we can make it clear that to add two pages, you might do:

module.exports = {
  options: {
    pages: [
      'index.js',
      'admin.js'
    ]
  },

  // but to set up a vendor bundle you still need to do:
  use: (neutrino) => {
    neutrino.config.module
      .entry('vendor')
        .add(/* ... */);
  }
};

@eliperelman eliperelman added this to the v8 milestone Nov 1, 2017
@eliperelman
Copy link
Member

I think using the term "pages" is presumptuous of it being a web app, and doesn't apply to libraries or Node.js apps.

@eliperelman
Copy link
Member

@edmorley would you be interested in taking this one on for v8?

@iongion
Copy link

iongion commented Nov 18, 2017

@edmorley how did you manage to have hot reload work for the entry ? I can't get it with the following:

  const entry = 'm1';
  const config =  neutrino.config
  // Interact with entry points
  .entry(entry)
    .add(
      `./src/project/modules/${entry}/index.standalone.jsx`,
      'webpack/hot/only-dev-server',
      `webpack-dev-server/client?http://0.0.0.0:3000`
    )
    .end();

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

No branches or pull requests

3 participants