本文介紹 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