<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong></p>
<p dir="auto">Feature.</p>
<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">Webpack configuration happens per bundle, this means it's on a <em>per-output</em> basis.</p>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">Configuration would be way more flexible if it provided an additional <em>per-entry</em> configuration.</p>
<p dir="auto"><strong>If this is a feature request, what is motivation or use case for changing the behavior?</strong></p>
<h2 dir="auto">My Use Case</h2>
<p dir="auto">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.</p>
<p dir="auto">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".</p>
<p dir="auto">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.<br>
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.</p>
<p dir="auto">Currently this kind of encapsulated behaviour is not possible in webpack.</p>
<h2 dir="auto">The Essence</h2>
<p dir="auto">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.</p>
<p dir="auto">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.</p>
<p dir="auto">So that would essentially mean to be able to mix multiple webpack configurations into a single output.</p>
<h2 dir="auto">Implementation</h2>
<p dir="auto">A naïve approach to adding this idea to the configuration API would be to allow the values of the <code class="notranslate">entry</code> object to be themselves objects:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// To be honest, this looks awful #pyramidofdeath
{
  entry: {
    myEntry: {
      files: [ 'foo.js', 'bar.js' ],
      config: {
        resolve: {
          alias: {
            myAlias: '/actual/path'
          }
        }
      }
    }
  }
}"><pre class="notranslate"><span class="pl-c">// To be honest, this looks awful #pyramidofdeath</span>
<span class="pl-kos">{</span>
  <span class="pl-c1">entry</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">myEntry</span>: <span class="pl-kos">{</span>
      <span class="pl-c1">files</span>: <span class="pl-kos">[</span> <span class="pl-s">'foo.js'</span><span class="pl-kos">,</span> <span class="pl-s">'bar.js'</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-c1">config</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">resolve</span>: <span class="pl-kos">{</span>
          <span class="pl-c1">alias</span>: <span class="pl-kos">{</span>
            <span class="pl-c1">myAlias</span>: <span class="pl-s">'/actual/path'</span>
          <span class="pl-kos">}</span>
        <span class="pl-kos">}</span>
      <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Let's for now agree on calling each of these embedded <code class="notranslate">config</code> objects a "per-entry configuration" while the surrounding object is the "main configuration".</p>
<h2 dir="auto">Requirements and Ideas</h2>
<p dir="auto">Per-entry configurations</p>
<ul dir="auto">
<li>
<p dir="auto">should be able to <strong>use a shared set of modules</strong>.<br>
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.</p>
</li>
<li>
<p dir="auto">should <strong>support a sensible subset of the webpack configuration</strong><br>
Aliases, loaders and resolution roots would be useful while having an <code class="notranslate">entry</code> or <code class="notranslate">output</code> option would not make too much sense.</p>
</li>
<li>
<p dir="auto">should <strong>extend the main confguration</strong> in the spirit of <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/bebraw/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/bebraw">@bebraw</a>'s very own <code class="notranslate">webpack-merge</code>.<br>
Existing aliases may be extended by custom ones, maybe even overridden.</p>
</li>
<li>
<p dir="auto">may only apply to their respective entry and <strong>neither affect the main configuration nor other entry configurations</strong><br>
This means overriding main configuration options in an entry configuration will not be applied to anything outside the entry.</p>
</li>
</ul>
<h2 dir="auto">Reality Check</h2>
<p dir="auto">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 <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/TheLarkInn/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/TheLarkInn">@TheLarkInn</a> <a href="https://twitter.com/TheLarkInn/status/824716888957718529" rel="nofollow">confirmed</a> when I mentioned my thoughts on twitter). Just to mention that I'm aware of this being a heavyweight suggestion.</p>
<p dir="auto">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.</p>
<p dir="auto">I'm curious to hear about your thoughts on this.</p>
<h1 dir="auto">Bug report</h1>
<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">Production build in webpack 5 takes approximatly 20% more time to complete than in webpack 4. Turn minimization off via optimization.minimize makes webpack 5 actually faster then webpack 4.</p>
<p dir="auto">Providing result of <a href="https://github.com/SkReD/webpack5-performance-issue/blob/master/bench.json">10 build runs</a> by webpack 4 and by webpack 5:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="webpack 4: 6.135080679988861 seconds
webpack 5: 7.854557122190793 seconds"><pre class="notranslate"><code class="notranslate">webpack 4: 6.135080679988861 seconds
webpack 5: 7.854557122190793 seconds
</code></pre></div>
<p dir="auto"><strong>If the current behavior is a bug, please provide the steps to reproduce.</strong><br>
Repo for reproducing <a href="https://github.com/SkReD/webpack5-performance-issue">https://github.com/SkReD/webpack5-performance-issue</a></p>
<p dir="auto"><strong>What is the expected behavior?</strong><br>
Build time is bigger about 0 - 5% maximum. Should be possible to configure optimization for reducing build time to webpack 4 values.</p>
<p dir="auto"><strong>Other relevant information:</strong><br>
webpack version:  5.38.1<br>
Node.js version: 16.3.0 (--cpu-profile fails on current LTS)<br>
Operating System: windows 10 x64<br>
Additional tools:</p>
<p dir="auto">Providing logs of last runs from bench run</p>
<p dir="auto"><strong>webpack 4 profile logs</strong><br>
<a href="https://github.com/SkReD/webpack5-performance-issue/blob/master/webpack4/main-process.cpuprofile">main-process.cpuprofile</a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/938036/120779902-3d26ff00-c530-11eb-8179-86dd3c6d6671.png"><img src="https://user-images.githubusercontent.com/938036/120779902-3d26ff00-c530-11eb-8179-86dd3c6d6671.png" alt="main-process" style="max-width: 100%;"></a></p>
<p dir="auto"><a href="https://github.com/SkReD/webpack5-performance-issue/blob/master/webpack4/child-process.cpuprofile">child-process.cpuprofile</a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/938036/120779912-3dbf9580-c530-11eb-967f-61344a7cb6ca.png"><img src="https://user-images.githubusercontent.com/938036/120779912-3dbf9580-c530-11eb-967f-61344a7cb6ca.png" alt="child-process" style="max-width: 100%;"></a></p>
<p dir="auto"><strong>webpack 5 profile logs</strong><br>
<a href="https://github.com/SkReD/webpack5-performance-issue/blob/master/webpack5/main-process.cpuprofile">main-process.cpuprofile</a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/938036/120779954-49ab5780-c530-11eb-9328-f682b21b25b3.png"><img src="https://user-images.githubusercontent.com/938036/120779954-49ab5780-c530-11eb-9328-f682b21b25b3.png" alt="main-process" style="max-width: 100%;"></a></p>
<p dir="auto"><a href="https://github.com/SkReD/webpack5-performance-issue/blob/master/webpack5/child-process.cpuprofile">child-process.cpuprofile</a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/938036/120779956-4adc8480-c530-11eb-86e9-d6a22877afab.png"><img src="https://user-images.githubusercontent.com/938036/120779956-4adc8480-c530-11eb-86e9-d6a22877afab.png" alt="child-process" style="max-width: 100%;"></a></p>