The background,


The school started with TOB, and it is well known that THE TOB business is easy to turn into boulder applications. In the past two years, the school has developed rapidly, and one of our major front-end projects has encountered a bottleneck, which is that the project is too big.

In order to reduce coupling and speed up packaging, we chose to take some functionality out of the new project and introduce it into the main project as an iframe. While the problem of project size was solved, the user experience was reduced.


Because every time the user switches to the TAB of the iframe, no matter how well optimized, there is always a flash of white screen, the system is not consistent, and the url of the browser’s address bar does not change when switching pages in the iframe, giving the impression of two systems.

The rapid growth of our business has forced us to find a new approach – the micro front end.


Second, the basic concept of micro front end


1. What is a micro front end


A popular concept in the last two years is the micro front end. The term originally came from ThoughtWorks Technology Radar in 2016, which extended the concept of microservices to the front end. The current trend is to build a rich and powerful front-end application called a single page application (SPA). The front end layer is typically developed by a single team and over time becomes larger and harder to maintain. This is the legendary Frontend Monolith.


The idea behind the micro front is to treat a website or Web App as a collection of features, each of which is handled by a separate team. Each team has a specific business area of expertise or task it cares about. Here, a team is cross-functional and can fully develop the functionality it is responsible for end-to-end, from the database to the user interface.


However, the concept is not new; it used to be called front-end integration or standalone systems for vertical systems. It’s just that micro front is obviously a friendlier and less cumbersome term.


2. Advantages of micro front end


◾ Complexity controllable: each UI business module is developed by an independent front-end team to avoid code oversize, maintain high-speed compilation during development, maintain low complexity, and facilitate maintenance and development efficiency.

◾ Independent deployment: Each module can be stored and deployed separately without affecting other modules.

◾ Flexible technology selection: it is also the most attractive. All the front-end technology stacks on the market today, including future front-end technology stacks, can be used under the same project.

◾ Fault tolerance: If a single module fails, the fault does not affect the whole module.

◾ Scaling: Each service can scale independently to meet business scalability, with unnecessary consumption of resources.


3. When do we need front-end microservitization


◾ The project technology stack is too old, the relevant skills of the developers are few, functional expansion is difficult, refactoring costs are high, maintenance costs are high.

The ◾ project is too large, the code is slow to compile, the development is poor, and a higher dimensional decoupling solution is needed.

◾ A single technology stack will not meet your business needs.

◾ other existing projects need to be integrated into the main project.


4. Several ways to implement a micro front end


◾iframe: The iframe is the simplest and most direct method. The iframe provides sandbox isolation, enabling multiple applications to run on the same user interface.

◾ Route distribution micro front-end: That is, routes are used to distribute different services to different, independent front-end applications, typically aliyun.

◾ Build with Web Components technology: Use Web Components to build frame-independent Components and then introduce those Components into the corresponding framework, suitable for smaller modules.

◾ Home-made framework compatible applications: the representative frameworks include Single-SPA and Ali qiankun. Introduce or create the DOM in the appropriate place on the page. When the user operates, the corresponding application is loaded (triggering the startup of the application), and the application can be uninstalled.


5. Comparison of single applications and micro-front-end architectures


◾ Single Application

◾ micro front-end



3. How to achieve micro front-end applications


1. Basic concepts


, it can be concluded that implement a set of micro front-end architecture reference is divided into four parts: https://alili.tech/archive/11052bf4/


◾ Loader: The core of the micro front-end architecture. It is used to schedule sub-applications and decide which sub-applications to display when. It can be thought of as a power supply.

◾ wrappers: With loaders, you can wrap existing applications so that the loaders can use them. They are equivalent to power adapters.

◾ Main application: Typically a project that contains the common parts of all sub-applications – it’s the equivalent of an electrical base.

◾ sub-apps: Numerous apps that are displayed in the main app content area — the equivalent of your appliances.


So this is the concept: power supply (loader)→ power adapter (wrapper)→️ appliance base (main application)→️ appliance (sub-application)️.


In general, the process is as follows: after the user accesses index.html, the browser runs the JS file of the loader, and the loader goes to the configuration file. After registering each sub-application configured in the configuration file, the main application (menu, etc.) is loaded first, and then the sub-application is loaded dynamically and remotely by route determination.


2. Preliminary knowledge


✅ SystemJs


SystemJS provides a generic approach to module import, supporting both traditional and ES6 modules. There are two versions of SystemJS. Version 6.x is used in browsers, and version 0.21 is used in browsers and node environments.

Reference: https://github.com/systemjs/systemjs

The main role in microservices is as a loader.


It is worth noting that we have not chosen to use System.js for the time being, because after research, there are very few resources to load at present, which makes us feel like killing a cow by killing a cow. At present, our approach is to dynamically create scripts to reference resources, of course, the orthodox approach is to use System.js.


✅ singleSpa

Single-spa is a framework for bringing together multiple javascript applications in a front-end application. Primarily as a wrapper.

Reference: https://single-spa.js.org/docs/getting-started-overview.html


Iv. Concrete implementation steps


First, you need two front-end projects, a main project and a subproject. The main project has the basic login and navigation modules, and the rest of the main business logic is in the subproject.

Since we know that the main front-end technology stack in the future is VUE, we will use vUE as an example, of course react and Angular are also applicable.


1.)


◾ First let’s look at the changes in vue.config.js

This option indicates where the resource file is to be loaded from. Normally, this option indicates where the resource file is to be loaded from the root directory of the website, but now it is to be loaded from the storage address of the sub-project.

The devServer needs to add a new header header for cross-domain use. The main reason for this is that when we are developing locally, the resource loading sub-project port number from the main project port number will also cross domain.

The output option specifies the name of the resource bundle and the runtime environment. In this case, we chose window. Note that if we use System.js, this option specifies umD mode.

The stats-webpack-plugin is a plugin that describes how dependencies are referenced to each other. Now we use it to generate a manifest.json file. What’s in the manifest.json file? So let’s see.

In this case, we use entryPoints, as you can see, this is the entry file that we need to load to start the subproject. In other words, we can request the manifest.json file in the main project to know which js we need to load.

Here we also add the CSS to the scope single-SPa-vue, subproject, so the CSS only works under this style prefix, ensuring that the subproject style does not affect the main project.


◾ Then a change to main.js

Here we use a small plug-in single-SPA-Vue. The main function of this plug-in is to export the three life cycles required by the single-SPA framework: bootstrap, mount, and unmount. The equivalent is single-spa-react and single-spa-angular. As you can see, the way we write it ensures that the subproject runs as a module in the main project, can be packaged and deployed separately, or can even exist in parallel.


◾ router. Js modified

This url prefix is our module route prefix in the main project. If you do not add this url prefix in the main project, the sub-project will not be matched when the main project refresh the page.


2. The main project


The single-spa-config.js file is added to ◾

The main steps are to dynamically create the script tag, remotely load the JS files required by the subproject, and then register the microservice module ‘learnSystem’.


At first this file was loaded in main.js, but then it became a problem if the subproject could be loaded faster than the main project, so we put it in the created hook function of app.vue and introduced it with require to make sure that the subproject was loaded after the main project was loaded.

In the figure above, LEARN_URL can be configured with different values depending on the environment. For example, the development environment can be configured with localhost+ subproject port number, and the production environment can be configured with online links.


◾ router. Js

Fuzzy matching * should be added to the router; otherwise, if the current page of the submodule is directly refreshed, the 404 page of the main item will be entered first


◾ App. Vue

We started our app. vue with just one router-view, now we need to provide a container for subprojects to render. Remember the single-spa-vue scope? Make sure that the styles of the subproject only take effect in this div


3. Communication between the main project and the sub-project


In general, we recommend trying to avoid this – coupling these applications together. If you find yourself doing this frequently between applications, you might want to consider that those individual applications should really be just one application. However, there are some scenarios where communication is needed, such as when the sub-project request interface discovers that the token has expired, it needs to notify the main project to log out and jump to the login interface.

We use a simple method. Since both projects belong to the same window, they also share a window object. Register a method in the main project and mount it to the window object, and call the method in the child project.


4. Optimize the packaging configuration


Since both the main project and the subproject use the same part of the dependencies, consider unpacking the common dependencies and introducing them in the main project to improve packaging efficiency by modifying vue.config.js

Note that a shareable resource must be one that the main project and the subproject use the same version of their dependencies, or that is compatible with the same version. If a dependency is too different from one another, then it is not a shareable resource.


Five, the conclusion


This plan can only be said to be a feasible plan, in fact, there are many places that can be optimized, we can discuss together.


Such as:

◾ We solved the CSS interaction between the sub-application and the main application, but do not forget to js, how to create a sandbox like iframe, so that the application does not affect each other, including global variable event processing, is a more important point.

◾ We can’t use vue without using Vuex, so can different applications share vuex data? Because there are some permissions and things like that that data might be generic. Or further, whether the application itself can control whether a state is a private variable of the application or a public variable accessible to other applications.

◾ We are currently loading subproject resources lazily, that is, when the route matches’ learnSystem ‘we load subproject resources. It’s actually better to preload, which is to load child application resources when the application is idle.

◾ Subapplication nesting, how to nest micro front end.

◾ How can the primary application deliver the status to a sub-application?


It’s not perfect, but it doesn’t stop us from experiencing the benefits of the micro front. We share these things with you and ask you to keep an eye on the growth of the Future School of Magic in recent years.