Preface
MicroApp is a micro-front-end framework based on WebComponent-like rendering. Different from the current popular open source framework, it realizes the micro-front-end from the component-based thinking, and aims to reduce the difficulty of getting started and improve work efficiency. It is currently the lowest cost framework for accessing micro front-ends on the market, and provides a series of complete functions such as JS sandbox, style isolation, element isolation, preloading, resource address completion, plug-in system, and data communication. MicroApp has nothing to do with the technology stack, nor is it tied to the business, and can be used in any front-end framework and business.
In this article, we will introduce MicroApp from the business background and implementation ideas, and will also introduce its use and technical principles in detail.
Business background
With the rapid development of the Internet in these years, the web applications of many companies have become more and more complex in the continuous iteration, and the number of participating personnel and teams continues to increase, resulting in difficult maintenance problems. This situation is especially common on the PC side. Many research and development The team is also looking for a solution to efficiently manage complex applications, so the micro front end is mentioned more and more frequently.
Micro front-end is not a new technology, but an architectural concept that disassembles a single web application into multiple small applications that can be independently developed, run, and deployed independently, and integrate them into one application.
In actual business, we also encountered the same problem, and tried various solutions in different business scenarios, such as iframe, npm package, micro front-end framework, and compared the pros and cons of various solutions.
iframe : Among all micro-front-end solutions, iframe is the most stable and the least difficult to get started, but it has some unsolvable problems, such as low performance, complex communication, dual scroll bars, and pop-ups that cannot be globally covered. Growth is not high, only suitable for simple page rendering.
npm package : encapsulate sub-applications into npm packages, and import them through components. It is the best solution in terms of performance and compatibility, but there is a fatal problem that is version updates. Each version release requires notification to access It is very difficult to manage the updates simultaneously.
micro-front-end framework : Popular micro-front-end frameworks include single-spa and qiankun, which balance maintenance costs and functions, and are currently a highly respected solution for realizing micro-front-ends.
Since the problems of iframe and npm packages cannot be solved theoretically, we used qiankun as the solution at the beginning. qiankun is packaged on the basis of single-spa, providing js sandbox, style isolation, pre-loading and other functions, and is compatible with technology It has nothing to do with the stack and can be compatible with different frameworks.
Business appeal
Although Qiankun is excellent, it still cannot meet our expectations. The first question is that in our actual use scenario, each project connected to the micro front end has been running for a long time, and each project is responsible for different people and teams. How to reduce the intrusion to the source code, reduce code modification and communication Cost, this is a point we are very concerned about, so we need a solution that is less expensive than qiankun access. The second problem is that in the case of multi-party application access, the sandbox cannot perfectly circumvent all problems, but qiankun's ability to deal with such unpredictable problems is not very efficient. In constant exploration, we found an extremely concise implementation idea, which is as simple as using components, only a little code can be modified to connect to the micro front end, and a plug-in system is also provided to give developers the ability to deal with problems flexibly .
Realization ideas
The micro front end is divided into a main application and a sub-application. The main application is also called a base application, which is the container carrier for other applications, and the sub-application is the embedded party. From the perspective of the main application and the sub-application, we explore a more concise and effective way to access the micro front end.
Thinking about qinkun and single-spa
In both single-spa and qiankun, the url change event is monitored, and the rendered sub-application is matched and rendered when the route changes. This routing-based monitoring rendering is the earliest implementation of single-spa. As the earliest and most influential micro-front-end framework, single-spa has been used for reference by many frameworks and companies, and the current implementation of micro-front-end methods are mostly based on routing. monitor.
At the same time, single-spa requires the sub-application to modify the rendering logic and exposes three methods: bootstrap, mount, and unmount, which correspond to initialization, rendering, and unmounting, respectively. This also causes the sub-application to modify the entry file. This feature has also been inherited by qiankun, and some modifications to the webpack configuration are required.
Is it necessary to implement route monitoring and modify the sub-application entry file and webpack configuration?
In fact, it is not. The core of the micro front end lies in resource loading and rendering. The rendering method of iframe is a typical one. As long as a function of element isolation can be realized and the routing meets the requirements, the sub-application can be embedded in another page without modifying the code in theory. Rendering, we try to find a different realization idea from this perspective.
Componentization of the micro front end
If you want to simplify the implementation steps of the micro front end, you must abandon the old implementation ideas and explore a different path.
We borrowed the idea of WebComponent, and introduced another more component-based implementation based on this: WebComponent + HTML Entry.
HTML Entry : refers to setting html as a resource entry, by loading remote html, parsing its DOM structure to obtain static resources such as js, css, etc. to achieve the rendering of the micro front end. This is also the rendering scheme currently adopted by qiankun.
WebComponent : web native component, it has two core components: CustomElement and ShadowDom. CustomElement is used to create custom tags, ShadowDom is used to create shadow DOM, which has natural style isolation and element isolation properties. Since WebComponent is a native component, it can be used in any framework, and it is theoretically the best solution for realizing micro front-end. But WebComponent has an unsolvable problem-the compatibility of ShadowDom is very poor, and some front-end frameworks cannot run normally in the ShadowDom environment, especially the react framework.
class WebComponent : is to use CustomElement combined with custom ShadowDom to achieve basically the same function of WebComponent.
Due to the problems of ShadowDom, we use custom style isolation and element isolation to achieve similar functions to ShadowDom, and then encapsulate the micro front-end application in a CustomElement, thereby simulating a WebComponent-like component. Its usage and compatibility are similar to The WebComponent is consistent, and it also avoids the ShadowDom problem. And because of the isolation features of custom ShadowDom, Micro App does not require sub-applications to modify rendering logic and expose methods like single-spa and qiankun, nor does it need to modify webpack configuration.
We encapsulated a custom tag micro-app
through the above solution. Its rendering mechanism and function are similar to that of WebComponent. Developers can access the micro front end just like using web components. It can be compatible with any framework, and it is more componentized in usage and data communication, which significantly reduces the access cost of the base application, and due to the element isolation property, the amount of sub-application changes is also greatly reduced.
How to use
Next, we will separately introduce the access methods of the main application and sub-applications.
Take react code as an example
Main application
Each custom tag micro-app
rendered as a sub-application of the micro front end, and its use is similar to the iframe tag.
We need to pass three basic attributes to the tag:
- name: name
- url: sub-application page address
- baseurl: baseurl is the routing prefix assigned by the base application to the sub-application
The usage is as follows:
Sub application
If the sub-application has only one page and no routing configuration, no modification is required.
If the sub-application has multiple pages, you only need to modify the routing configuration and add the routing prefix.
as follows:
window.__MICRO_APP_BASE_URL__ is the routing prefix issued by the base application. In a non-micro front-end environment, this value is undefined
After completing the above configuration, the rendering of the micro front end can be realized, with few changes to the source code. Of course, MicroApp also provides some other capabilities, such as plug-in system, data communication, we will introduce in detail next.
Core principle
The core functions of MicroApp are built on the basis of CustomElement. CustomElement is used to create custom tags, and provides hook functions such as element rendering, uninstallation, and attribute modification. We know the rendering timing of the microapp through the hook function, and customize the tags. As a container, all elements and style scopes of a micro application cannot escape the container boundary, thus forming a closed environment.
Concept map
Rendering process
The life cycle function connectedCallback
custom element micro-app
is used to monitor the element being rendered, load the html of the sub-application and convert it to the DOM structure, recursively query and load all static resources such as js and css, set element isolation, and intercept all dynamically created scripts and links Wait for tags and extract the tag content. After the loaded js is processed by the plug-in system, it is put into the sandbox to run, and the CSS resources are styled isolated. Finally, the formatted elements are put into micro-app
, and the micro-app
element is finally rendered into a micro-front-end sub-application. During the rendering process, the life cycle functions bound by the developer will be executed for further operations.
flow chart
Element isolation
Element isolation originates from the concept of ShadowDom, that is, the elements in ShadowDom can be repeated with external elements but will not conflict, and ShadowDom can only operate on its own internal elements.
MicroApp simulation achieves similar functions. We intercept the methods of the elements on the underlying prototype chain to ensure that sub-applications can only operate on their own internal elements, and each sub-application has its own element scope.
Element isolation can effectively prevent sub-applications from misoperation of the base application and other sub-application elements. A common scenario is that the root elements of multiple applications use the same id. Element isolation can ensure that the rendering framework of the sub-application can correctly find itself The root element.
Concept map
actual effect
As shown in the figure above, the micro-app
element is a sub-application, and it also has two custom elements micro-app-head
and micro-app-body
. The functions of these two elements correspond to the head and body elements in html, respectively. The content of the sub-application in the original head element and some link and script elements dynamically created and inserted into the head will be moved to micro-app-head
, and the content in the original body element and some dynamically created and inserted body elements will be moved to micro-app-body
. This can prevent the elements of the sub-application from leaking to the whole world. When performing element query, deletion, etc., only need to micro-app
, which is an important basis for achieving element isolation.
micro-app
can be understood as an embedded html page, its structure and function are similar to the html page.
Plug-in system
The use scenario of the micro front end is very complicated, and even if there is a sandbox mechanism, all problems cannot be avoided, so we provide a plug-in system to solve some unpredictable problems.
A plug-in can be understood as an object that meets specific rules. The object provides a function for processing resources. The plug-in is usually customized by the developer.
The role of the plug-in system is to perform preliminary processing of the incoming static resources, and call the eligible plug-ins in turn, pass the initially processed static resources as parameters to the plug-in, and the plug-in will further modify the content of the resource, and the modified The content is returned. The plug-in system gives developers the ability to flexibly handle static resources and modify problematic resource files.
The plug-in system itself is pure and will not affect the content of resources. Its role is to coordinate how each plug-in is executed. When the developer does not set the plug-in, the incoming and outgoing content is the same.
js sandbox and style isolation
The js sandbox uses Proxy to proxy the global objects of sub-applications to prevent conflicts of global variables between applications, record or clear the global side-effect functions of sub-applications, and inject global variables into sub-applications for customized processing.
Style isolation refers to formatting the css content of the link and style elements of the sub-application to ensure that the style of the sub-application only scopes itself and cannot affect the outside.
MicroApp draws on the js sandbox and style isolation scheme of qiankun, which is also a widely used and mature scheme at present.
Preloading
MicroApp provides the function of pre-loading sub-applications. It is implemented based on requestIdleCallback. Pre-loading will not affect the rendering speed of the base application and other sub-applications. It will load the static resources of the application during the idle time of the browser. When it is actually rendered, the resource is directly obtained from the cache and rendered.
Resource address completion
Resource loss often occurs in the micro front end. The reason is that the base application loads the resources of the sub-application into its own page rendering. If the static resource address of the sub-application is a relative address, the browser will complete it with the domain name address where the base application is located. Static resources, resulting in loss of resources.
Resource address completion is to complete the relative address of the static resource of the sub-application into an absolute address to ensure that the address points to the correct resource path. This operation is similar to setting publicPath at runtime by webpack.
The life cycle
When the micro application is rendered, the micro-app
element will trigger the corresponding life cycle events in different rendering stages, and the base application can perform corresponding operations by listening to the events.
List of life cycles:
- created: When the micro-app tag is created, it is executed before loading the resource.
- beforemount: The resource is loaded and executed before the official rendering.
- mounted: execute after the sub-application has been rendered
- unmount: Execute when the sub-application is uninstalled.
- error: Execute when a destructive error occurs and rendering cannot continue.
During uninstallation, the sub-application will also receive an uninstallation event, which is used to perform uninstallation-related operations.
data communication
Data communication is a very important function in the micro front end. There are many technical solutions to realize data communication. An excellent solution can improve development efficiency and reduce trial and error costs. We have also studied the data communication methods of micro front-end frameworks such as qiankun, but their implementation methods are not suitable for us. We try to achieve data communication in the form of passing complex data directly through element attributes.
The most familiar to front-end developers is the way of componentized data interaction, and the custom element micro-app, as a class of WebComponent, must be the best way to interact with data through component properties. But the biggest problem that MicroApp encounters in data communication is that custom elements cannot support setting object type attributes. For example, <micro-app data={x: 1}></micro-app>
will be converted to <micro-app data='[object Object]'></micro-app>
. If you want to communicate in a componentized form, you must let the element support object attributes.
To solve this problem, we rewrite the micro-app
method property set on the elements of the prototype chain, in micro-app
saved to the data center elements when setting the value of the object will be passed by the data center will distribute the value of sub-applications.
Data in MicroApp is bound to communicate, that is, each micro-app
element can only communicate with the sub-application that it points to, so that each application has a clear data link, which can avoid data confusion. At the same time, MicroApp also supports global communication, so that Pass data across applications.
Data communication concept map
Frame comparison
In order to more intuitively feel the difference between Micro App and other frameworks, we use a picture for comparison.
It can be seen from the comparison chart that the current open source micro front-end framework has some functions MicroApp, and provides some functions they do not have, such as static resource address completion, element isolation, plug-in system, etc.
Business practice
MicroApp has been used in many projects within the company and has performed well, especially the transformation of some old projects into micro front-ends. Under the condition that the project is not affected, it reduces the access cost, while ensuring the smooth operation of the project and reducing coupling .
Why open source?
When our team planned to use the micro front-end, we investigated the framework for implementing the micro-front-end on the market, and the only choices available were sigle-spa and qiankun. Single-spa is too basic, too much modification of the original project, and the cost is too high. The only thing left is qiankun, but because of the access to many old projects, there were many problems in actual use, and we had to make a lot of magical changes to the source code of qiankun. In the process, we developed some of our own ideas about the implementation of the micro front end, and put these ideas into practice, so we have MicroApp.
At present, there are too few micro front-end frameworks that provide complete functions like qiankun. When the access to qiankun fails, there is no other solution to choose from. This is the pain we experienced at the beginning. So we chose to open source MicroApp. First, MicroApp has many innovations, allowing easier access to micro front-ends and richer functions. Second, it allows everyone to have one more choice. There is no perfect micro-front-end framework, only more choices. , I know which one is more suitable for me.
If you are interested in this project, you can participate in the joint construction by joining the organization or making pull requests. You are very welcome and looking forward to joining.
navigation
GitHub address: https://github.com/micro-zoe/micro-app
Official website address: https://cangdu.org/micro-app
Special thanks: qiankun
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。