<h1 dir="auto">Bug report</h1>
<p dir="auto">If you declare shared modules that consist of multiple internal libraries, and define shareKey for this module, you may get run-time JS exceptions <code class="notranslate">Type error: fn is not a function</code>, because ModuleFederationPlugin will register more internal libraries under the same shareKey, which will make some shared libraries inaccessible.</p>
<p dir="auto"><strong>If the current behavior is a bug, please provide the steps to reproduce.</strong></p>
<p dir="auto">Some shared modules consist of multiple separated libraries. For example, declaring rxjs module as shared:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="shared: {
  [ 'rxjs' ]
}"><pre class="notranslate"><code class="notranslate">shared: {
  [ 'rxjs' ]
}
</code></pre></div>
<p dir="auto">In this case ModuleFederationPlugin will generate and register two separated JS libraries: <code class="notranslate">rxjs</code> and <code class="notranslate">rxjs/operators</code>, and register them like so:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="register(&quot;rxjs&quot;, &quot;6.6.7&quot;, () =&gt;  .... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/index.js */ 5906)
register(&quot;rxjs/operators&quot;, &quot;6.6.7&quot;, () =&gt; ... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/operators/index.js */ 6370)"><pre class="notranslate"><code class="notranslate">register("rxjs", "6.6.7", () =&gt;  .... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/index.js */ 5906)
register("rxjs/operators", "6.6.7", () =&gt; ... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/operators/index.js */ 6370)
</code></pre></div>
<p dir="auto">This works as expected. But there is a problem when you use shareKey in config:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="shared: {
  [ 'rxjs': { shareKey: 'rxjs for Angular 13'  } ]
}"><pre class="notranslate"><code class="notranslate">shared: {
  [ 'rxjs': { shareKey: 'rxjs for Angular 13'  } ]
}
</code></pre></div>
<p dir="auto">In this case ModuleFederationPlugin will register both libraries under the same key:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="register(&quot;rxjs for Angular 13&quot;, &quot;6.6.7&quot;, () =&gt;  .... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/index.js */ 5906)
register(&quot;rxjs for Angular 13&quot;, &quot;6.6.7&quot;, () =&gt; ... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/operators/index.js */ 6370)"><pre class="notranslate"><code class="notranslate">register("rxjs for Angular 13", "6.6.7", () =&gt;  .... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/index.js */ 5906)
register("rxjs for Angular 13", "6.6.7", () =&gt; ... __webpack_require__(/*! ./node_modules/rxjs/_esm2015/operators/index.js */ 6370)
</code></pre></div>
<p dir="auto">This will produce unexpected run-time JS errors: <code class="notranslate">Type error: fn is not a function</code>, whenever a function from the first library is called, because the function will be looked-up in the second library because it will override the first registered library due to the same key.</p>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">ModuleFederationPlugin should correcly register and resolve multiple libraries (because developers are not aware if shared module consists with more libraries).</p>
<p dir="auto">There is currently a workaround for this problem if you need to use shareKey: you must explicitely define all internal libraries for a shared module, and define them unique shareKeys:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="shared: {
  [ 
    'rxjs': { shareKey: 'rxjs for Angular 13'  },
    'rxjs/operators': { shareKey: 'rxjs/operators for Angular 13'  },
 ]
}"><pre class="notranslate"><code class="notranslate">shared: {
  [ 
    'rxjs': { shareKey: 'rxjs for Angular 13'  },
    'rxjs/operators': { shareKey: 'rxjs/operators for Angular 13'  },
 ]
}
</code></pre></div>
<p dir="auto"><strong>Other relevant information:</strong><br>
webpack version:  5.73.0<br>
Node.js version: 16.15.1<br>
Operating System: Windows 10<br>
Additional tools:</p>
<h1 dir="auto">Bug report</h1>




<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">When using Module Federation, sharing a dependency and your other dependencies are using it too but in different versions, it won't respect semver matching and use the same version for everything.<br>
For example, even when it is explicitly defined to be shared with <code class="notranslate">^8.3.2</code> in the top-level, it matches the <code class="notranslate">3.4.0</code> version that another deep dependency consumes.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="3.4.0 does not satisfy constraint ^8.3.2"><pre class="notranslate"><code class="notranslate">3.4.0 does not satisfy constraint ^8.3.2
</code></pre></div>
<p dir="auto"><strong>If the current behavior is a bug, please provide the steps to reproduce.</strong></p>
<p dir="auto">Repo that reproduces the issue - <a href="https://github.com/tzachbon/mf-shared-deep-dependency">https://github.com/tzachbon/mf-shared-deep-dependency</a></p>
<p dir="auto">This example tries to reproduce the problem when sharing a dependency that exists in multiple versions across the node modules but resolves the request incorrectly.</p>
<p dir="auto">In this example repo, I use <code class="notranslate">uuid</code> package.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="└─┬ @startup-code/app1@0.0.0 -&gt; ./app1
  ├─┬ lib@1.0.0 -&gt; ./lib
  │ └── uuid@3.4.0
  ├── uuid@8.3.2
  └─┬ webpack-dev-server@4.8.1
    └─┬ sockjs@0.3.24
      └── uuid@8.3.2 deduped"><pre class="notranslate"><code class="notranslate">└─┬ @startup-code/app1@0.0.0 -&gt; ./app1
  ├─┬ lib@1.0.0 -&gt; ./lib
  │ └── uuid@3.4.0
  ├── uuid@8.3.2
  └─┬ webpack-dev-server@4.8.1
    └─┬ sockjs@0.3.24
      └── uuid@8.3.2 deduped
</code></pre></div>
<p dir="auto">This graph shows that the root <code class="notranslate">uuid</code> is 8.3.2 and the version under <code class="notranslate">lib</code> is 3.4.0.</p>
<p dir="auto"><code class="notranslate">lib</code> uses the <code class="notranslate">v3</code> method from <code class="notranslate">uuid</code>.<br>
This method exists only in version 8.3.2.</p>
<p dir="auto">By default, if we build this project, serve it and click on <code class="notranslate">new uuid</code>, <strong>everything crashes as expected</strong>:<br>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-is-not-shared/console.png?raw=true"><img src="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-is-not-shared/console.png?raw=true" alt="console" style="max-width: 100%;"></a></p>
<p dir="auto">But when we use Module Federation and share this package from <code class="notranslate">app1</code> like this:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="[
      new ModuleFederationPlugin({
      name: 'app1',
      shared: {
        lib: deps['lib'],
        uuid: deps['uuid'], // &lt;-- resolve to ^8.3.2
        react: { singleton: true, requiredVersion: deps.react },
        'react-dom': { singleton: true, requiredVersion: deps['react-dom'] },
      },
    })
]"><pre class="notranslate"><span class="pl-kos">[</span>
      <span class="pl-k">new</span> <span class="pl-v">ModuleFederationPlugin</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'app1'</span><span class="pl-kos">,</span>
      <span class="pl-c1">shared</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">lib</span>: <span class="pl-s1">deps</span><span class="pl-kos">[</span><span class="pl-s">'lib'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
        <span class="pl-c1">uuid</span>: <span class="pl-s1">deps</span><span class="pl-kos">[</span><span class="pl-s">'uuid'</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-c">// &lt;-- resolve to ^8.3.2</span>
        <span class="pl-c1">react</span>: <span class="pl-kos">{</span> <span class="pl-c1">singleton</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">requiredVersion</span>: <span class="pl-s1">deps</span><span class="pl-kos">.</span><span class="pl-c1">react</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
        <span class="pl-s">'react-dom'</span>: <span class="pl-kos">{</span> <span class="pl-c1">singleton</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">requiredVersion</span>: <span class="pl-s1">deps</span><span class="pl-kos">[</span><span class="pl-s">'react-dom'</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><span class="pl-kos">)</span>
<span class="pl-kos">]</span></pre></div>
<p dir="auto">We can see that the runtime understands the difference between the packages:<br>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/runtime.png?raw=true"><img src="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/runtime.png?raw=true" alt="runtime" style="max-width: 100%;"></a></p>
<p dir="auto">But when we click on <code class="notranslate">new uuid</code> which crashed our app, it works (not the desired behavior)...<br>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/console.png?raw=true"><img src="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/console.png?raw=true" alt="console" style="max-width: 100%;"></a></p>
<p dir="auto">When we look inside the index file, we can see the <code class="notranslate">moduleToHandlerMapping</code> resolve it incorrectly:<br>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/moduleToHandlerMapping.png?raw=true"><img src="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-shared/moduleToHandlerMapping.png?raw=true" alt="moduleToHandlerMapping" style="max-width: 100%;"></a></p>
<p dir="auto">And when we remove the <code class="notranslate">uuid</code> entry from the <code class="notranslate">shared</code> section in ModuleFederationPlugin we can see that the app behaves as expected:<br>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-is-not-shared/console.png?raw=true"><img src="https://github.com/tzachbon/mf-shared-deep-dependency/blob/master/screenshots/uuid-is-not-shared/console.png?raw=true" alt="console" style="max-width: 100%;"></a></p>
<p dir="auto">For some reason, even when it is explicitly defined to be shared with <code class="notranslate">^8.3.2</code>, it matches the <code class="notranslate">3.4.0</code> version that <code class="notranslate">lib</code> consumes.</p>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">I would expect that each dependency would get the correct package resolution according to the node resolution algorithm.<br>
In our example -</p>
<ul dir="auto">
<li>top level (App) - 8.3.2</li>
<li>lib - 3.4.0</li>
</ul>
<p dir="auto"><strong>Other relevant information:</strong><br>
webpack version:  5.72.1<br>
Node.js version: v16.15.0<br>
NPM version: 8.5.5<br>
Operating System: MacOS Monterey 12.4</p>
<p dir="auto">Also asked in the Module Federation examples repo -<br>
<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1278088681" data-permission-text="Title is private" data-url="https://github.com/module-federation/module-federation-examples/issues/2033" data-hovercard-type="issue" data-hovercard-url="/module-federation/module-federation-examples/issues/2033/hovercard" href="https://github.com/module-federation/module-federation-examples/issues/2033">module-federation/module-federation-examples#2033</a></p>