Vue + qiankun 快速实现前端微服务

一、前言
什么是微前端
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. – Micro Frontends

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

更多关于微前端的相关介绍,推荐大家可以去看这几篇文章:

Micro Frontends
Micro Frontends from martinfowler.com
可能是你见过最完善的微前端解决方案
微前端的核心价值
qiankun
qiankun 是蚂蚁金服开源的一套完整的微前端解决方案。具体描述可查看 文档 和 Github。

下面将通过一个微服务Demo 介绍 Vue 项目如何接入 qiankun,代码地址:micro-front-vue

二、配置主应用
使用 vue cli 快速创建主应用;
安装 qiankun
$ yarn add qiankun # 或者 npm i qiankun -S
调整主应用 main.js 文件:具体如下:
import Vue from “vue”
import App from “./App.vue”
import router from “./router”

import { registerMicroApps, setDefaultMountApp, start } from “qiankun”
Vue.config.productionTip = false
let app = null;
/**

  • 渲染函数
  • appContent 子应用html内容
  • loading 子应用加载效果,可选
    */
    function render({ appContent, loading } = {}) {
    if (!app) {
    app = new Vue({
    el: “#container”,
    router,
    data() {
    return {
    content: appContent,
    loading
    };
    },
    render(h) {
    return h(App, {
    props: {
    content: this.content,
    loading: this.loading
    }
    });
    }
    });
    } else {
    app.content = appContent;
    app.loading = loading;
    }
    }

/**

  • 路由监听
  • @param {*} routerPrefix 前缀
    */
    function genActiveRule(routerPrefix) {
    return location => location.pathname.startsWith(routerPrefix);
    }

function initApp() {
render({ appContent: ‘’, loading: true });
}

initApp();

// 传入子应用的数据
let msg = {
data: {
auth: false
},
fns: [
{
name: “_LOGIN”,
_LOGIN(data) {
console.log(父应用返回信息${data});
}
}
]
};
// 注册子应用
registerMicroApps(
[
{
name: “sub-app-1”,
entry: “//localhost:8091”,
render,
activeRule: genActiveRule("/app1"),
props: msg
},
{
name: “sub-app-2”,
entry: “//localhost:8092”,
render,
activeRule: genActiveRule("/app2"),
}
],
{
beforeLoad: [
app => {
console.log(“before load”, app);
}
], // 挂载前回调
beforeMount: [
app => {
console.log(“before mount”, app);
}
], // 挂载后回调
afterUnmount: [
app => {
console.log(“after unload”, app);
}
] // 卸载后回调
}
);

// 设置默认子应用,与 genActiveRule中的参数保持一致
setDefaultMountApp("/app1");

// 启动
start();

修改主应用 index.html 中绑定的 id ,需与 el 绑定 dom 为一致;
调整 App.vue 文件,增加渲染子应用的盒子:

loading

创建 vue.config.js 文件,设置 port :
module.exports = {
devServer: {
port: 8090
}
}
三、配置子应用
在主应用同一级目录下快速创建子应用,子应用无需安装 qiankun
配置子应用 main.js:
import Vue from ‘vue’;
import VueRouter from ‘vue-router’;
import App from ‘./App.vue’;
import routes from ‘./router’;
import ‘./public-path’;

Vue.config.productionTip = false;

let router = null;
let instance = null;

function render() {
router = new VueRouter({
base: window.POWERED_BY_QIANKUN ? ‘/app1’ : ‘/’,
mode: ‘history’,
routes,
});

instance = new Vue({
    router,
    render: h => h(App),
}).$mount('#app');

}

if (!window.POWERED_BY_QIANKUN) {
render();
}

export async function bootstrap() {
console.log(‘vue app bootstraped’);
}

export async function mount(props) {
console.log(‘props from main app’, props);
render();
}

export async function unmount() {
instance.$destroy();
instance = null;
router = null;
}
配置 vue.config.js
const path = require(‘path’);
const { name } = require(’./package’);

function resolve(dir) {
return path.join(__dirname, dir);
}

const port = 8091; // dev port

module.exports = {
/**

  • You will need to set publicPath if you plan to deploy your site under a sub path,
  • for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
  • then publicPath should be set to “/bar/”.
  • In most cases please use ‘/’ !!!
  • Detail: https://cli.vuejs.org/config/#publicpath
    /
    outputDir: ‘dist’,
    assetsDir: ‘static’,
    filenameHashing: true,
    // tweak internal webpack configuration.
    // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
    devServer: {
    // host: ‘0.0.0.0’,
    hot: true,
    disableHostCheck: true,
    port,
    overlay: {
    warnings: false,
    errors: true,
    },
    headers: {
    ‘Access-Control-Allow-Origin’: '
    ’,
    },
    },
    // 自定义webpack配置
    configureWebpack: {
    resolve: {
    alias: {
    ‘@’: resolve(‘src’),
    },
    },
    output: {
    // 把子应用打包成 umd 库格式
    library: ${name}-[name],
    libraryTarget: ‘umd’,
    jsonpFunction: webpackJsonp_${name},
    },
    },
    };
    其中有个需要注意的点:

子应用必须支持跨域:由于 qiankun 是通过 fetch 去获取子应用的引入的静态资源的,所以必须要求这些静态资源支持跨域;
使用 webpack 静态 publicPath 配置:可以通过两种方式设置,一种是直接在 mian.js 中引入 public-path.js 文件,一种是在开发环境直接修改 vue.config.js:
{
output: {
publicPath: //localhost:${port};
}
}
public-path.js 内容如下:

if (window.POWERED_BY_QIANKUN) {
// eslint-disable-next-line no-undef
webpack_public_path = window.INJECTED_PUBLIC_PATH_BY_QIANKUN
}
至此,Vue 项目的前端微服务已经简单完成了。

但是在实际的开发过程中,并非如此简单,同时还存在应用间跳转、应用间通信等问题

你可能感兴趣的:(vue.js,javascript,node.js)