Why do you need to learn about WebPack5 Module Federation? Because the EMP micro front end scheme is based on this revolutionary function, it has a historical breakthrough significance. In this article, you will learn the principles of WebPack5 Module Federation, master the underlying building blocks of EMP micro front-end solutions, and make it easier to use and apply EMP micro front-end solutions.
Webpack5 has recently been released, and one of the most exciting new features is Module Federation (mf), which is the main character of the day. The following three aspects (what, how, where) will explore the mystery of this feature.
I. What is it
In the official webpack document, the real meaning of Module Federation is not given, but the motivation of using this function is given. The original text is as follows
Multiple separate builds should form a single application. These separate builds should not have dependencies between each other, so they can be developed and deployed individually.
This is often known as Micro-Frontends, but is not limited to that.
Copy the code
Translated into Chinese is
Multiple independent builds can form an application. These separate builds do not depend on each other, so they can be developed and deployed separately. This is often called a micro front end, but it's not limited to that.Copy the code
Combined with the above, it is not difficult to see that what MF is really trying to do is to combine multiple non-interdependent, independently deployed applications into one. In general terms, MF provides the ability to remotely load applications on other servers within the current application. To this, the following two concepts can be introduced:
- Host: An application that references another application
- Remote: an application used by another application
Given mf’s capabilities, we can fully implement onedecentralizedApplication deployment cluster: Each application is deployed on its own server. Each application can refer to and be referenced by other applications. That is, each application can serve as a host or a remote.
How to use it
Configuration example:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
// Other WebPack configurations...
plugins: [
new ModuleFederationPlugin({
name: 'empBase'.library: { type: 'var'.name: 'empBase' },
filename: 'emp.js'.remotes: {
app_two: "app_two_remote".app_three: "app_three_remote"
},
exposes: {
'./Component1': 'src/components/Component1'.'./Component2': 'src/components/Component2',},shared: ["react"."react-dom"."react-router-dom"]]}})Copy the code
From the above configuration, we have a preliminary understanding of mf. To use MF, we need to configure several important properties:
The field name | type | meaning |
---|---|---|
name | string | The mandatory value, that is, the output module name, is referenced remotely in the path of${name}/${expose} |
library | object | How to declare a global variable with name as umD name |
filename | string | Build the file name of the output |
remotes | object | Mapping of the remote referenced application name and its alias. The name is a key value |
exposes | object | Resource paths and aliases 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 repeatedly in your code |
3. Build the analytical principle
Let’s look at the code after the build:
var moduleMap = { "./components/Comonpnent1": function() { return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react_react"), __webpack_require__.e("src_components_Close_index_tsx")]).then(function() { return function() { return (__webpack_require__(16499)); }; }); }}; var get = function(module, getScope) { __webpack_require__.R = getScope; getScope = ( __webpack_require__.o(moduleMap, module) ? moduleMap[module]() : Promise.resolve().then(function() { throw new Error('Module "' + module + '" does not exist in container.'); })); __webpack_require__.R = undefined; return getScope; }; var init = function(shareScope, initScope) { if (! __webpack_require__.S) return; var oldScope = __webpack_require__.S["default"]; var name = "default" if(oldScope && oldScope ! == shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope"); __webpack_require__.S[name] = shareScope; return __webpack_require__.I(name, initScope); }Copy the code
As you can see, the code consists of three parts:
- ModuleMap: A collection of modules generated through exposes
- Get: host This function is used to retrieve components from remote
- Init: host injects dependencies into remote using this function
Look at the moduleMap, which loads its dependencies through __webpack_require__.e before returning the corresponding component. Let’s see what __webpack_require__.e does:
__webpack_require__.f = {};
// This file contains only the entry chunk.
// The chunk loading function for additional chunks
__webpack_require__.e = function(chunkId) {
// Get the dependencies in __webpack_require__.f
return Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {
__webpack_require__.f[key](chunkId, promises);
returnpromises; } [])); }; __webpack_require__.f.consumes =function(chunkId, promises) {
// Check whether the chunk to be loaded is declared as a shared resource in the configuration item using __webpack_require__.o. If it can be found, use it instead of requesting it
if(__webpack_require__.o(chunkMapping, chunkId)) {
chunkMapping[chunkId].forEach(function(id) {
if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
var onFactory = function(factory) {
installedModules[id] = 0;
__webpack_modules__[id] = function(module) {
delete __webpack_module_cache__[id];
module.exports = factory(); }};try {
var promise = moduleToHandlerMapping[id]();
if(promise.then) {
promises.push(installedModules[id] = promise.then(onFactory).catch(onError));
} else onFactory(promise);
} catch(e) { onError(e); }}); }}Copy the code
After reading through the core code, we can summarize it as follows:
- First, MF will allow Webpack to
filename
Generate files as file names - Second, a named var is exposed in the file as var
name
Which contains the global variableexposes
As well asshared
Is configured in the - Finally, as
host
, pass firstremote
theinit
Method will itselfshared
writeremote
Middle, pass againget
To obtainremote
In theexpose
As a component ofremote
The judgehost
Is there a shared dependency available in the. If yes, load ithost
If none is found, the dependency itself is loaded.
Iv. Application Scenarios
Let’s take a look at the application scenarios of MF:
- Micro front: Through shared and exposes, multiple applications can be brought into the same application for management. The EMP micro front plan independently developed by the Web front end team of YY business center is based on MF capabilities.
- Reuse resources, reduce compilation volume: Common components used by multiple applications can be deployed separately, and the MF function can be introduced to other projects at Runtime, so that the component code will not be compiled into the project, but also meet the needs of multiple projects at the same time, kill two birds with one bird.
5. The last
At present, only EMP micro front end solution is a set of micro front end solution with mature scaffolding and complete ecology based on Module Federation, and 80% of large projects have been applied in Yy Company. From this paper, we can also recognize that EMP micro front end solution is forward-looking, extensible and has reliable foundation. For EMP micro front-end solutions, there is a complete wiki for you to learn:
-
Basic Knowledge analysis
What is a micro front end
Compare a variety of micro front end solutions
Learn principles of WebPack5 Module Federation
The design architecture of EMP
-
Quick start
How does the React project use and access EMP
How do VUE projects use and access EMP
Tutorial for using auxiliary plug-ins
-
Advanced tutorial
How do Vue and React projects call each other remotely
How to use and access EMP for cocos2D project
Teach you base station building skills