How does the Vue project implement front-end microservices

One, foreword

What is a micro front end

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. — Micro Frontends

The micro front end is a technical approach and strategy for multiple teams to build modern Web applications by independently publishing their capabilities.

For more information about the micro front end, I recommend you to read these articles:

  • Micro Frontends
  • Micro Frontends from martinfowler.com
  • Probably the most complete micro front end solution you’ve ever seen
  • Core values of the micro front end

qiankun

Qiankun is a complete set of open-source micro front-end solutions from Ant Financial. For details, see the documentation and Github.

The Vue project is connected to Qiankun through a micro-service Demo. The code address is micro-front-Vue

2. Configure the master application

  1. Use vUE CLI to quickly create a master application.
  2. Install qiankun
$ yarn add qiankun # or NPM I qiankun-s
Copy the code
  1. Tuning the master applicationmain.jsFiles: The details are as follows:
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;
/** * Render function * appContent child HTML content * Loading child loading effect, optional */
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; }}/** * Route monitor *@param {*} RouterPrefix prefix * /
function genActiveRule(routerPrefix) {
	return location= > location.pathname.startsWith(routerPrefix);
}

function initApp() {
	render({ appContent: ' '.loading: true });
}

initApp();

// Pass data to the child application
let msg = {
	data: {
		auth: false
	},
	fns: [{name: "_LOGIN"._LOGIN(data) {
				console.log('The parent application returns information${data}`); }}};// Register the subapplication
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); }].// Call back before mounting
		beforeMount: [
			app= > {
				console.log("before mount", app); }].// Call back after mount
		afterUnmount: [
			app= > {
				console.log("after unload", app); }]// Call back after uninstallation});// Set the default subapplication, consistent with the parameters in genActiveRule
setDefaultMountApp("/app1");

/ / start
start();

Copy the code
  1. Modify the binding in the main application index.htmlidAnd need to be withelDom binding is consistent;
  2. Adjusted app. vue file to add render subapplication box:
<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>Copy the code
  1. Create the vue.config.js file and setport :
module.exports = {
	devServer: {
		port: 8090}}Copy the code

3. Configure sub-applications

  1. Create sub-applications in the same directory as the primary application without installation
  2. Configure the subapplication 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;
}
Copy the code
  1. Configure the 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': The '*',}},// Customize webPack configuration
	configureWebpack: {
		resolve: {
			alias: {
				The '@': resolve('src'),}},output: {
			// Package the child application in umD library format
			library: `${name}-[name]`.libraryTarget: 'umd'.jsonpFunction: `webpackJsonp_${name}`,}}};Copy the code

Here’s a caveat:

  1. Sub-applications must support cross-domains: As Qiankun fetches static resources from sub-applications via fetch, it must require these static resources to support cross-domains.
  2. Using webPack static publicPath configuration: You can set it either by importing the public-path.js file directly in mian.
{
  output: {
    publicPath: `//localhost:${port}`; }}Copy the code

The contents of public-path.js are as follows:

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
Copy the code

At this point, the front-end microservice for the Vue project is simply complete.

However, in the actual development process, it is not so simple, and there are also problems such as inter-application jump, inter-application communication.


Code, articles continue to be updated…