美文网首页
qiankun 实战(一)

qiankun 实战(一)

作者: 草帽lufei | 来源:发表于2022-04-24 11:13 被阅读0次

    前言

    前两天用了一下微前端框架 icestark, 在实际架构搭建过程中发现中发现在 Vue 主应用子应用之间切换 tag (tag 分别主应用和子应用的页面)页签时会有子应用数据状态无法保存的情况,搜索了一波解决方案后发现,icestarkReact 应用实现了对数据状态的缓存,Vue 里面没有这个实现。

    React 实现的思路是通过 Tabs 组件结合 icestark 实现的一种机制,但是没有用到路由。由于架构时间有限,发现按照那个方案调整是实现方面时间代价有点大,尝试了一下 qiankun 发现框架中可以不存在这个问题,所以决定更换微前端框架方案为 qianun

    如果想了解 icestark 可以看如下文章, 里面有一些关于微前端架构理念的思考

    快速上手微前端框架 icestark (一)

    快速上手微前端框架 icestark (二)

    主应用接入 qiankun

    本地使用 vue-cli 创建了一个 Vue2.0 纯净项目作为主应用,执行 yarn add qiankun 命名安装 qiankun,在 main.js 中引入 qiankun, 注册并启动

    import Vue from 'vue'
    import App from './App.vue'
    import VueRouter from 'vue-router'
    
    // --- 引入qiankun ---
    import { registerMicroApps, start } from 'qiankun'
    
    registerMicroApps([
      {
        name: 'vueApp',
        entry: '//localhost:8081',
        container: '#container',
        activeRule: '/app-vue'
      }
    ])
    
    start();
    // --- end ---
    
    Vue.config.productionTip = false
    
    Vue.use(VueRouter)
    
    const router = new VueRouter({
      mode: 'hash',
      base: '/',
      routes: [
        {
          path: '/',
          name: 'home',
          component: () => import('./views/Home.vue')
        },
        {
          path: '/home',
          name: 'home',
          component: () => import('./views/Home.vue')
        },
        {
          path: '/hello',
          name: 'hello',
          component: () => import('./components/HelloWorld.vue')
        }
      ]
    })
    
    new Vue({
      router,
      render: h => h(App),
    }).$mount('#app')
    
    vue-router 安装时遇到一个小异常

    安装 vue-router 时遇到一个版本兼容问题,通过 npm install vue-router --save 命令安装会提示版本不兼容,如下效果

    图片.png

    提示版本不兼容,如果通过控制台提示执行 npm install vue-router --save --forcenpm install vue-router --save --legacy-peer-deps 可以安装 vue-router,但是在 Vue 项目中使用时会有无法正确引入的异常

    图片.png

    因为默认安装的 vue-router 是4.0大版本和现在的 vue 版本不兼容,要么升级 vue, 要么降级 vue-router,公司前端团队技术栈定的 Vue2.0 版本,果断降级 vue-router, 安装时 vue-router 时指定一个3.0的版本就行了, 执行 npm install vue-router@3.0.2 --save 命令即可。

    子应用接入 qiankun

    src 目录创建 public-path.js 文件,如果项目 lint 校验不通过需要添加 /* eslint-disable */

    /* eslint-disable */
    if (window.__POWERED_BY_QIANKUN__) {
      __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    }
    

    修改 main.js 文件, 引入 public-path, 添加 qiankun 配置

    import './public-path'
    import Vue from 'vue'
    import App from './App.vue'
    import routes from './router'
    import VueRouter from 'vue-router'
    
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI)
    
    
    Vue.config.productionTip = false
    
    let router = null
    let instance = null
    
    function render(props = {}) {
      const { container } = props
      router = new VueRouter({
        base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
        mode: 'history',
        routes
      })
    
      instance = new Vue({
        router,
        render: (h) => h(App)
      }).$mount(container ? container.querySelector('#app') : '#app')
    }
    
    // 独立运行
    if (!window.__POWERED_BY_QIANKUN__) {
      console.log('111')
      render()
    }
    
    
    // qiankun 钩子函数
    export async function boostrap(){
      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.$destory();
      instance.$el.innerHTML = '';
      instance = null;
      router = null;
    }
    
    
    // main.js 原始写法
    // new Vue({
    //   router,
    //   render: h => h(App),
    // }).$mount('#app')
    
    

    修改 vue.config.js 文件中的打包配置

    const { name } = require('./package.json');
    module.exports = {
      devServer: {
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
      },
      configureWebpack: {
        output: {
          library: `${name}-[name]`,
          libraryTarget: 'umd', // 把微应用打包成 umd 库格式
          jsonpFunction: `webpackJsonp_${name}`,
        },
      },
    };
    
    // 原始写法
    // const { defineConfig } = require('@vue/cli-service')
    // module.exports = defineConfig({
    //   transpileDependencies: true
    // })
    
    

    这时子应用的配置就添加好了

    注意

    Vue 子应用的 @vue/cli-xxx 依赖不能为 5.0 版本,当前配置下导致无法单独运行子应用。如果是安装的最新 vue-cli 脚手架创建的项目最好看一下 @vue/cli-xxx 相关版本。

    相关文章

      网友评论

          本文标题:qiankun 实战(一)

          本文链接:https://www.haomeiwen.com/subject/tqltyrtx.html