How do we reuse code in our daily development?

The answers are as follows:

  • Copy and paste. This is the easiest approach for a junior engineer to take. While it is simple and effective, it causes many problems in code maintenance, such as adding a lot of duplicate code and changing the logic of reusable code everywhere. Therefore, such violations of the DRY (Don’t Repeat Yourself) principle should be avoided as much as possible.
  • Encapsulate modules. A more experienced engineer would consider encapsulating code logic into modules that can then be reused by referring to modules. For example, the most common component is a code module that integrates view operations. This approach solves the problem of copy-and-paste maintainability, but not when the scenario is scaled up, such as when multiple projects are using the same module.
  • Package into a library. Module is a good solution to reuse code across files. For reuse across projects, it can be packaged as a library, such as the front-end domain will be packaged as a library and published to NPM, and then installed through the command line tool when used.
  • Provide services. In fact, the reuse of libraries has its drawbacks. First, libraries have specific dependencies. For example, to use vUe-based tree components in React projects, Vue must be introduced as well, which will inevitably increase the volume and complexity of projects. Secondly, libraries are more inclined to reuse functions, and business-oriented codes are rarely implemented by libraries. With a micro front-end architecture, you can break down the micro applications by business and then reuse the required micro applications by means of configuration references.

However, the micro front end was first proposed not for code reuse, but to split and decouple projects.

Microfront-end concept

The term “microfront-end” was first proposed in ThoughtWorks Technology Radar at the end of 2016. It extends the concept of back-end microservices to the front-end world. Microservice is a bounded context, loosely coupled architectural pattern proposed by the server, which is to break the application server into smaller microservices, which can run independently and use lightweight communication methods (such as HTTP).

The concept of a micro front end can be understood in the following diagram of the evolution of Web application architecture patterns.

The original architectural pattern is monolithic Web applications, developed by a single team.

As technology evolved, development responsibilities began to be subdivided, and the team responsible for a project could be divided into front-end and back-end teams, which led to the emergence of a front-end and back-end architecture.

As projects become more complex, the back end is the first to feel the pinch, and architectural patterns for microservices begin to emerge.

With the further improvement of the front-end operating environment, the development trend of Web applications is more and more toward rich applications, that is, more and more functions are integrated in the browser side, and the amount of front-end code and business logic also begins to rapidly increase, which becomes more and more difficult to maintain. Therefore, the architecture idea of microservices is introduced to divide websites or Web applications into smaller microapplications according to business, which are developed by independent teams.

As can be seen from the figure, the evolution trend of micro-front-end, micro-service and other architectural patterns is to continuously split logic, thus reducing project complexity and improving maintainability and reusability.

Micro front-end application scenarios

As can be seen from the evolution process above, the micro-front-end architecture is more suitable for large-scale Web applications, and there are the following three common forms

  • The platform system within the company. There is a certain correlation between these systems. Users may have to perform cross-system operations during the use of these systems. Frequent page hops or system switching may lead to low operation efficiency. Moreover, repetitive functions, such as user management, may be developed within multiple independent systems, resulting in increased development costs and user usage costs.
  • Large single-page applications. Such applications are characterized by large system volume, which takes a lot of time in daily debugging and development, seriously affecting the development experience and efficiency. In addition, with the upgrading of business functions, the volume of the project will continue to increase, and the transformation cost will be very high if the project needs to upgrade the architecture.
  • Compatibility and extension of existing systems. For example, some projects are using old technology, and with the use of a micro front end, new technical frameworks can be used for the development of new functions, avoiding overturning refactoring and continuing development based on outdated technology.

Micro front end core idea

The micro front-end architecture follows three core ideas.

1. Technology is irrelevant

The front end looks pretty uniform, unlike the server side, which has a lot of language choices (Java, Python, Go, PHP, etc.), but there are still frameworks that diverge. The microfront-end architecture requires that each team retain the right to choose the technology stack, which means that different microapplications can choose different technology frameworks to implement, including different release cycles and release processes.

2. Environment independence

To achieve a high degree of decoupling, each microapplication should not share the runtime environment, and even though all microapplications use the same framework, they should try to avoid relying on shared state or global variables between them.

To avoid conflicts between microapplications, some common scopes should be isolated, such as by naming prefixes.

For CSS isolation, it is easy to conflict between the main application and micro-application. You can use CSS Modules or namespaces to write each micro-application with a specified prefix, or use the PostCSS plug-in to add a specific prefix when packaging.

Another way to separate CSS from microapps is to unload the link and style of the previous microapp each time a new microapp loads.

JavaScript isolation is a little trickier, and it’s better to sandbox it. The core of the sandbox mechanism is to keep the local JavaScript runtime’s access to and modification of external objects under control, meaning that no matter what happens inside, it doesn’t affect external objects. The browser-side sandbox can be implemented with the with keyword and the window.proxy object.

It is important to note that the core of the sandbox mechanism is to create a virtual runtime environment, not the same as creating a separate scope. In a separate scope, there is a risk of contamecting global variables. For example, if you change the native API to array.prototype. forEach =null in a separate scope, then all subsequent arrays created by the sandbox will generate an error when executing forEach.

This sandbox mechanism not only ensures independence between microapplications, but also the stability of the main application, so when a microapplication’s JavaScript fails or has not yet executed, the entire application should still be available.

3. Native is preferred

Native uses browser events for communication in preference to self-encapsulated publish-subscribe systems. If you do have to communicate across applications, keeping what and how simple is a great way to reduce common dependencies between microapplications.

Micro front-end architecture patterns

After understanding the fundamentals of the micro front end, let’s see how it is implemented. Micro-front-end architecture can be divided into two categories according to the location of integrated micro-applications:

  • Integrate microapplications on the server side, such as forwarding through Nginx proxies;
  • Integrate micro-applications in the browser, such as custom element capabilities using Web Components.

Some say by building tools to integrate at compile time also belong to the category of micro front-end, such as the application of NPM package release independently, common as the main application of dependency, build produces a JS Bundle for deployment, but this way does not conform to the core of the micro front-end, also is not the mainstream of the front-end is implemented, So we won’t discuss it in depth. This article covers only server-side and browser-side integration

Server-side integration

The common way of server integration is to carry out routing and forwarding on the server through reverse proxy, that is, to forward different requests to corresponding micro applications through path matching. This architectural approach is relatively easy to implement and requires less effort to modify, because a patchwork of different Web applications is not, strictly speaking, a complete Web application. When users jump from one microapplication to another, they often need to refresh the page to reload resources.

This proxy forwarding mode has an advantage over the direct jump to the corresponding Web application, that is, the communication between different applications becomes simple, because in the same domain, the data such as localstorage and cookie can be shared. For example, each micro-application requires a token for identity authentication information. In this case, you only need to write the token information to localstorage after login. Then all subsequent micro-applications can use it without re-logging in or transferring login information in other ways.

Browser integration

Browser integration, also known as runtime integration, can be done in the following three common ways.

  • The iframe. Different microapplications are integrated into the main application through iframe, which has low implementation cost, but has some problems in style and compatibility. For example, some values of sandbox attribute are not supported in IE.
  • Front-end routing. Each microapplication exposes a rendering function. The main application loads the main module of each microapplication at startup, and then renders the corresponding microapplication according to the routing rules. Although the implementation is more flexible, but there is a certain transformation cost.
  • Web Components. Loading different micro-applications based on native custom elements and using Shadow DOM to achieve isolation, the transformation cost is relatively large.

This is also a very popular integration approach, with frameworks such as Single-SPA and the universe based on it.

conclusion

This paper introduces the concepts related to micro-front-end technology, and the core content is as follows:

  • First of all, the micro-front-end architecture is derived from micro-services, which aims to split and isolate projects so as to improve the maintainability and reusability of projects.
  • Secondly, there are three core ideas of the micro-front-end architecture: technology independent, environment independent and native priority. Environment independence is difficult to achieve and requires the help of certain technical means or code specifications.
  • Finally, the mainstream micro front end implementation methods can be roughly divided into two categories, namely, server side integration or browser side integration. Server side integration is generally realized by proxy forwarding. Browser-side integration is implemented in many ways, with frameworks such as Single-SPA supporting it.

Public account “Grace Front end”

For every aspiring “front-end ER” to lead the way, build dream aspirations.

Just to be an excellent front end Engineer!