qiankun实战从0到1

3,371 阅读2分钟

本文章主要讲述如何接入qiankun微前端。

父类:采用vue。

子类:采用vue以及react的方式接入。

其次:vue是通过 vue cli进行创建, react是通过create-react-app来进行项目创建。

在创建完父类项目以及子类项目之后,我们需要进行进行qiankun项目的安装。

npm install qiankun --save

在安装完成之后,我们需要对其做相应的处理。分类三部分:

  1. 在父类中创建微前端基座

    首先在src下创建一个子应用的配置文件,我们叫做micro_app.js

    // src/micro_app.jsconst microApps = [
        {
          name: 'micro_vue',
          entry: '//localhost:8081/',
          activeRule: '/micro_vue',
          container: '#subapp-viewport', // 子应用挂载的div
          props: {
            routerBase: '/micro_vue' // 下发路由给子应用,子应用根据该值去定义qiankun环境下的路由
          }
        },
        {
          name: 'micro_react',
          entry: '//localhost:10100/',
          activeRule: '/micro_react',
          container: '#subapp-viewport', // 子应用挂载的div
          props: {
            routerBase: '/micro_react'
          }
        }
      ]
      
      export default microApps
    ​
    

    在设置完子应用的配置文件之后,我们需要改写App.vue

    // 为了简单期间,只是改写了模板文件,
    <template>
      <div id="layout-wrapper">
        <div class="layout-header">头部导航</div>
        <div id="subapp-viewport"></div>
      </div>
    </template>
    

    接下来是更改main.js。在main.js中最主要做的事情就是将之前配置的子应用进行注册并且启动qiankun框架服务

    import Vue from 'vue';
    import App from './App.vue';
    import { registerMicroApps, start } from 'qiankun';
    import microApps from './micro-app';
    ​
    Vue.config.productionTip = false;
    ​
    window.projectName = 'main'; // 为了测试沙盒环境new Vue({
      render: h => h(App),
    }).$mount('#app');
    ​
    // 注册子应用
    registerMicroApps(microApps, {
      beforeLoad: app => {
        console.log('before load app.name====>>>>>', app.name)
      },
      beforeMount: [
        app => {
          console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
        },
      ],
      afterMount: [
        app => {
          console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name);
        }
      ],
      afterUnmount: [
        app => {
          console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
        },
      ],
    });
    // 启动qiankun
    start();
    ​
    

    讲完父类的基座创建完成之后,接下来就是子应用的注册了。

    1. vue接入qiankun

      首先需要在项目根目录下简历vue.config.js用来改写webpack的相应配置。在src下创建public-path.js。public-path用来改写webpack打包好之后,通过那个路径可以访问到打包后的文件。

      // vue.config.js
      const { name } = require('../package.json')
      ​
      module.exports = {
        configureWebpack: {
          output: {
            library: `${name}-[name]`,
            libraryTarget: 'umd',
            jsonpFunction: `webpackJsonp_${name}`,
          }
        },
        devServer: {
          port: 8081, // 在.env中VUE_APP_PORT=7788,与父应用的配置一致
          headers: {
            'Access-Control-Allow-Origin': '*' // 主应用获取子应用时跨域响应头
          }
        }
      }
      ​
      // public-path.js
      (function() {
        // 用来判断是否运行在乾坤的框架下
          if (window.__POWERED_BY_QIANKUN__) {
            // eslint-disable-next-line no-undef
            __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
          }
        })();
      

      修改router下的Index,我们只需要导出对应的路径定义即可,不需要导出对应的vue-router实例,如果直接导出vue-router实例的话,会与我们在父类micro_app.js中设置的routerBase匹配不上。导致渲染子应用失败。

      import Home from '../views/Home.vue'
      const routes = [
        {
          path: '/',
          name: 'Home',
          component: Home
        },
        {
          path: '/about',
          name: 'About',
          component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
        }
      ]
      export default routes;
      ​
      

      接下来就是需要改写main.js。我们既然要用乾坤,那就要提供qiankun的相应的生命周期。并且注册vue-vouter实例。

      import './public-path' // 注意需要引入public-path
      import Vue from 'vue'
      import App from './App.vue'
      import routes from './router'
      import store from './store'
      import VueRouter from 'vue-router'
      Vue.use(VueRouter)
      Vue.config.productionTip = false
      let instance = null
      window.projectName = 'micro_vue';
      function render (props = {}) {
        // 这个是我们在父类注册的时候定义的那些参数。
        const { container, routerBase } = props
        const router = new VueRouter({
          base: window.__POWERED_BY_QIANKUN__ ? routerBase : process.env.BASE_URL,
          mode: 'history',
          routes
        })
        instance = new Vue({
          router,
          store,
          render: (h) => h(App)
        }).$mount(container ? container.querySelector('#app') : '#app')
      }
      ​
      if (!window.__POWERED_BY_QIANKUN__) {
        render()
      }
      ​
      export async function bootstrap () {
        console.log('[vue] vue app bootstraped')
      }
      ​
      export async function mount (props) {
        console.log('[vue] props from main framework', props)
      ​
        render(props)
      }
      ​
      export async function unmount () {
        instance.$destroy()
        instance.$el.innerHTML = ''
        instance = null
      }
      ​
      

      最后需要在根目录下创建.env文件。

      VUE_APP_PORT=8081
      

      以上步骤完成之后,我们只需要启动项目我们既可以通过对应的路由进行访问了http://localhost:xxxx/micro_vue

      image-20210925151551862

      1. react项目的接入

        创建public-path.js文件

        if (window.__POWERED_BY_QIANKUN__) {
           // eslint-disable-next-line no-undef
           __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
          }
        

        修改 webpack 配置

        安装插件 @rescripts/cli,当然也可以选择其他的插件,例如 react-app-rewired

        npm i -D @rescripts/cli
        

        根目录新增 .rescriptsrc.js

        
        
        const { name } = require('./package');
        
        module.exports = {
          webpack: (config) => {
            config.output.library = `${name}-[name]`;
            config.output.libraryTarget = 'umd';
            config.output.jsonpFunction = `webpackJsonp_${name}`;
            config.output.globalObject = 'window';
        
            return config;
          },
        
          devServer: (_) => {
            const config = _;
        
            config.headers = {
              'Access-Control-Allow-Origin': '*',
            };
            config.historyApiFallback = true;
            config.hot = false;
            config.watchContentBase = false;
            config.liveReload = false;
        
            return config;
          },
        };
        

        修改 package.json

        -   "start": "react-scripts start",
        +   "start": "rescripts start",
        -   "build": "react-scripts build",
        +   "build": "rescripts build",
        -   "test": "react-scripts test",
        +   "test": "rescripts test",
        -   "eject": "react-scripts eject"
        

        最后,同理在根目录下创建一个.env文件,

        PORT=10100
        BROWSER=none
        

        然后启动react 项目,之后就可以通过http://localhost:xxx/micro_react进行访问了

        image-20210925150249912

  2. \