美文网首页前端工程化
qiankun + Vue实现微前端服务

qiankun + Vue实现微前端服务

作者: 超人s | 来源:发表于2020-11-06 15:55 被阅读0次

    本文介绍如何使用qiankun + Vue搭建一个前端微服务

    一、什么是微前端

    Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
    微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

    以上内容均来自于 qiankun手册,有兴趣可以也看看这个api文档,很多关于微前端的困惑都在里面,以及为什么是不用iframe等....
    本文代码,可以直接食用:qiankun-demo
    效果:

    微前端效果.gif

    二、创建应用

    在本例子中,我们需要通过vue-cli创建创建一个主应用,两个子应用。
    目录结构:

    |——qiankun-demo // 主文件夹
    |——|——child-app01 //子应用1
    |——|——child-app02 //子应用2
    |——|——main-app //主应用
    |——|——server.js // 自己写的一个快捷启动服务脚本,手动启动服务的可以忽略
    |——|——package.js // 脚本依赖,手动启动服务的可以忽略
    

    三、应用配置

    主应用相关代码:

    qiankun是通过registerMicroApps(apps, lifeCycles)API来注册子应用的,在main-app目录下

    npm install qiankun -S
    npm install element-ui -S // 引入element快速实现样式
    

    main.js

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import element from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    Vue.use(element);
    import { registerMicroApps, start } from 'qiankun'
    
    Vue.config.productionTip = false
    
    const microAppNum = 2
    let apps = [];
    for (let i = 1; i <= microAppNum; i++) {
      apps.push(
        {
          name: '子应用child0' + i,
          entry: 'http://localhost:90' + i + '0',
          //fetch,
          container: '#vue',
          activeRule: '/child0' + i,
          props: { param01: i }
        }
      );
    }
    const config = {
        beforeLoad: [
            app => {
                console.log("%c before load",
                'background:#0f0 ; padding: 1px; border-radius: 3px;  color: #fff',
                app);
            }
        ], // 挂载前回调
        beforeMount: [
            app => {
                console.log("%c before mount",
                'background:#f1f ; padding: 1px; border-radius: 3px;  color: #fff',
                app);
            }
        ], // 挂载后回调
        afterUnmount: [
            app => {
                console.log("%c after unload",
                'background:#a7a ; padding: 1px; border-radius: 3px;  color: #fff',
                app);
            }
        ] // 卸载后回调
      }
    registerMicroApps(apps, config);
    let option = { prefetch: false }
    start();
    
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    
    • 如果暂时不需要看到生命周期的输出,可以不定义config,同时注册应该时registerMicroApps(apps, config);把里面的config去掉即可
    • 其中的container内的#vue,对应app.vue内的id="vue"元素块

    vue.config.js

    若不存在该文件,新建一个vue.config.js

    module.exports = {
        devServer: {
            port: 9000,
            headers: {
                //'Access-Control-Allow-Origin': "*"
            }
        }
    };
    

    App.vue

    利用引入的element,快速搭建一个简单的页面

    <template>
      <div>
        <el-menu :router="true" mode="horizontal">
          <el-menu-item index="/">首页</el-menu-item>
          <el-menu-item v-for="no in  microAppNum" :key="no" :index="'/child0'+no">子应用0{{no}}</el-menu-item>
        </el-menu>
        <router-view />
        <!-- 子应用入口 -->
        <div id="vue"></div>
      </div>
    </template>
    
    <script>
    export default {
      name: "main01",
      data() {
        return {
          microAppNum: 2
        };
      },
    };
    </script>
    

    子应用配置

    mian.js

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    // Vue.config.productionTip = false
    
    let install = null;
    function render(props) {
      install = new Vue({
        router,
        store,
        render: h => h(App)
      }).$mount('#app')
    }
    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();
    }
    

    vue.config.js

    同样,在该文件内,

    const port = 9010; // 一个应用写9010,另一个写9020
    module.exports = {
        devServer: {
            port,
            headers: {
                'Access-Control-Allow-Origin': '*'
            }
        },
        configureWebpack: {
            output: {
                library: 'child',
                libraryTarget: 'umd'
            }
        }
    };
    

    子应用必须支持跨域:由于 qiankun 是通过 fetch 去获取子应用的引入的静态资源的,所以必须要求这些静态资源支持跨域;

    本地服务直接在vue.config.js内配上跨域相关即可,上线的话,需要在服务器配置白名单。后续文章将更新跟打包相关内容。

    /router/index.js

    这里需要特别注意,我们在父应用注册微服务的时候,写了相关activeRule,
    所以子应用路由这边配置也要相应的修改


    image.png

    四、使用

    分别进入父子应用目录

    npm run serve
    

    全部启动后,可以单独打开子应用,看到页面,也可以在主应用内,直接看到里面的子应用,效果类似iframe。

    发现服务启动,因为代码端口写死,若端口冲突,可以关闭端口重新启动服务,或者修改代码。

    由于我不想每次都进入父子应用目录,去重复启动多个服务,手动写了一个node脚本,去快速启动三个服务,可以手动启动服务的,可忽略该脚本,分别手动启动三个服务即可。

    相关文章

      网友评论

        本文标题:qiankun + Vue实现微前端服务

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