“This is the third day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.

In October, I took a new job. After participating in the one-month requirement iteration, I received the task of project reconstruction. Simply put, a solution idea needs to be presented in a short period of time, accompanied by local validation, and ultimately a technology replacement. So, buried oneself in hard work for a month, finally stem some result to come out, today make a simple summary of the thinking and practice at that time, be a review bar.

I. Current situation of old projects

The front-end technology stack used in the original project was mainly (jQuery1.8 + Layui-V2.5.4 + ExtJS4.2.1.883). When I got the project, IT was a little strange to write it. After all, I had been using VUE and React for several years. The way jquery is written is a bit strange, and the ExtJS4.2.1.883 (released in 2011) used is old, and Layui-v2.5.4 stopped updating in July 2021. For these two frameworks, one has a high learning curve, while the other may have no place to check for complex problems after stopping updating, so we still want to replace them as a whole.

Second, put forward ideas

Due to the current project, there are many sub-modules, and each module involves many functions. In the old project, all modules are separated into separate folders. When clicking on the menu, the url of the module is obtained, and then access based on iframe. The problem with this approach is that:

  • Each module uses a separate file. Common files cannot be shared. The more modules, the more files.
  • If the iframe mode is introduced, the browser context needs to be rebuilt and resources need to be reloaded each time, resulting in slow loading.
  • The module introduced by iframe is completely isolated from the parent window data, but this project is not a micro front-end project, and the data transfer steps after isolation are cumbersome.

Considering the introduction of iframe idea in the old project, there is already the shadow of micro front end, so I introduced the Qiankun micro front end solution in my idea.

2.1 Introduction to micro front-end technology

So what exactly is a micro front end? First of all, the concept of micro means small, small is relative to large. In other words, with the increase of project modules, functions and business complexity, a common application will gradually become a boulder application, and the boulder application will gradually encounter problems in maintenance cost and difficulty. If large applications are divided into small ones and developed according to small ones, it will be easier to manage people and control technology. The advantages of the micro front end can be viewed on the official website of Qiankun and will not be described here.

In addition to consider introducing micro front-end technology, I also created in the design of a public library, because the final micro application meet in the main application, as a whole to present to the user, it must ensure that the style of the public, in addition, there are some tools in each application methods, such as handling of data format, such as time, Therefore, a common library is also built.

2.2 Microapplication splitting

Having identified the idea of using a micro front end, one of the most important tasks is to split the micro application. In principle, it can be extracted according to common business functions or existing menu management. Since it is in the experimental stage and focuses on verifying the realization of micro front end, I directly extracted corresponding micro applications according to the existing menu.

2.3 Technical Architecture

In terms of system architecture, the master application can dynamically register micro-applications and access micro-applications through route management.

Microapplications need to meet the principles of separate development, separate deployment, separate testing, and at the same time can be connected to the main application and run at the same time. Independent development, need to have login, workbench, system management and other functions, connected to the main application, can directly access to the content display area.

The master application and micro-application can install common component libraries as required and can be deployed independently. The architecture diagram is classified, so I won’t show it here.

Third, concrete implementation

The technology stack used by main and micro applications (qiankun-2.6.3 + vueCli4.5.0 + vue-2.6.11 + element-ui-2.15.6). Micro applications can also be developed using other technologies, which is not limited by the technology stack. You can try plugging into other technology stacks later.

3.1 the main application

The main application uses vuE-CLI to create a project. For details about how to quickly create a VUE project using vue-CLI, see the official website of the Vue CLI. By default, vuE-Router and VUex are added to the application. Note that all the code shown in Section 3.1 is in the main application project, which is currently micro-front-main.

3.1.1 qiankun introduced

In the main application, execute Yarn Add Qiankun to install the Qiankun frame.

3.1.2 Route Configuration

In the SRC directory of the main application, create a micro folder, and create app and index.js files at the same time. In the app.js file, configure the sub-application to be added, and enable micro-services in index.

In the route configuration of micro-applications, follow the route configuration rules. Route configuration is designed based on the mode of the primary and sub-routes (history and hash) and whether the primary route loads micro-applications on a routing page.

  • In the first case, the main application route is in history mode, and the sub-application is also in History mode. The micro-application is not loaded in a routing page of the main application, that is, the micro-application is directly loaded in app.vue.

  • In the second case, the main application route is in (History/Hash) mode, and the micro application is in hash mode. The micro application is not loaded on a route page of the main application. This configuration is the same as that of both master and child routes in hash mode. Note that ‘#’ is required.

  • In the third case, the main application route is in history mode and the sub-application route is in History mode, and the micro application is loaded on a route page of the main application, such as home.vue page loading.

  • In the fourth case, the primary application route is in (History/Hash) mode, and the sub-application route is in hash mode. The micro-application is loaded on a route page of the primary application, for example, the home.vue page.

3.1.3 Route implementation

The main application and micro application in this paper are based on hash mode, and micro application is connected to the home page home.vue. Therefore, the fourth method described above is selected when configuring routes.

  1. Set the microapplication DOM node in the main application

Access from the home page, and the home page opens the DOM node of the master and micro-application. The micro-App must be consistent in the subsequent micro-application introduction configuration.

// pages/home.vue
<div class="content-wrapper"> <! -- Main application render, read the route of current main application --><router-view v-show="$route.name"></router-view><! -- Subapplication render, read the corresponding route in the subapplication --><div v-show=! "" $route.name" id="micro-app"></div>
</div>
Copy the code
  1. Configure the routing

Create the phones. js file under the SRC and configure the routes for the master and micro applications in the file. Name is used here to distinguish between master and micro applications. Echoes the V-show specified in the home.vue page above.

import Home from './pages/Home'
const routers = [
    {
        path: '/home'.name: 'Home'.component: Home,
        children: [{path: ' '.name: 'Dashboard'.component: Dashboard
            }
        ]
    },
    // All microapps are connected to the home page, but you can define them according to your own needs. You do not need to start from home
    {
        path: '/home/*'.component: Home
    }
]
export default routers
Copy the code
  1. Microapplication registration

The container property is the same as the mount DOM ID property defined on the page.

// micro/app.js, micro application route registration, note the path configuration under activeRule here
const apps = [
    {
        name: 'micro-fronted-query'.entry: MICRO_FRONTED_DATA_QUERY,
        container: '#micro-app'.activeRule: getActiveRule('#/home/micro-fronted-query'),}]export default apps
Copy the code
  1. Export start function
// micro/index.js 
import apps from './app'
// Register microapplications in the main application
registerMicroApps(apps)
addGlobalUncaughtErrorHandler((event) = > {
    console.error(event);
    const { message: msg } = event
    if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
        console.error("Microapplication failed to load. Please check whether the application is running."); }});// Export the start function
export default start
Copy the code
  1. Configuration menu

Generally, the menu is directly obtained from the interface, and the menu path is directly configured in the background management system. The menu configured here is equivalent to the event that is clicked in the menu bar of the home.vue page. Therefore, the path configured in the menu should be consistent with the micro-application route defined above.

For example, if the path of menu 1 is /home/micro-fronted-query, the path is the same as that defined during micro-application registration

// menu.vue
<el-menu-item v-for="(item, index) in newMenus"
            :key="index"
            :index="item.path"
            @click="addTab(item.name, index+1, item.path)">
        {{ item.name }}
</el-menu-item>
Copy the code
3.1.4 Page launch Qiankun

In the main application, if the micro application is not connected to the root app.vue, you need to call the startup function on the page that should be connected to the micro application. As in the app.vue page, the start() method is called in main.js. If connected in home.vue, the start() method is called in the home.vue page.

// page/home.vue
import qiankunStart from '.. /micro'
mounted() {
    if (!window.qiankunStarted) {
        window.qiankunStarted = true;
        / / start qiankunqiankunStart(); }},Copy the code

Now that the main functions of the main application access are complete, the work of micro-application access is started.

3.2 the application

Microapplications also use vuE-CLI framework to create, mainly to do the following work. The micro-application project is micro-fronted-Query.

3.2.1 Login Logic

Since microapplications need to ensure the ability to run, test, and deploy independently, the logon logic needs to be sorted out according to project requirements in specific development. In this test, the global navigation guard is first used to determine whether the token exists. If so, the route can be read directly. If not, the login page of the micro-application is entered. At the same time, in order to prevent cookies from being expired, the system determines whether the token is valid in the interceptor of the interface request. If the token is invalid, the system directly enters the login page of the micro-application.

3.2.2 Creating a Microservice Profile

In the SRC directory of the child application, create the micro-service configuration file public-path.js

// src/public-path.js
if (window.__POWERED_BY_QIANKUN__) {
    // Dynamically set webpack publicPath to prevent resource loading errors
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
Copy the code
3.2.3 Whether to microservice

In main.js, the rendering logic is processed according to whether micro-services are enabled or not. In order to avoid conflicts between the root ID #app and other DOM, the search scope needs to be limited, and the bootstrap/mount/unmount life cycle functions need to be exposed.

// Micro application main.js
// The render function for the microapplication
function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    // Set the path between the microservice and the standalone runtime
    routes : sysRouters.concat(routerConfigs)
  })
  
  vueInstance = new Vue({
    render: h= > h(App),
    router
  }).$mount(container ? container.querySelector('#app') : '#app')}// When run independently, read the current configuration directly
if(! isQiankun) { render() }/** * expose the bootstrap */
export async function bootstrap() {
  console.log("VueMicroApp bootstraped");
}
/** * expose mount */
export async function mount(props) {
  console.log("VueMicroApp mount", props);
  render(props);
}
/** * exposes unmount */
export async function unmount() {
  console.log("VueMicroApp unmount");
  vueInstance.$destroy();
  vueInstance = null;
  router = null;
}
Copy the code
3.2.4 Modifying the Packaging Configuration File

Create a vue.config.js file in the root of the microapplication and configure the configuration properties that the Qiankun needs to use. Note that the library under the configureWebpack property needs to have the same name as when the microapplication was registered, so you can get the name value directly from package.json for error purposes. If there is a cross-domain problem, you also need to configure header cross-domain information in devServer, you can check the vue.config.js configuration details.

module.exports = {
    configureWebpack: {
        output: {
            library: `${packageName}`.libraryTarget: 'umd'.// Package microapplications into umD library format
            jsonpFunction: `webpackJsonp_${packageName}`,,}}}Copy the code
3.2.5 Route Configuration

In the route configuration file of the micro-application, you need to add the route root path corresponding to the route configuration in the primary application, and distinguish whether the route is micro-service. In the micro-service case, you need to add the route prefix, but do not need to add the route prefix for non-micro-service.

// Add the prefix prefix depending on whether it is a micro application
const prefix = window.__POWERED_BY_QIANKUN__ ? '/home/micro-fronted-query' : ' '
const appRouters = [
    {
        path: `${prefix}/list`.component: () = > import('./views/list.vue')}]export default appRouters
Copy the code

3.3 public library

In addition to the processing of master and micro-application logic, a public library is created in this scheme. The public library can guarantee the compatibility of master micro-application style and reuse common components and methods at the same time. The common library is also developed based on VUE, although you can choose any technology to develop the common library here. The common library application name is system-common.

The public library is mainly used to extract the common content between various applications, including system public routing configuration, business-related pages such as login, permissions, user protocol components, API interfaces for judging login methods, cookie setting and tool methods for obtaining, etc. Technically, we use the VUE framework to develop common libraries and provide plug-in exposure for other applications. How VUE develops plug-ins will be updated in a future article.

A public library can be installed in a local project using NPM to send private packages or yarn Add file:/.

3.3.1 Common library plug-in development

In SRC /index.js, we mainly expose plug-in methods. For example, we create a common component in the Components folder and register the component in components/index.js using Vue.component(). At the same time, install the registered component in index.js. This way we can use the vue.use () method to use components in other applications, as long as the common library is installed.

/ / SRC/index. Js file
const install = function(Vue) {
    if (install.installed) return;
    install.installed = true;
    // Iterate over registered components
    components.map((component) = > Vue.use(component));
}

if (typeof window! = ="undefined" && window.Vue) {
    install(window.Vue);
}

export default{ install, ... components,// Share components
    cookies,   / / the cookies
    sysRouters,  // Generic routing
    judgeApi // Generic API methods
};
Copy the code

3.4 Project Deployment

3.4.1 Application Packaging

Microapplications are developed based on VUE and packaged exactly as vUE provides.

Env. * file, such as. Env.development. js file, represents the packaging configuration in the development environment. In this configuration, you can configure the interface access address, packaging path, node execution environment, etc. At the same time, modify the script command in package.json to add –mode mode to the command. This allows you to package different environments for different configurations.

In addition to common packaging, dynamic microapplication configuration has been added. In the. Env file, add the micro-application address configuration for the access of the master application and dynamically obtain it in the method of registering micro-applications. In this way, you can only modify the content in the configuration file to complete the registration of micro-applications.


3.4.2 nginx deployment

Project deployment, in the local testing, mainly using Nginx for static resource redirection. After packaging each application and configuring it under the same domain name of Nginx, cookie data sharing can be realized. For details about nginx deployment, see the Nginx Official website

Four, effect drawing

This paper introduces in detail the practical steps of introducing Qiankun into the project, and you can choose the appropriate micro front end scheme according to the needs of the project. If you like this article, please feel free to join us.