As we learned in the previous documentation, the current micro front end uses composite application routing distribution. The parent class detects routes and dynamically unloads or mounts child applications.

Before we understand how it works, let’s take a look at how single-SPA works. Let’s take vUE for example.

First we define two child projects and a parent base.

  1. Introduce single-SPA-vue in the subclass project

    npm install single-spa-vue --save
    Copy the code
  1. In a subclassmain.jsaddsingle-spa-vueCorresponding life cycle
import Vue from 'vue' import App from './App.vue' import router from './router' import singleSpaVue from 'single-spa-vue' Vue.config.productionTip = false const appOptions = { el: '#microApp', router, render: H => h(App)} // Support independent application running, deployment, independent of the base application if (! Process.env.ismicro) {delete appoptions.el new Vue(appOptions).$mount('#app')} Const vueLifecycle = singleSpaVue({Vue, Export function bootstrap (props) {console.log('app2 bootstrap') return Vuelifecycle. bootstrap(() => {})} // Mount lifecycle Export function mount (props) {console.log('app2 mount') return Vuelifecycle. mount(() => {})} // Unmount lifecycle Export function unmount (props) {console.log('app2 unmount') return vueLifecycle.unmount(() => {}) }Copy the code
  1. Create the vue.config.js file and set the export format to UMD

    Const package = require('./package.json') module.exports = {// tells child applications to load static resources at this address, or else to load publicPath under the domain name of the base application: '//localhost:8082', // devServer: {port: 8082}, configureWebpack: {// Export the package in UMD format and mount the property package.name on the global object from which the base application needs to get some information, such as the life cycle function output: {// The value of library needs a unique library among all the child applications: package.name, libraryTarget: 'umd' } }Copy the code

    After the above steps, a micro front end of the subproject is basically created.

    Let’s move on to creating the parent base.

    1. The parent base introduces single-SPA

      npm install single-spa --save
      Copy the code
    1. Modify the parent class main.js

      import Vue from 'vue' import App from './App.vue' import router from './router' import { registerApplication, Start} from 'single-spa' vue.config. productionTip = false function createScript(url) {return new Promise((resolve, reject) => { const script = document.createElement('script') script.src = url script.onload = resolve script.onerror = reject const firstScript = document.getElementsByTagName('script')[0] firstScript.parentNode.insertBefore(script, FirstScript)})} Return a Promise function loadApp(url, GlobalVar) {// Support remote loading of child applications return async () => {// await createScript(URL + '/js/chunk-vendors. Js ') await CreateScript (URL + '/js/app.js') // return is important here, Return window[globalVar]}} // List of child apps const apps = [{// name of child apps: 'app1', // The subapplication loading function, is a Promise app: loadApp('http://localhost:8083', 'app1'), // When the route meets the condition (return true), activate (mount) the subapplication activeWhen: Location = > location. The pathname. StartsWith ('/app1), / / is passed to the child application object customProps: {}}, {name: 'app2, app: loadApp('http://localhost:8082', 'app2'), activeWhen: location => location.pathname.startsWith('/app2'), customProps: {}}] for (let I = apps.length-1; i >= 0; I --) {registerApplication(apps[I])} new Vue({router, mounted() {// start()}, render: h => h(App) }).$mount('#app')Copy the code

      After the above modification is complete, a superbase application is created.

      So let’s compare main.js with the modified version

    By comparison, we can see that we have added a total of these methods or properties to the superclass base. Respectively is:

    LoadApp createScript, apps. From the concrete implementation, we can see:

    1. LoadApp basically requests resources based on their addresses
    2. CreateScript basically adds requested scripts to the page.
    3. Apps is a description of some subclass of applications.
    4. RegisterApplication is to register these child applications tosingle-spaIn the.

    After comparing the parent base, let’s compare the child base.

    As we can see, the biggest difference in subclasses is the addition of some single-SPa-vue lifecycle. Because the micro front end solution is single-SPA, you have to import these life cycles to use it.

    So when we look at the comparison, when we look at a picture, we can suddenly see how the micro front end works.

From the figure, we can see that when the browser opens the parent application for the first time, the first step is to register the app by calling registerApplication, and then determine which subapplication the current route belongs to based on the activeWhen in apps. The son will replace the current application status, divided into appToLoad, appToUnmounted, appToMounted. Then, according to the state of the subapplication, the subapplication that needs to be uninstalled will be executed first. After uninstallation, the subapplication whose state is appToLoad and appToMounted will be executed. Then, the corresponding callback function will be executed at the end, that is, the life cycle registered in the subapplication.

So why do we need Qiankun when we have single-SPA as a micro front-end solution?

Qiankun was developed from 0-1K

Compared to single-SPA, Qiankun solved the JS sandbox environment without us having to deal with it ourselves. During the development of Single-SPA, we had to manually write the method to call the child application JS (as shown in the createScript method), but Qiankun didn’t need it. Qiankun just needed the configuration of the app that you passed in the response to help us load it. There is another difference in their nature

So before we get to the essential difference, we need to know that combinatorial application routing distribution also has two solutions, one is JS entry, the other is HTML entry

JS Entry usually means that sub-applications type resources into an Entry script. However, this scheme has many limitations, such as requiring all resources of sub-applications to be packaged into a JS bundle, including CSS, images and other resources. In addition to the potential size of the printed package, features such as parallel loading of resources are not available.

HTML Entry is more flexible, directly typing out HTML as the Entry of the sub-application. The main frame can fetch THE static resources of the sub-application by THE way of HTML, and at the same time, the HTML document is stuffed into the container of the main frame as a child node. In this way, not only can the access cost of the main application be greatly reduced, but the development mode and packaging mode of the sub-application basically do not need to be adjusted, and it can naturally solve the problem of style isolation between the sub-applications (mentioned later).

So that’s the difference between them. The Qiankun is based on single-SPA, which has been modified to make access more convenient.