preface

Qiankun micro-service aggregates systems with different technology stacks (React,Vue,Angular,jQuery) into one system, and each system can be independently deployed and run, which is suitable for large teams and large front-end projects.

Functions:

  • Introducing multiple tech stacks (React + Vue)
  • Background management system (Ant Design Pro) multi-tab page in Qiankun environment caching practice
  • Dependency Sharing – Sharing of common packages like React, React – DOM, Moment, AnTD, etc
  • Resource sharing – common tools util, components, and configurations are synchronized across multiple projects

Online preview based on Qiankun microservice:

Click on Preview

Get the project source code

The project architecture

project Technology stack port Access to the address
Main project (the main – the react) Ant Design Pro 5000 http://qiankun.fancystore.cn
Component (1) app1 – react to Ant Design Pro 5001 http://app1.fancystore.cn
Component 2 (app2 – react) Ant Design Pro 5002 http://app2.fancystore.cn
Subproject 3 (app3 – vue) Vue Element Template 5003 http://app3.fancystore.cn
Common Resource Library (Qiankun-Common) TypeScript https://github.com/czero1995/…

Project reform

1. Main application (base)

1.1 installation qiankun

   npm install @umi/qiankun --save   
   or
   yarn add @umi/qiankun --save    

1.2 Registered child applications

// Add qiankun: {master: {apps: [{name:'app1', entry: process.env.NODE_ENV === 'production' ? '//app1.fancystore.cn' : '//localhost:5001', }, { name:'app2', entry: process.env.NODE_ENV === 'production' ? '//app2.fancystore.cn:' : '//localhost:5002', }, { name:'app3', entry: process.env.NODE_ENV === 'production' ? '//app3.fancystore.cn:' : '//localhost:5003', }, ], sandbox: // sandbox prefetch enabled: true, // prefetch enabled}}

1.3 Modify the root node

    // src/pages/document.ejs
    id=root-master

1.4 Create a new child application load layout MicroAppLayout

// src/layouts/MicroAppLayout import BasicLayout from '@ant-design/pro-layout'; import { KeepAlive, Provider } from 'react-keep-alive'; import { MicroAppWithMemoHistory } from 'umi'; import allRoutes from '.. /.. /config/routes'; function MicroAppLayout(props) { let targetMicro = '' const transRoutes = (routes, pathname) => { routes.map(item => { if (item.routes) { return transRoutes(item.routes, pathname) } if (item.path === pathname) { targetMicro = item.microName } }) return targetMicro } return <Provider> <KeepAlive name={props.location.pathname}> { targetMicro ? <MicroAppWithMemoHistory name={transRoutes(allRoutes[0].routes, props.location.pathname)} url={props.location.pathname} /> : <BasicLayout></BasicLayout> } </KeepAlive> </Provider> } export default MicroAppLayout;

1.5 Create a new app.ts in SRC directory. If it is a child application, it needs to be loaded with MicroApplayout

    // src/app.ts
    import LoadingComponent from '@/components/PageLoading';
    import { dynamic } from 'umi';
    const transRoutes = (routes) => {
      routes.forEach(item => {
        if(item.routes){
          return transRoutes(item.routes)
        }
        if(item.microName){
          item.component = dynamic({
            loader: (a) => import(/* webpackChunkName: 'layouts__MicroAppLayout' */ '@/layouts/MicroAppLayout'),
            loading: LoadingComponent,
          })
        }
      })
    }

    export function patchRoutes({ routes }) {
      transRoutes(routes[0].routes)
    }

### 2. Application of React(Ant Desin Pro)

#### 2.1 Install Qiankun


    npm install @umi/qiankun --save   
    or
    yarn add @umi/qiankun --save
   

#### 2.2 Subproject registered with QIANKUN and added in config/config.ts


    qiankun: {
        slave: {}
    }

#### 2.3 Change the root node SRC /pages/document.ejs

    
    id=root-slave

#### 2.4 Create a new app.ts in SRC directory and export the corresponding lifecycle hooks. The subproject needs to separate the Qiankun environment from the current environment. If it is Qiankun environment, use a blank template (SRC /layouts/ blankLayout). Use the default template (SRC /layouts/BasicLayout) so that it can be embedded into the Qiankun environment and can be developed and deployed independently

Const isQiankun = window.__powered_by_qiankun__ export const Qiankun = {// Async bootstrap(props) { console.log('app1 bootstrap', props); }, // trigger async mount(props) before applying render {console.log('app1 mount', props); }, // trigger async unmount(props) after the application is unmounted {console.log('app1 unmount', props); }}; export async function patchRoutes({routes}) { if(isQiankun){ routes[0]['component'] = require('@/layouts/BlankLayout').default } }

3. Child application Vue(vue-element-template)

3.1 Add to ConfigureWebpack under Vue.config.js

Library: '${name}-[name] ', libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${name}`, }

3.2 Add devServer under vue.config.js:

headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Headers": "*"}

3.3 Expose the life cycle of Qiankun in main.js:

    let install = null;
    function render(props) {
      install = new Vue({
        router,
        store,
        render: h => h(App)
      }).$mount('#app3')
    }
    if (window.__POWERED_BY_QIANKUN__) {
      __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    } else {
      render();
    }
    export async function bootstrap(props) {
    }
    export async function mount(props) {
      render(props);
    }
    export async function unmount(props) {
      install.$destroy();
      install = null
    }

Project summary

  1. There are two ways for the main application to load the child application using the route binding and the
    component. If you want to support Ant Design Pro multi-tab, you need to use
    because the dynamic display inserts the Tab. Binding a dead-end will cause Qiankun to fail to load the corresponding page.
  2. Ant Design Pro TAB, click the tabs to show different application page will lead to be destroyed, content data is initialized and lost, in the SRC/layouts/MicroAppLayout under:

    MicroAppWithMemoHistory is required to introduce the React-Keep-Alive package host application. MicroApp has no effect.
  3. Page jump 404 in Qiankun environment

    In QIAKUN environment, all route changes will trigger QIAKUN route listening. You need to make a decision about the environment: Export const qiankunJump = (url:string,name=' page name ',params = null) = bb0 {window.__powered_by_qiankun__? history.pushState(params,name,url): umiHistory.push(url) } qiankunJump('/xxx')
  4. The QIANKUN external will report Cannot read property ‘createContext’ of undefind

    Externals: {' act': 'window.react ',' act-dom': exteranls Externals: {' act': 'window.react ',' act-dom': exteranls Externals: {' act': 'window.react ',' act-dom': exteranls 'window.ReactDOM', } => externals: { react: 'React', 'react-dom': 'ReactDOM', }

Project optimization

1. Dependency sharing

If the host application uses the same library or package (React, React -DOM, Moment, etc.), you can use the externals way to introduce, reduce the load of duplicate packages resulting in resource waste. Qiankun will be the child's external link script tag content request, will record in a global variable. The next time he uses it, he'll take it from the global variable first. This allows for reuse of content, Just make sure both the Url of the link simply const fetchScript = scriptUrl = > scriptCache [scriptUrl] | | (scriptCache [scriptUrl] = fetch(scriptUrl).then(response => response.text())); So as long as the child project has configured the Webpack Externals, these common dependencies are on the same server, you can implement the child project's common dependencies import on demand, after the use of one project, another project will not repeat the load, can directly reuse this file.

2. Resource sharing

Resolving the problem of resource sharing can improve the maintainability of the project, which would otherwise be difficult to maintain components or tools that are shared by multiple systems. 1. It is commonly used to publish as an NPM package, and each project installs the update package. Local debugging can be done using NPM link. But repeatedly updating the package is also cumbersome. 2. There is another way to use the Git library to introduce "qiankun-common" in the package.json dependency: "Git+https://[email protected]: czero1995 / qiankun - common. Git" using the import {commonUtil} from 'qiankun - common; util.qiankunJump('/xxx')

### Project start

1. Enter main-react NPM install NPM run start 2. Enter app1-react NPM install NPM run start 3. Enter app2-react NPM install NPM run start 4. Go to app3-react NPM install NPM run dev

### project deployment

  1. The child application Nginx needs to be equipped with cross-domain request headers:

      add_header Access-Control-Allow-Origin *;
      add_header Access-Control-Allow-Credentials true;
      add_header Cache-Control no-cache;
  2. Nginx enables gzip compression:

     
      gzip  on;
      gzip_min_length 200;
      gzip_buffers 4 16k;
      gzip_comp_level 9;
      gzip_vary on;
      gzip_disable "MSIE [1-6]\.";
      gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;