Remember the practice of qiankun project of micro front end!!! Pit Guide

Source: zxh1307

https://juejin.im/post/5ea55417e51d4546e347fda9

Introduction

Recently, I stepped on a lot of holes in the process of working on the micro front-end project. I kept trying and making mistakes in the limited data. I was silent for two lines of tears. Ha ha This time, the mining pit will be recorded so that more people can avoid detours. This project uses ant financial qiankun as the basis for development Don't talk too much!!!

So what is qiankun?

qiankun is a micro front-end implementation library based on single spa, which aims to help you build a production usable micro front-end architecture system more simply and painlessly.

What is a micro front end

The micro front-end architecture has the following core values:

  • Technology stack independent

    The main framework does not restrict access to the technology stack of applications, and micro applications have full autonomy

  • Independent development and deployment

    The micro application warehouse is independent, and the front and rear ends can be developed independently. After the deployment, the main framework automatically completes the synchronous update

  • Incremental upgrade

    In the face of various complex scenarios, it is usually difficult for us to upgrade or restructure an existing system. The micro front end is a very good means and strategy for implementing progressive reconfiguration

  • Stand alone runtime

    The state of each micro application is isolated, and the runtime state is not shared

From official documents of qiankun

Main application configuration

The main application and sub application of this project are vue,

Download ABCD

npm install qiankun     

Register micro application in main application

//Import Qiankun function
import {
  registerMicroApps,
  setDefaultMountApp,
  start
} from "qiankun";

Encapsulate render method

This method is in main JS needs an initial call, which is mainly used to mount the main application, and then the sub applications are called in turn, so it is a judgment The parameters passed in are the HTML of the sub application and the content field of the loading status. We use vuex to store them for easy use

let app = null;

function render({ appContent, loading }) {
  if (!app) {
    app = new Vue({
      router,
      store,
      render: h => h(App),
    }).$mount('#app');
    
  } else {
    store.commit('microApp/changeCenter', appContent);
    store.commit('microApp/changeLoading', loading);
  }

}

Micro app registration

The apps in the following paragraphs can be used to register micro applications after obtaining data. The case in this article is relatively simple and easy for everyone to understand,

There are many self applied parameters container and render, which will be explained in the following section

function genActiveRule(routerPrefix) {
  return location => location.pathname.startsWith(routerPrefix);
}

//Data passed to sub application
let msg = {
![](https://user-gold-cdn.xitu.io/2020/4/27/171bbc5de042ec98?w=1811&h=959&f=gif&s=4951066)
  data:'Cultivate the bitterness of love,Learn to let go of your old desires'
}

let apps = [
  {
    name: 'linjunjie', 
    entry: '//localhost:215', / / change to the port number of your child application
    container:'#subView', / / node id / / sandbox mode
    //render:render, / / normal mode
    activeRule: genActiveRule('/star'),
    props:msg
  }
]
   //The registered sub application parameters are arrays
registerMicroApps(apps,{
  beforeLoad: [
    app => {
      console.log(app)
      console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
    },
  ],
  beforeMount: [
    app => {
      console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
    },
  ],
  afterUnmount: [
    app => {
      console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
    },
  ],
});


setDefaultMountApp('/star/linjunjie')

//Turn on sandbox mode
start({ 
   sandbox :{strictStyleIsolation: true}
})

After the micro application information is registered, once the url of the browser changes, the matching logic of qiankun will be automatically triggered. All micro applications on the activeRule rule matching will be inserted into the specified container, and the exposed life cycle hooks of the micro application will be called in turn.

Presentation elements prepared by main application for sub application

<template>
  <div id="app">
    <div id="nav">
      <!--//Jump dom-->
      <div @click="onChangePage('/star/linjunjie')" >Linjunjie</div>
      <div @click="onChangePage('/star/zhangyixin')" >Zhang Yixing</div>
   
    </div>
<!--//Content area for developing sub applications -- >
     <div id="subView" class="sub-content-wrap" v-html="content"></div>
  </div>
</template>

<script>

  import { mapState } from 'vuex';
  export default{
    data(){
      return {
     
      }
    },
    computed:{
    //Get sub app HTML data
       ...mapState('microApp', ['content']),
       ...mapState('microApp', ['mircoAppLoading']),
    },

    methods:{
    
      //Define jump method
      onChangePage(url){
        console.log(url)
        
        this.routerGo(url, 'My favorite male star')
      },
  
      routerGo(href = '/', title = null, stateObj = {}) {
        window.history.pushState(stateObj, title, href); 
      },
    }
 }
</script>

Subapplication configuration

The configuration of subapplications is relatively simple. You don't need to download additional qiankun. You can export the life hook

Export response life hook

Export the bootstrap, mount and unmount life cycle hooks for the main application to call at an appropriate time. Note that when instantiating a route, it is judged that when running in the qiankun environment, the route should be prefixed. The prefix is consistent with the parameters in the main application registration sub application function genactivrule ("/subdemo")

The 'star' value should correspond to the value of the main application. The value in genactivrule ("/star") should be agreed that both the main application and the micro application should be used

If new VueRouter is not in main JS, please move this configuration to main JS for easy management

import routes from './router' //Export routing information for easy use

let router = null;
let instance = null;

function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/star' : '/',  
    mode: 'history',
    routes,
  });

  instance = new Vue({
    router,
    store,
    render: h => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}

if (!window.__POWERED_BY_QIANKUN__) {
  render();
}else{
 __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}


export async function bootstrap() {
  console.log('[vue] vue app bootstraped');
}

export async function mount(props) {
 //props contains the parameters passed by the main application as well as the node information created for the sub application
  console.log(props)
  render(props);
}

export async function unmount() {
  instance.$destroy();
  instance = null;
  router = null;
}

Configuring packaging tools for micro applications

In addition to the corresponding life cycle hooks exposed in the code, in order for the main application to correctly identify some information exposed by the micro application, the packaging tool of the micro application needs to be in vue Config The following configurations are added to JS:

const packageName = require('./package.json').name;

module.exports = {
  output: {
    library: `${packageName}-[name]`,
    libraryTarget: 'umd',
    jsonpFunction: `webpackJsonp_${packageName}`,
  },
};

Sub application judgment

Create a publicpath JS in main JS import

if (window.__POWERED_BY_QIANKUN__) { 
//Processing resources
 __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; 
}

Handling resource loading issues

Configure vue Config JS

module.exports = {
  publicPath:`//localhost:${port}`,
}

Vue Config JS complete configuration

const path = require('path');
const packageName = require('./package').name;

function resolve(dir) {
  return path.join(__dirname, dir);
}

const port = 7101; // dev port
module.exports = {

  publicPath:`//localhost:${port}`,
  outputDir: 'dist',
  assetsDir: 'static',
  filenameHashing: true,
 
  devServer: {
    // host: '0.0.0.0',
    hot: true,
    historyApiFallback: true,//Add focus
    port,
    overlay: {
      warnings: false,
      errors: true,
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },

  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    output: {
      library: `${packageName}-[name]`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${packageName}`,
    },
  },
};

Pit records

When the current page is a sub application, refresh the page 404

The following methods are configured for the main application

  • Method 1: delete the mode configuration item

mode: 'history', //Delete this configuration code
  • Method 2 configuration 404 page

If mode:'history'is not commented out, this parameter redirects the 404 page to the home page

{
    path: '*',
    name: 'indexNotFound',
    component: resolve => require(['@/components/home'], resolve),
    children: HomeChild,
},
Problems encountered by subapplication style isolation start sandbox mode

Main application configuration sandbox: {strictstyleisolation: true} the rendering mode is changed from render mode to container container:'\subview', and the mounting dom of the sub application is <div id= "subview" > </div> remember the main container: \id+id

The main code interception mentioned above for sub application configuration

instance = new Vue({
router,
store,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app'); / / key points

Problem encountered: enable sandbox mode. If render mode is adopted, an error will be reported. Select container mode

Renderings

At this point, the project has been built. Let's see the effect

Here is the complete code for everyone to learn https://github.com/zxh1307/qiankun-vue

Project issues

Why can't I see the effect of sub application after the project is started

Apply master to main The port number of the sub application registered in JS can be changed to the port number of its own project

epilogue

There are other holes in the development that have been forgotten. Remember that the cross domain problem of sub application resources in the project deployment requires Nginx to configure the cross domain problem

A pupil in the front end!!!

last

Welcome to join the front-end communication group by following the "front-end bottle king" and replying to "communication"!

Welcome to "front end bottle king" and reply that "algorithm" will be automatically added to build a complete data structure and algorithm system from 0 to 1!

Here, Ping Ping Jun not only introduces the algorithm, but also combines the algorithm with various front-end fields, including browser, HTTP, V8, React, Vue source code, etc.

Here (arithmetic group), you can learn a big algorithm programming problem (ALI, Tencent, Baidu, byte, etc.) or leetcode every day, and aquariujun will solve it the next day!

In addition, there are handwritten source code questions every week, and you can also answer them!

>>The interviewer is also looking at the algorithm information<<

"Watching and forwarding" is the biggest support

Tags: html Java Python Vue xhtml

Posted by tsfountain on Mon, 30 May 2022 00:49:16 +0530