Micro front-end MicroApp with a simple introduction | JD Cloud technical team

Foreword:

This article is inspired by a recent project, because we have done some unification of technology stacks before. In order to use ant Design's pro-table, PC unification uses react, but we have some old projects that are based on vue. This time There are many new pages and few changes to the old pages. In addition, the old project wants to change the menu, so we want to take this opportunity to develop it with react. After some thinking, we found that it is very suitable to use micro front-end to complete this project. After meeting the needs, we finally decided to use react to build a base (main application) and connect the original vue project to the base. In this way, we not only realized the new page react development, but also the old project can be integrated with the new project.

The concept of micro frontend

What are micro frontends? Micro front-end draws on the architectural concept of micro-services. It can not only integrate multiple projects into one, but also reduce the coupling between projects and improve project scalability. Compared with a complete front-end warehouse, the micro-front-end architecture Front-end repositories tend to be smaller and more flexible. There is a base application (main application) that manages the loading and unloading of various sub-applications. Therefore, micro front-end does not refer to a specific library, a specific framework, or a specific tool, but an ideal and architectural model. The three core principles of micro front-end: independent operation, independent deployment, and independent development.

When to use micro frontends

(1) A very large project is getting bigger and bigger, making it difficult to maintain in the future.

(2) In some large factories, there are often cross-department and cross-team collaborative development projects, which will lead to reduced team efficiency and increased communication costs. At this time, we can use micro front-ends, and each team or department maintains its own independently. For projects, we only need one main project to bring together scattered sub-projects.

(3) A very old project has low development efficiency, but it cannot be completely reconstructed for a while. At this time, we can create a new base for a new technology and new project, and connect the pages of the old project to the new project. Inside, all new requirements will be developed in the new project, and there is no need to touch the old project.

(4) Want to deploy each single-page application independently.

(5) Improve initial loading time and delay loading code.

(6) Sub-applications based on multiple pages lack management, specifications/standards are not unified, and visual presentation, shared functions and dependencies cannot be uniformly controlled. Causing duplication of work.

How to create a micro frontend base

1. Micro front-end framework selection

(1) Existing framework
  1. single-spa is a JavaScript micro front-end framework that aggregates multiple single-page applications into a single overall application.

2. qiankun is a micro front-end framework based on single-spa packaging.

  1. MicroApp is produced by JD.com, a lightweight, efficient and powerful micro front-end framework based on the idea of ​​​​WebComponent.

Our project uses the umi+react+ts technology stack. In fact, it is more suitable to use qiankun. Qiankun inherits the umi framework, but this framework is more troublesome to configure. Secondly, MicroApp is owned by JD.com.

**(2)** MicroApp Advantages

1. The lowest cost to use, encapsulate everything into a WebComponent-like component, so that a micro front-end application can be rendered by embedding a line of code in the main application base.

2. There is no need to require sub-applications to modify rendering logic and expose methods like single-spa and qiankun, and there is no need to modify webpack configuration. It is currently the lowest-cost solution for accessing micro-frontends on the market.

3. Provides a series of complete functions such as js sandbox, style isolation, element isolation, preloading, data communication, and static resource completion.

4. There are no dependencies, which gives it a small size and higher scalability.

5. In order to ensure the independent development and independent deployment capabilities of each business, micro-app has made many compatibility and can run normally in any technical framework.

**(3)** MicroApp concept map

2. Scene demonstration

Take the backend management system as an example

The outermost layer is the ** base, which is an important platform for micro front-end application integration. At the same time, it also shoulders the responsibility of managing public resources, dependence, and regulations. Mainly has the following responsibilities:

(1) Sub-application integration, providing a rendering container for sub-applications

(2) Permission management

(3) Session management

(4) Routing and menu management

(5) Topic management

(6) Shared dependencies

(7) Multi-language management (the most important point), etc.

Content can be arbitrarily placed with sub-applications of different technologies. We only need to develop a main application (the main application can also freely choose the language, currently supports react, vue, vite, angular, next.js, nuxt.js), and some scattered After the application is connected, the main application can also control permissions so that different accounts see different menus, that is, they can see pages of different systems and access different sub-applications through the same address.

3. Build a micro front-end base

Take react base as an example
1. Create a project
(1) First make sure the local node version >= 14 (it is recommended to use nvm to manage the node version, and nvm-windows is recommended under windows )
(2) You can quickly create a UMI-based project as the main application by providing commands on the official website, which is what we call the base.
(3) Install dependencies
npm i @micro-zoe/micro-app --save

There will be an extra line of code in dependencies in the package.json file. Congratulations when you see the following code. The project already has micro-app access capabilities.

"@micro-zoe/micro-app": "^1.0.0-alpha.7"
(4) Introduce our micro-app at the entrance

First create a global.tsx file in the root directory

import microApp from '@micro-zoe/micro-app'

microApp.start()
(5) Introduce sub-applications into the main application

a. Assign a sub-application route

  {
    path: '/yp',
    name: 'yp',
    linkHidden: true,
    linkDisable: true,
    breadcrumbClose: true,
    component: '@/pages/yp-app',
  }


b. Sub-application files

Create a yp-app (sub-application file) under the pages file

// name (required): application name // url (required): application address, which will be automatically completed as http://localhost:3000/index.html

import React from 'react';
import config from '@/config';

// /** @jsxRuntime classic */
// /** @jsx jsxCustomEvent */
// import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event';

export default (): React.ReactElement => {
  
  // 子应用点击了面包屑的回到首页
  const onDispathChild = (e: any) => {
    const { isBackHome } = e.detail.data;
    if (isBackHome) window.location.href = '/';
  };

  return (
    <>
      <micro-app name="yp" url={config?.yp} onDataChange={onDispathChild} />
    </>
  );
};

Description: The onDataChange method is the information communication method between the sub-application and the main application. The micro-app mounts a global object under the window. We only need to trigger the methods it provides to complete the communication between the master and the child. Whether it is interaction logic or data transfer logic, everything is fine.

c. The main application successfully introduces the sub-application (the sub-application is a VUE project)

So far, if our project does not have cross-domain problems, the sub-application has successfully connected to the main application. At this time, we can see the following picture:

The left side is the main application, and the middle module is the sub-application, which contains the entire module menu and list of the sub-application. Considering that the menus are unified into the main application (base) for easy management, we need to put the menus of the sub-application pages and some different Delete the necessary things, and then we can uniformly adjust some public styles and public layouts of the sub-projects. Finally, we will get a final page of main application + sub-application page. Congratulations on getting here. You have successfully accessed the first one. Sub-application, the second application. . . . Follow the same steps for other applications.

The completion of access does not mean that all modules in your sub-application can be used. At this time, we also need to check whether the export and import interfaces are obtained from the domain name or defined separately. If the prefix in the domain name is obtained, your import at this time The export cannot be used normally. We need to re-define the import and export separately. For example, create a separate host.js file in the sub-application and reference the domain name prefix that is differentiated according to the environment.

2. Route jump

Jump to the route of the corresponding sub-application through the menu of the main application

//config.ts
let config = {
  yp: 'https://xxx.xxx.com:7000/gw',//本地环境子应用的路由前缀
};

const isEnvPro = process.env.NODE_ENV === 'production';

if (isEnvPro) {
  config = {
    yp: 'https://xxx.xxx.com/gw',//预发环境环境子应用的路由前缀
  };
}

export default config;
//以上是config.ts文件的全部-----end


//菜单点击事件里面的内容

history.push('/yp'); //切换到子应用

setTimeout(() => {
    microApp.router.push({
      name: 'yp',//和子应用的name要保持一致,为了匹配到对应子应用的路由
      path: `${config.yp}${item.url}`,
    }); //跳转子应用的路由,其中config是上面的配置文件,根据不同的环境取对应环境的子应用,item是当前点击的菜单路径信息
}, 500);

Here is an explanation of why setTimeout is used. First, switch to the sub-application through history.push('/yp') to prevent the route of the sub-application from being found in a short time after switching. Therefore, adding a delay can accurately jump to The route corresponding to the sub-application.

3. Set up cross-domain

(1) If you only use local cross-domain, you can set it for the sub-application and set cross-domain support in the headers of webpack-dev-server:

devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  }
},

This has corresponding documentation. We set different cross-domain information according to the language of the sub-application.

(2) If your interface is cross-domain.

Then you need to find the back-end settings to allow our front-end cross-domain code, Java as an example:

  @Override
    public void init(FilterConfig filterConfig) {
        this.origins = Lists.newArrayList("http://localhost:8088",
            "https://xx.51epei.com",
            "https://xx.yunxiu.com",
            "https://dev.51epei.com:8088",
            "https://xx.51epei.com:7000");
    }

This is the basic configuration. We can also change it to allow cross-domain for everything under the same domain name. It is best not to set it to '*', which is very unsafe.

4. Agent configuration

If you encounter that the main application cannot access the sub-application locally, and the access is always pre-release or online, then you need to first consider whether your agent is paired, such as one of my sub-projects, as shown in the figure:

proxy: (() => {
  return {
    //  本地访问预发
    '/avoid': {
      target: 'https://pai.51epei.com',
      changeOrigin: true,
      bypass: (req) => {
        if(req.headers.accept.indexOf('html') !== -1 ) {
          return '/index'
        }
      },
    }
  }
})()

Initially, the local proxy was proxied to the pre-issued server if the route contained '/'. Normally, the link of the sub-application was accessed separately, and the local agent pre-issued interface could be accessed normally. However, it could not be placed in the main application. Finally, the proxy was changed. It has become the public part of the entire project/avoid, which solves this problem. It may not be because of this in your project, but I think you can start with the agent to find the problem.

5. Data communication

micro-app provides a flexible data communication mechanism to facilitate data transmission between base applications and sub-applications.

Under normal circumstances, the communication between the base application and the sub-application is bound. The base application can only send data to the specified sub-application, and the sub-application can only send data to the base. This method can effectively avoid data pollution. , to prevent multiple sub-applications from affecting each other.

At the same time, we also provide global communication to facilitate data communication between applications.

The sub-application obtains data from the base application, and the base application sends data to the sub-application. The base application obtains data from the sub-application, and global data communication. I won’t go into detail here. It is described in detail in the document. , please refer to https://zeroing.jd.com/docs.html#/zh-cn/data for details

Summarize

From the above introduction, we can know that the advantage of adopting a micro front-end architecture is that it can merge several applications that have been running for a long time and have no correlation into one application, or merge many small individual applications into a complete application, which can reduce the number of projects. The coupling between them improves project scalability. The micro-app draws on the idea of ​​​​WebComponent and uses CustomElement combined with a customized ShadowDom to encapsulate the micro front-end into a WebComponent-like component to achieve componentized rendering of the micro front-end. And due to the isolation characteristics of custom ShadowDom, there is no need to modify the webpack configuration. It is currently the lowest-cost solution for accessing micro-frontends on the market, so it is also favored by programmers.

Although micro-front-end is already a very mature field, and the purpose of using micro-front-end is to reduce costs and improve efficiency, in today's open source environment, it doesn't matter which framework we use, or we can implement micro-front-end ourselves. Personally, I think it should be Consider if the current project becomes more expensive to maintain after being connected to microservices, then you need to consider whether it is suitable for micro frontends. We cannot use them just for the sake of use. Micro frontends are not suitable for all scenarios. If you encounter problems, try to Consider multiple solutions.

Reference: micro-app official website: https://zeroing.jd.com/docs.html#/

Author: JD Retail Chen Yanchun

Source: JD Cloud Developer Community Please indicate the source when reprinting

Guess you like

Origin blog.csdn.net/jdcdev_/article/details/133128998