<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: zhangHongEn</title>
    <description>The latest articles on DEV Community by zhangHongEn (@zhanghongen).</description>
    <link>https://dev.to/zhanghongen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F952879%2F831a3a27-35c1-447b-acad-8baefe7875ce.png</url>
      <title>DEV Community: zhangHongEn</title>
      <link>https://dev.to/zhanghongen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhanghongen"/>
    <language>en</language>
    <item>
      <title>hmr of remote module</title>
      <dc:creator>zhangHongEn</dc:creator>
      <pubDate>Mon, 11 Dec 2023 03:23:37 +0000</pubDate>
      <link>https://dev.to/zhanghongen/hmr-of-remote-module-2dfn</link>
      <guid>https://dev.to/zhanghongen/hmr-of-remote-module-2dfn</guid>
      <description>&lt;p&gt;Hot update of a single application is generally available out of the box, while hot update of remote modules requires some adaptation processing according to the development environment of multiple projects, and there is no mainstream mature solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem manifestation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/wpmjs/examples/tree/main/module-federation-react-hmr"&gt;https://github.com/wpmjs/examples/tree/main/module-federation-react-hmr&lt;/a&gt; You can clone this example and run it locally&lt;/p&gt;

&lt;p&gt;There are three modules: app1 (localhost:9001), app2 (localhost:9002), and app3 (localhost:9003). As the root application, app1 introduces app2 and app3 through module-federation. At this time, start the development environment of the three apps. Try Modify local code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  When you access the port of each app individually and modify the corresponding code, the page will be updated.&lt;/li&gt;
&lt;li&gt;  When accessing localhost:9001 directly, only the code page of app1 will be updated, and the code pages of app2 and app3 will not be refreshed or changed (websocket successfully triggered and completed the code update, and the react component did not change)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ALBDs6fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idwf1zrxe7m6a1ma61tl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ALBDs6fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idwf1zrxe7m6a1ma61tl.png" alt="Image description" width="720" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cause Analysis
&lt;/h3&gt;

&lt;p&gt;As a result, only the first loaded root application can be hot updated, and other subsequently loaded modules cannot be hot updated. The reason is actually that the hot update conditions of react are relatively strict:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; React and react-dom are singletonsReact and react-dom are singletons&lt;/li&gt;
&lt;li&gt; react, react-dom is the development version&lt;/li&gt;
&lt;li&gt; Register &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt; with global through react-refresh&lt;/li&gt;
&lt;li&gt; react-dom.development gets &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt; (react-dom will get &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt; when the code is executed for the first time, so you must strictly follow the order of loading react-refresh first, completing the registration hook, and then loading react-dom. If the order is wrong, hot update cannot be started., there is no remedy, this is also the most error-prone and difficult to troubleshoot)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well, since the previous example uses module-federation to share react and react-dom and both are locally started services, it actually meets the above conditions 1 and 2.&lt;/p&gt;

&lt;p&gt;The reason why app2 and app3 cannot be hot updated is &lt;a href="https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/426490f7bf7bf166efc85a0588e5c3b8e64cd72f/client/ReactRefreshEntry.js#L17"&gt;https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/426490f7bf7bf166efc85a0588e5c3b8e64cd72f/client/ReactRefreshEntry.js#L17&lt;/a&gt; This plug-in found that global hooks already existed, so it did not register app2 and app3. Only app1 successfully registered &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt; (by the way, react-dom.development is obtained directly from global &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt;, so it is not feasible to register each application individually.)&lt;/p&gt;

&lt;p&gt;For specific questions, please see this issue: &lt;a href="https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/394"&gt;Component modifications are not applied in module federation · Issue #394 · pmmmwh/react-refresh-webpack-plugin&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Multiple modules reuse the same &lt;strong&gt;REACT_DEVTOOLS_GLOBAL_HOOK&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/single-react-refresh-plugin"&gt;https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/single-react-refresh-plugin&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vue's hot update is not so troublesome to integrate. Logically, it only needs to satisfy the vue singleton and the development version plus vue-loader. If anyone encounters similar problems, you can leave a message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Remote module optimization points
&lt;/h3&gt;

&lt;p&gt;It is not difficult to find from the above example that although we have three modules that can be independently constructed and released, we need to start the root application + remote module project locally during development. If we only need to modify one module and disassemble the project, it will reduce efficiency. of. &lt;strong&gt;The better way is to start only the modules that need to be debugged or modified locally, so that they can be directly connected to the resources that have been deployed online or in the test environment (you can experience the micro front-end example built below)&lt;/strong&gt;, In this way, you can truly achieve minimal independent construction, independent release and independent debugging, to improve the development and deployment efficiency of the project and even reduce the scope of release impact.&lt;/p&gt;

&lt;p&gt;This development method involves how to start a remote module so that the main application can be switched to the development version, which will be discussed separately later.&lt;/p&gt;

&lt;h3&gt;
  
  
  micro frontend
&lt;/h3&gt;

&lt;p&gt;An application composed of multiple independently built and independently released modules can also be called a micro front end.&lt;/p&gt;

&lt;p&gt;You can also use the following link to experience starting the remote module alone and directly connecting to the online environment for development and debugging:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Visit the micro front-end root application demo address: &lt;a href="https://zhanghongen.github.io/universal-module-federation-plugin/"&gt;https://zhanghongen.github.io/universal-module-federation-plugin/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; clone remote module mf-app-01: &lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/mf-example/app1"&gt;https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/mf-example/app1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; npm install &amp;amp;&amp;amp; npm run start&lt;/li&gt;
&lt;li&gt; Activate the local connection switch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can see the effect in the picture below, a remote page, part of the page uses locally started components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aIorSDf4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbm1s1qbms5emxahswaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aIorSDf4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbm1s1qbms5emxahswaw.png" alt="Image description" width="720" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above micro front-end page is implemented using wpmjs and npm-federation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/npm-federation-webpack"&gt;https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/npm-federation-webpack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, I will share some micro-front-end related technologies.:&lt;/p&gt;

&lt;p&gt;Loader:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  systemjs、module-federation（Can be regarded as a mainstream remote module loader）&lt;/li&gt;
&lt;li&gt;  wpmjs（Versioned loading of remote modules, and integration of multiple module specifications such as: umd, system, module-federation）&lt;/li&gt;
&lt;li&gt;  npm-federation（Load the plug-in of the remote npm package in the module-federation method, and you can also load the umd package）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open up the technology stack:&lt;/p&gt;

&lt;p&gt;vuereact-combined（vue2 and react components refer to each other）&lt;/p&gt;

&lt;p&gt;veaury（vue3 and react components refer to each other）&lt;/p&gt;

&lt;p&gt;Application isolation: qiankun, single-spa, etc.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Remote package manager based on npm and module-federation</title>
      <dc:creator>zhangHongEn</dc:creator>
      <pubDate>Fri, 22 Sep 2023 11:44:12 +0000</pubDate>
      <link>https://dev.to/zhanghongen/remote-package-manager-based-on-npm-and-module-federation-3ol2</link>
      <guid>https://dev.to/zhanghongen/remote-package-manager-based-on-npm-and-module-federation-3ol2</guid>
      <description>&lt;h3&gt;
  
  
  Remote package manager based on npm and module-federation
&lt;/h3&gt;

&lt;p&gt;Recently I worked on a micro front-end open source project(web package manager), As the holiday approaches, I will briefly promote it, and I will continue to update after the holiday. &lt;a href="https://zhanghongen.github.io/universal-module-federation-plugin/"&gt;Everyone is welcome to experience it.&lt;/a&gt; or &lt;a href="https://zhanghongen.github.io/universal-module-federation-plugin/"&gt;star&lt;/a&gt;, Communication and discussion are also welcome, thank you&lt;/p&gt;

&lt;h3&gt;
  
  
  WPM introduce
&lt;/h3&gt;

&lt;p&gt;The web package manager is a remote package manager based on module-federation (mf) and npm. Connected the existing umd specification and mf module. You can share remote modules more easily and without worries. You can easily access existing npm packages or use npm private sources and other sources to build a new remote module system.&lt;br&gt;
It also has a built-in self-expandable debugging plug-in system, which can switch remote/local modules with one click, integrate hot updates, etc. to greatly improve development and debugging efficiency.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Multi-module specifications (integrated module specifications such as system, umd, module-federation, etc.)&lt;/li&gt;
&lt;li&gt;Debug mode/hot update (integrates debugging panel and hot update, can automatically connect to the locally started dev-server)&lt;/li&gt;
&lt;li&gt;Version management (you can use private or public npm as the remote module storage source, or you can customize url splicing rules to store remote modules yourself)&lt;/li&gt;
&lt;li&gt;Remote lock (supports dynamic configuration of remote module version)&lt;/li&gt;
&lt;li&gt;Performance optimization (the plug-in automatically optimizes the loading links of multiple remote modules and their chunks to avoid waiting for multiple loads)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Improve efficiency value
&lt;/h4&gt;

&lt;p&gt;I've been using wpm in my own work for two years and have only recently taken the time to decouple it. Simply put, its value lies in greatly improving development and construction efficiency as well as versioning, grayscale strategy and other management.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ltNbaG6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzo5xooy0p33tng00b0j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ltNbaG6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzo5xooy0p33tng00b0j.jpg" alt="Image description" width="500" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z1y25wn---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxdu1icx4usr5k5i74bu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z1y25wn---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxdu1icx4usr5k5i74bu.jpg" alt="Image description" width="287" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical advantages
&lt;/h4&gt;

&lt;p&gt;The underlying technology uses npm + module-federation, which is more in line with the existing technology ecosystem and has the lowest access cost. To elaborate on this future, I will only briefly introduce it now. As the most complete basic capability (ts, ssr, various packaging tool plug-ins) and the most active remote module sharing and loading capabilities, module-federation can automatically be compiled by the packaging tool. Analyze how many js resource (chunk) requests should be initiated in parallel and in advance to load the next module to remove the loading waterfall. This will also bring performance improvements that cannot be achieved by introducing remote modules during manual coding runtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  可以独立使用的底层能力
&lt;/h4&gt;

&lt;p&gt;When I was working on wpm, I also made many other libraries to solve some problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/module-federation/webpack-4"&gt;webpack4 module-federation&lt;/a&gt; webpack4 project uses module-federation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/module-federation-runtime"&gt;module-federation-runtime&lt;/a&gt; Simulated and exposed module-federation runtime API supporting browser and node environments&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/universal-module-federation-plugin"&gt;universal-module-federation-plugin&lt;/a&gt; Allows customizing the loading behavior of remotes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/wpmjs"&gt;wpmjs（umd + module-federation）&lt;/a&gt; Connect the runtime of umd + mf, load the sdk of the remote module from npm&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/npm-federation"&gt;npm-federation&lt;/a&gt; remotes supports remote npm modules&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin/tree/main/packages/systemjs-intercept"&gt;systemjs-intercept&lt;/a&gt;  Intercept and customize the behavior of systemjs to obtain dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Recent plans
&lt;/h4&gt;

&lt;p&gt;At present, the open source version exposes about 60% of the capabilities. I will continue to update after the vacation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Documentation, examples, development specifications, contribution guide supplement&lt;/li&gt;
&lt;li&gt;wpm plugin supplement&lt;/li&gt;
&lt;li&gt;Built-in hot update integration&lt;/li&gt;
&lt;li&gt;Articles (wpm introduction, module-federation features and performance analysis)&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Hundreds of micro-frontend applications in the company, How to smoothly upgrade mf from umd</title>
      <dc:creator>zhangHongEn</dc:creator>
      <pubDate>Sun, 04 Dec 2022 15:38:24 +0000</pubDate>
      <link>https://dev.to/zhanghongen/hundreds-of-micro-frontend-applications-in-the-company-how-to-smoothly-upgrade-mf-from-umd-485n</link>
      <guid>https://dev.to/zhanghongen/hundreds-of-micro-frontend-applications-in-the-company-how-to-smoothly-upgrade-mf-from-umd-485n</guid>
      <description>&lt;h2&gt;
  
  
  MF introduce
&lt;/h2&gt;

&lt;p&gt;webpack5 &lt;a href="https://module-federation.github.io/blog/get-started"&gt;module-federation&lt;/a&gt;very powerful, The front-end code (module) sharing has reached a new level, and remote code can be used like a local module&lt;/p&gt;

&lt;p&gt;Before that, it is bound to use the most widely standard &lt;strong&gt;&lt;em&gt;UMD module specification for sharing&lt;/em&gt;&lt;/strong&gt;, Using loaders such as &lt;strong&gt;&lt;em&gt;systemjs&lt;/em&gt;&lt;/strong&gt; needs to process promise logic, which only has a small impact when using asynchronous components. If the remote module is a function or a configuration item (such as JSON data), then the usage restrictions will be more obvious, and There is also no development environment support such as mature supporting &lt;strong&gt;TS&lt;/strong&gt; prompts。&lt;/p&gt;

&lt;p&gt;MF can use remote modules almost without perception, and has solutions in various fields&lt;a href="https://github.com/module-federation"&gt;（webpack-4、5、vite/rollup、TS、SSR、medusa/dashboard等）&lt;/a&gt;, More efficient and stable than requiring manual coding to process remote modules asynchronously&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z4bR7_81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/785mb0wiftmt61r27c6a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z4bR7_81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/785mb0wiftmt61r27c6a.jpg" alt="Image description" width="287" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MF enhance
&lt;/h2&gt;

&lt;p&gt;The company has hundreds of micro front-end applications and modules, and the company's business architecture will also require a large number of product integration components (different businesses provide capabilities and components to each other), which is very compatible with the characteristics of MF。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1jJ3zzmv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcigxzyk9kue05s6wvwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1jJ3zzmv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcigxzyk9kue05s6wvwa.png" alt="Image description" width="880" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what's the problem with using MF directly??&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hundreds of micro-frontend projects need to be fully upgraded and adapted (if a team uses webpack5 to provide an MF module, the webpack4 team cannot consume this module)&lt;/li&gt;
&lt;li&gt;How to reuse a large number of existing remote modules without refactoring (after upgrading mf, remote resources are divided into two types (1.UMD 2.MF), both remote modules will have dependencies, and the two dependencies need to be able to communicate and maintain singleton)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the above two problems, we provide two open source projects as corresponding solutions, and improve the versatility of module-federation, no longer limited by webpack5 (module-federation/webpack-4), and support the integration of other module specifications (universal-module-federation).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1L8LrViD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emthnlgzs22fzr5ex642.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1L8LrViD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emthnlgzs22fzr5ex642.jpg" alt="Image description" width="880" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/module-federation/webpack-4"&gt;module-federation/webpack-4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/zhangHongEn/universal-module-federation-plugin"&gt;universal-module-federation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the support of these two plug-ins, MF can even be used as a synchronously loaded remote universal module loader, and can be used directly in existing projects, It should also be able to reuse the original ecology such as &lt;a href="https://github.com/module-federation"&gt;ts, dashboard/medusa&lt;/a&gt; of MF。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to support multi-version coexistence:
&lt;/h3&gt;

&lt;p&gt;Many people may think that MF's &lt;strong&gt;remote&lt;/strong&gt; cannot coexist in multiple versions. First of all, this is not a shortcoming of MF, nor is it unsolvable。 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since the webpack application needs to mount global variables on the window, use &lt;strong&gt;jsonp&lt;/strong&gt; to load different &lt;strong&gt;chunks&lt;/strong&gt;. And MF also has a globally unique module name that will pollute the global space. When multiple versions of the same application appear at the same time, the global module will conflict。&lt;/li&gt;
&lt;li&gt;You only need to add the dimension of the version number to the configuration items of webpack, &lt;strong&gt;output.library.[name | uniqueName]&lt;/strong&gt;, &lt;strong&gt;ModuleFederationOptions.name&lt;/strong&gt;, and the global conflict can be resolved (because the global jsonp variable name will appear In all chunks, the &lt;strong&gt;hash&lt;/strong&gt; of all chunks packaged in each version of this setting will change, and the cache will be invalidated, but generally there is no need for multiple versions)。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages of multiple versions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multiple versions of the same &lt;strong&gt;remote&lt;/strong&gt; are loaded at the same time, and should not exist in the &lt;strong&gt;H5&lt;/strong&gt; environment. The appearance of multiple versions will increase the resources requested by the network and cause performance problems&lt;/li&gt;
&lt;li&gt;In large-scale micro-frontend projects on the B-end, there is a high probability that multiple versions of remote will need to coexist. However, similar to H5, it generally only appears across micro-frontend applications. The same application still needs to ensure that the version is unified, and no redundant resources are required to ensure loading speed. However, there are &lt;strong&gt;qiankun&lt;/strong&gt; and other micro-frontend solutions across applications to isolate window global variables, and this problem no longer exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  future upgrade:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  If webpack is eliminated, can the MF project continue to be used without refactoring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;turbopack&lt;/strong&gt; succeeds webpack, MF official should continue to support&lt;/li&gt;
&lt;li&gt;If other build tools succeed webpack, they can also make the MF project continue to run. You can refer to &lt;a href="https://www.npmjs.com/package/usemf"&gt;usemf&lt;/a&gt; (loading MF modules in other environments), and here In the process, there must be similar technologies.&lt;/li&gt;
&lt;li&gt;Even in the era when &lt;strong&gt;esmodule&lt;/strong&gt; can be used directly in the browser, and the original MF module file can be imported directly, it can also be used in the form of promise, but then the packaging process can be simplified and the ES module can be directly output for support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, no matter how the front-end ecology changes in the future, there can always be a smooth upgrade plan, but we need to move closer to the open source ecology, so as not to build a car behind closed doors and lead to reconstruction in the future.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>webpack4 module-federation</title>
      <dc:creator>zhangHongEn</dc:creator>
      <pubDate>Sun, 23 Oct 2022 10:55:17 +0000</pubDate>
      <link>https://dev.to/zhanghongen/webpack4-module-federation-29b5</link>
      <guid>https://dev.to/zhanghongen/webpack4-module-federation-29b5</guid>
      <description>&lt;p&gt;&lt;a href="https://module-federation.github.io/blog/get-started" rel="noopener noreferrer"&gt;module-federation&lt;/a&gt; It is a new feature of webpack5 update, and it is easier to share front-end code, This article will introduce &lt;a href="https://www.npmjs.com/package/@module-federation/webpack-4" rel="noopener noreferrer"&gt;module-federation/webpack-4&lt;/a&gt; ealization principle and its difference from webpack5&lt;/p&gt;

&lt;h2&gt;
  
  
  module-federation/webpack-4 ealization principle
&lt;/h2&gt;

&lt;p&gt;Briefly explain the implementation principle, how do webpack4 and webpack5 achieve interoperability? There are three key points&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/usemf" rel="noopener noreferrer"&gt;usemf&lt;/a&gt;（Use the sdk output by webpack5 build to simulate a webpack5 environment to load module-federation in a non-webpack5 environment）&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow the loading process of module-federation（1. init all remote container 2. merge shareScopes 3. Restore the sharing rules of webpack5-share）; output module-federation-container&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// container&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shareScope&lt;/span&gt;&lt;span class="p"&gt;){},&lt;/span&gt; 
    &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// shareScopes example&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;18.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;other&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;17.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;other&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, a capability that webpack4 lacks, enabling jsonp-chunk to support waiting for dependencies (remote modules) to load&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implement the above process through plug-ins&lt;br&gt;
&lt;a href="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8o55iap04p3htc5wviz.png" rel="noopener noreferrer"&gt;Enlarge picture&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8o55iap04p3htc5wviz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8o55iap04p3htc5wviz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a new entry to implement the loading process of module-federation and output the container&lt;/li&gt;
&lt;li&gt;Intercept the module loading of remotes, no longer load local modules directly, but use remote modules&lt;/li&gt;
&lt;li&gt;Intercept shared module loading, no longer load local modules directly, but use remote modules&lt;/li&gt;
&lt;li&gt;Shared requests are intercepted, but the shared bundle still needs to be output, and the function merge shareScopes will be loaded&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It introduces the two red parts in the figure, how to change the webpack4 loading process to support loading remote modules&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intercept imports, reserve dependency tags

&lt;ol&gt;
&lt;li&gt;Set alias, transfer remotes to a non-existent url (no existence can be intercepted in the second step)&lt;/li&gt;
&lt;li&gt;Forward remotes to specific loader in "compiler.resolverFactory.plugin("resolver normal") --&amp;gt; resolver.hooks.resolve.tapAsync" hook&lt;/li&gt;
&lt;li&gt;Leave a string in the loader to mark that the current module depends on the remote module, get and export the value of the remote module&lt;/li&gt;
&lt;li&gt;The "compilation.mainTemplate.hooks.jsonpScriptchunk" hook makes the jsonp chunk wait for the remote module to load before executing&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Source code analysis
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/module-federation/webpack-4" rel="noopener noreferrer"&gt;https://github.com/module-federation/webpack-4&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// module-federation/webpack-4/lib/plugin.js&lt;/span&gt;
&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Generate unique jsonpFunction global variables to prevent conflicts&lt;/span&gt;
    &lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsonpFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`mfrename_webpackJsonp__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Generate 4 dummy modules for spare&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;genVirtualModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 3. Initialize the remote module mapping relationship in entry chunks&lt;/span&gt;
    &lt;span class="c1"&gt;// 4. Load all container initialization dependency collections (shareScopes) in entry chunks&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watchEntryRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 5. Generate mf entry file (usually remoteEntry.js)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;genRemoteEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 6. Intercept webpack compilation of remotes and shared modules&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convertRemotes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;interceptImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 7. Make webpack jsonp chunk wait for remote dependencies to load&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;patchJsonpChunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Generate unique jsonpFunction global variables to prevent conflicts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsonpFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`mfrename_webpackJsonp__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Generate 4 dummy modules for spare
&lt;/h3&gt;

&lt;p&gt;Just register these 4 file code modules as webpack virtual modules, which can be introduced and used by subsequent processes&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Initialize the remote module mapping relationship in entry chunks
&lt;/h3&gt;

&lt;h3&gt;
  
  
  4. Load all container initialization dependency collections
&lt;/h3&gt;

&lt;p&gt;Initialize all containers (other mf modules), and export the loading process as a promise to mark the completion of the initialization phase (all jsonp chunks need to wait for the initialization phase to complete)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;module-federation/webpack-4/lib/virtualModule/exposes.js&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yjr7bs2f8plgwr3h9po.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yjr7bs2f8plgwr3h9po.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Generate mf entry file (usually remoteEntry.js)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Add mf entry using singleEntry&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SingleEntryPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;virtualExposesPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remoteEntry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Copy the last file generated by the remoteEntry entry and rename it&lt;/span&gt;
&lt;span class="nx"&gt;entryChunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eachJsFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$_mfplugin_remoteEntry.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;compilation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$_mfplugin_remoteEntry.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compilation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;// delete compilation.assets[file]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;output container api（module-federation/webpack-4/lib/virtualModule/exposes.js）
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`
  /* eslint-disable */
  ...
  const {setInitShared} = require("&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;virtualSetSharedPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;")

  // All exposed modules are preset here with dynamic-import
  const exposes = {
    [moduleName]: async () {}
  }

  // 1. Register the container globally in a global-like manner
  module.exports = window["&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"] = {
    async get(moduleName) {
      // 2. Use code splitting to expose exported modules
      const module = await exposes[moduleName]()
      return function() {
        return module
      }
    },
    async init(shared) {
      // 4. Merge shares and wait for the init phase to complete
      setInitShared(shared)
      await window["__mfplugin__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"].initSharedPromise
      return 1
    }
  }

  `&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Intercept webpack compilation of remotes and shared modules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Set aliases for remotes and shared modules, identify special paths, and forward them to a non-existing file path（Only non-existing file paths can be intercepted by resolver hooks and forwarded）（module-federation/webpack-4/lib/virtualModule/plugin.js）
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remotes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shared&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remotes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`wpmjs/$/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;$`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`wpmjs/$/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`wpmjs/$/mfshare:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;$`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`wpmjs/$/mfshare:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Intercept remotes, shared aliases, and forward to import-wpm-loader.js to generate code for requesting remote resources（module-federation/webpack-4/lib/plugin.js）
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolverFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resolver normal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tapAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolveContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;alias&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;remotes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Forward to import-wpm-loader with pkgName parameter&lt;/span&gt;
          &lt;span class="nf"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emptyJs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`?&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;wpm&amp;amp;type=wpmPkg&amp;amp;mfName=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;pkgName=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pkgName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// request native module&lt;/span&gt;
          &lt;span class="nf"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Generate code to request remote resources（module-federation/webpack-4/lib/import-wpm-loader.js）
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;`
    /* eslint-disable */
    if (window.__wpm__importWpmLoader__garbage) {
      // 1. Leave a code mark to identify the dependent remote module, which is used to make the chunk wait for the remote dependency to load
      window.__wpm__importWpmLoader__garbage = "__wpm__importWpmLoader__wpmPackagesTag&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pkgName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;__wpm__importWpmLoader__wpmPackagesTag";
    }
    // 2. When entering the code of this module, the remote module has been loaded, you can use get to get the synchronization value of the module, and return
    module.exports = window["__mfplugin__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mfName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"].get("&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pkgName&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;")
    `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Make webpack jsonp chunk wait for remote dependencies to load
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use regular matching to the remote module that the jsonp chunk depends on, so that the chunk waits for the dependency to load&lt;/li&gt;
&lt;li&gt;Make webpack jsonp load function support jsonp waiting to load dependencies（module-federation/webpack-4/lib/plugin.js）&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Differences with webpack5
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@module-federation/webpack-4" rel="noopener noreferrer"&gt;module-federation/webpack-4&lt;/a&gt;The plugin has implemented the main capabilities of module-federation, and can be found in &lt;a href="https://stackblitz.com/github/wpmjs/wpmjs/tree/main/examples/module-federation/webpack-4" rel="noopener noreferrer"&gt;webpack4 and webpack5 refer to each other&lt;/a&gt; , The following describes which parameters are not supported by the plugin&lt;/p&gt;

&lt;h2&gt;
  
  
  unsupported parameter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  options.library
&lt;/h3&gt;

&lt;p&gt;The priority of this parameter is not very high, the implementation in webpack4 is more complicated, and there are still problems in using it in webpack5, see for details "&lt;a href="https://github.com/webpack/webpack/issues/16236" rel="noopener noreferrer"&gt;https://github.com/webpack/webpack/issues/16236&lt;/a&gt;" , Therefore, the implementation in webpack4 is similar to setting library.type = "global"&lt;/p&gt;

&lt;h3&gt;
  
  
  options.remotes.xxx.shareScope
&lt;/h3&gt;

&lt;p&gt;The same mf container can only be initialized with one shareScope. If inconsistent webpack is set by using shareScope multiple times, it will report an error, and the shareScope can be set too much, which is confusing. Even in pure webpack5, the performance is unpredictable. It is recommended to use options. shared.xxx.shareScope, options.shareScope alternative&lt;/p&gt;

&lt;h3&gt;
  
  
  module-federation ecological package
&lt;/h3&gt;

&lt;p&gt;The webpack-4 plugin has not yet integrated the ability of webpack-5 related packages（&lt;a href="https://github.com/module-federation" rel="noopener noreferrer"&gt;ssr、typescript、hmr、dashboard...&lt;/a&gt;）, However, 4 and 5 interoperability has been achieved, which can help you to use webpack5 to implement new projects without refactoring existing projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported parameters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;options.remotes&lt;/li&gt;
&lt;li&gt;options.name&lt;/li&gt;
&lt;li&gt;options.shareScope&lt;/li&gt;
&lt;li&gt;options.shared&lt;/li&gt;
&lt;li&gt;options.exposes&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webpack</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
