Feature Suggestion: Sub Configuration for Entry Points

Do you want to request a feature or report a bug?

Feature.

What is the current behavior?

Webpack configuration happens per bundle, this means it’s on a per-output basis.

What is the expected behavior?

Configuration would be way more flexible if it provided an additional per-entry configuration.

If this is a feature request, what is motivation or use case for changing the behavior?

My Use Case

I’m working with a CMS at my job. It’s suitable for the needs of our clients but it lacks some modern features including asset bundling. So I started working on kind of a webpack-based asset pipeline for that CMS.

The CMS makes use of third-party plugins. Those might bring their own assets so I want to provide a way to bundle those together with the CMS’ “main assets”.

Giving each plugin its own entry point is easy. But those plugins can get quite big. They may be small applications themselves and might require custom aspects of configuration e.g. their own aliases or loaders.
A plugin might want to define some custom aliases and those should be usable from inside the plugin while not affecting other CMS plugins for obvious reasons—they are probably created by other developers who are not aware of my plugin. These devs could not rely on webpack working in a certain way if my plugin-created configuration could “escape” its scope.

Currently this kind of encapsulated behaviour is not possible in webpack.

The Essence

This mostly boils down to one aspect: One configuration per output makes the bundler only partially suitable for projects where you don’t have full control over the assets’ source code.

Being able to add per-entry configurations would make webpack much more useful in very loosely coupled projects with independent (and agnostic-of-each-other) developers.

So that would essentially mean to be able to mix multiple webpack configurations into a single output.

Implementation

A naïve approach to adding this idea to the configuration API would be to allow the values of the entry object to be themselves objects:

// To be honest, this looks awful #pyramidofdeath
{
  entry: {
    myEntry: {
      files: [ 'foo.js', 'bar.js' ],
      config: {
        resolve: {
          alias: {
            myAlias: '/actual/path'
          }
        }
      }
    }
  }
}

Let’s for now agree on calling each of these embedded config objects a “per-entry configuration” while the surrounding object is the “main configuration”.

Requirements and Ideas

Per-entry configurations

  • should be able to use a shared set of modules.
    Multiple entries might access the same modules. That’s the main reason why the simplest approach for my case wouldn’t work: Bundling the CMS plugins individually and then bundle the resulting bundles together would mean a huge waste by using duplicate code.

  • should support a sensible subset of the webpack configuration
    Aliases, loaders and resolution roots would be useful while having an entry or output option would not make too much sense.

  • should extend the main confguration in the spirit of @bebraw‘s very own webpack-merge.
    Existing aliases may be extended by custom ones, maybe even overridden.

  • may only apply to their respective entry and neither affect the main configuration nor other entry configurations
    This means overriding main configuration options in an entry configuration will not be applied to anything outside the entry.

Reality Check

While this would (as shown above) not need too extensive changes in the configuration API it would certainly be some immense work under the hood (which @TheLarkInn confirmed when I mentioned my thoughts on twitter). Just to mention that I’m aware of this being a heavyweight suggestion.

It would also bring a load of non-trivial conceptual work e.g. deciding what configuration would be applied to an asset that is used from multiple entry points.

I’m curious to hear about your thoughts on this.

Author: Fantashit

1 thought on “Feature Suggestion: Sub Configuration for Entry Points

  1. My use case would be in i18n of my application. I’d like to create an entrypoint per language, then per entrypoint supply a different alias to something like localizedStrings which contains the strings for that language.

    {
      entry: {
        './app/en.js': {
          resolve: {
            alias: {
              localizedStrings: '/path/to/locale/en.json'
            }
          }
        },
        './app/fr.js': {
          resolve: {
            alias: {
              localizedStrings: '/path/to/locale/fr.json'
            }
          }
        },
        './app/es.js': {
          resolve: {
            alias: {
              localizedStrings: '/path/to/locale/es.json'
            }
          }
        }
      }
    }

Comments are closed.