This is my first day of the Gwen Challenge…

background

At present, the business of many companies involves the development of multiple ends, including PC side/small program/native client side, etc., and different ends have corresponding one or several independent projects, and there are some reusable business logic between these different projects, developers often need to maintain the same logic in different projects. Therefore, in order to save maintenance costs, cross-project module reuse is considered. After learning the module federation feature of Webpackage 5, I did some research.

MF is what

Module Federation, which translates as “Module Federation” in Chinese, is a feature in webpack5 that claims to be a game changer for JavaScript architecture. The purpose of use as defined in its documentation is:

Multiple independent builds can form an application. These independent builds do not depend on each other, so they can be developed and deployed separately. This is often referred to as a microfront-end, but it’s not limited to that.

In short, MF is essentially a combination of multiple independently deployed applications that have no separate dependencies. Or more than just applications, MF supports finer granularity. It can combine multiple modules, multiple NPM packages into one.

The characteristics of MF

  1. Support to export a module directly in the project, directly packaged separately.

At present, when we reuse across projects/team projects, the main way is still to export THE NPM package, and the removal, release and maintenance of the NPM package need a certain cost. And when multiple projects depend on the same NPM package, if there is an upgrade to the NPM, all dependent projects will be updated accordingly and then redistributed. And often when you write a certain logic, you may not expect the possibility of reuse later, so this time to extract NPM package to reuse is more troublesome.

The MF module can be directly exported in the project and packaged separately, as shown below:This is very flexible, in the reuse of logic can do as little as possible to the existing project, fast export.

  1. Support for runtime loading, which reduces the volume of code when packaging and is used as if under the same project

Because of split packaging, there is a smaller load volume, and the chunk that has been downloaded by the current subsystem can be shared, and if it can be reused, the next subsystem will not be downloaded again. This allows the same module logical dependencies to be updated synchronously between different projects at runtime and saves code construction costs, maintenance costs, and so on.

  1. Compared to the past, externals can’t coexist with multiple versions, DLLS can’t share modules, MF works perfectly.
  2. Better A/B tests can be done with the feature of dynamically loading modules at runtime
  3. MF can be used in conjunction with server-side rendering, and it also fits well with CDN edge computing. Imagine it can also be used with Serverless for on-demand compilation loading.

Build a complete example based on MF application

First of all, this is webpack5 capability, so of course to use Webpack5 to build, afraid of configuration trouble students, can directly see my demo, I have uploaded the demo on Github, the address is: github.com/LuckyWinty/…

Exporting party configuration:

// home webpack.config.js
    new ModuleFederationPlugin({
      name: "home".filename: "remoteEntry.js".exposes: {
        "./Content": "./src/components/Content"."./Button": "./src/components/Button"."./VueDemo": "./src/components/VueDemo"./ / component
        "./Utils": "./src/utils"./ / pure functions}}),Copy the code

User configuration:

// layout webpack.config.js
    new ModuleFederationPlugin({
      name: "layout".filename: "remoteEntry.js".remotes: {
        home: "home@http://localhost:3002/remoteEntry.js"./ / the CDN address
      },
      exposes: {},}),// layout main.js
    import Vue from "vue";
    import Layout from './Layout.vue';

    const Content = () = > import("home/Content");
    const Button = () = > import("home/Button");
    const VueDemo = () = > import("home/VueDemo");

    (async() = > {const { sayHi } = await import("home/Utils"); sayHi(); }) (); Vue.component("content-element", Content);
    Vue.component("button-element", Button);
    Vue.component("vue-demo", VueDemo);

    new Vue({
    render: h= > h(Layout),
    }).$mount('#app')
Copy the code

Through the above configuration, we have a preliminary understanding of MF, that is, if you want to use MF, you need to configure several important properties:

The field name type meaning
name string Mandatory value, which is the name of the output module
library object How to declare a global variable. Name is the name of the UMD
filename string Build the file name of the output
remotes object A mapping of remotely referenced application names and their aliases, using the key value as the name
exposes object The resource path and its alias that can be exposed when referenced remotely
shared object Third party dependencies that can be shared with other applications so that you don’t have to load the same dependencies twice in your code

Thus, modules can be shared between projects in a way that is not much different from normal introduction. The basic principle is that independently exported modules are packaged into a separate package, and then referenced by the user in the form of CDN address. In this way, the same module logic between different projects can be updated synchronously and the cost of code construction and maintenance can be saved.

It is recommended that you run a demo to see how it works.

Limitations of wechat applets

Small procedures due to the need to be online before all the code package, and then submitted to the approval of the online. Therefore, corresponding modules cannot be dynamically loaded by CDN on demand. In order to be compatible with the applets, we can use scripts to pull the CDN address of the code to the applets project specified directory, and then the applets reference.

Comparison of MF in microfront-end applications

Some differences between Module Federation and Qiankun/ICestark frameworks in microfront-end applications:

  1. The definition of micro

MF is based on modules, and the qiankun/ ICestark frameworks are based on applications. In other words, MF is an application formed by the aggregation of multiple independent modules and the framework is an application formed by the aggregation of multiple independent applications.

  1. The technical implementation

The MF module is essentially a JS code fragment, which is commonly referred to as chunk. So the aggregation of modules is actually the aggregation of chunks. Framework applications are essentially HTML, and in SPA, HTML is populated with main.js. Therefore, an aggregation of applications is actually an aggregation of main.js.

  1. Usage scenarios

MF is a creative effort to upgrade the technology at a cost to make the system more capable. Framing is a conservative effort to maintain the status quo at a fraction of the cost in order to make the system last longer.

  1. case

The EMP micro front-end solution independently developed by THE WEB front-end team of YY business center is realized based on MF’s ability. Project address: github.com/efoxTeam/em… Qiankun framework can directly see the website, address: qiankun.umijs.org/zh/guide/tu…

Both can be microfronds with different granularity and use scenarios.

The disadvantage of MF

  1. Slightly higher requirements on the environment, need to use Webpack5, old project renovation cost.
  2. For projects with high code closure, NPM still needs to do the same set of management and extra pull code, which is not as convenient as NPM reuse.
  3. The granularity of splitting is a tradeoff. While it is possible to rely on sharing, the shared lib cannot be tree-shaking, which means that if a Lodash library is shared, the entire Lodash library is packaged into shared-chunk. Although relying on sharing can solve the version consistency problem of externals of traditional microfronts.
  4. Webpack has done a lot of work with the Runtime to support loading the Remote module, which dramatically increases the number of things to do at runtime, potentially negatively impacting the runtime performance of our pages.
  5. Runtime sharing is also a double-edged sword, and how to do version control and control the impact of shared modules is an issue to consider.
  6. Problems with remote module typing.

conclusion

MF has a lot of imagination, worth exploring and paying attention to. MF is not a silver bullet, or need to be combined with the scene to choose. I’m going to stop here for space. Next time, let’s talk about how MF works in detail

References & relevant browsing materials

  • Juejin. Cn/post / 689532…
  • www.zhihu.com/question/37…
  • Nextfe.com/5-practical…
  • zhuanlan.zhihu.com/p/220138948
  • Webpack.js.org/concepts/mo…

The last

My full blog: github.com/LuckyWinty/…