本文介绍 Vue 项目如何实现前端微服务html
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends微前端是一种多个团队经过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。前端
更多关于微前端的相关介绍,推荐你们能够去看这几篇文章:vue
qiankun 是蚂蚁金服开源的一套完整的微前端解决方案。具体描述可查看 文档 和 Github。webpack
下面将经过一个微服务Demo 介绍 Vue 项目如何接入 qiankun,代码地址:micro-front-vue)git
$ 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();
id
,需与 el
绑定 dom 为一致;<template> <div id="main-root"> <!-- loading --> <div v-if="loading">loading</div> <!-- 子应用盒子 --> <div id="root-view" class="app-view-box" v-html="content"></div> </div> </template> <script> export default { name: "App", props: { loading: Boolean, content: String } }; </script>
port
:module.exports = { devServer: { port: 8090 } }
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; }
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}`, }, }, };
其中有个须要注意的点:github
{ output: { publicPath: `//localhost:${port}`; } }
public-path.js 内容以下:web
if (window.__POWERED_BY_QIANKUN__) { // eslint-disable-next-line no-undef __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ }
至此,Vue 项目的前端微服务已经简单完成了。
可是在实际的开发过程当中,并不是如此简单,同时还存在应用间跳转、应用间通讯等问题。vue-router
代码、文章 持续更新中...vue-cli