Table of contents
1. What is a micro frontend?
Micro-frontend is a technical means and method strategy for multiple teams to jointly build modern web applications by releasing functions independently.
2. Core Values
① Technology stack irrelevant: The main framework does not limit the technology stack of the access application, and the micro application has complete autonomy.
②Independent development and independent deployment: The micro-application warehouse is independent, and the front and rear ends can be independently developed. After the deployment is completed, the main framework will automatically complete the synchronous update.
③Incremental upgrade: When faced with various complex scenarios, it is usually difficult for us to upgrade or refactor the entire technology stack of an existing system, and the micro-frontend is a very good means of implementing gradual refactoring and strategy.
④ Independent runtime: The state of each micro-application is isolated, and the runtime state is not shared.
3. Meaning
The micro front-end architecture is designed to solve the problem of single application in a relatively long time span, due to the increase and change of participating personnel and teams, after it evolves from an ordinary application to a frontend monolith application, the ensuing application unmaintainable problem. This type of problem is especially common in enterprise web applications.
4. Implementation of qiankun
main application
①Install qiankun
It only needs to be installed in the main application, and the micro application does not need to be installed.
yarn add qiankun
②Register micro-app (main.js)
import Vue from "vue";
import App from "./App";
import router from "./router";
import store from "./store";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import { registerMicroApps, start } from "qiankun";
Vue.config.productionTip = false;
Vue.use(ElementUI);
registerMicroApps([ // 注册应用
{
name: "micro", // 微应用的名称
entry: "//localhost:8087", // 微应用的地址
container: "#micro-one", // 放置微应用的容器
activeRule: "/vue", // 匹配逻辑
props: { data: store.state } // 向微应用传递的值
}
]);
start(); // 启动
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
After the micro-app information is registered, once the url of the browser changes, the matching logic of qiankun will be automatically triggered, and all micro-apps that match the activeRule rule will be inserted into the specified container, and at the same time, the micro-apps will be called sequentially to expose lifecycle hooks.
③Set the main application routing (router/index.js)
const routes = [
{
path: "/",
name: "main",
component: Main
}
];
const router = new Router({
mode: "history", // 设置路由模式为 history
routes
});
④Navigation menu (App.vue)
<template>
<div id="app">
<el-menu :router="true" mode="horizontal" default-active="/">
<!-- 点击不同的菜单,跳转到对应的路由 -->
<el-menu-item index="/">主应用</el-menu-item>
<!-- 此处的"/vue"与注册微应用时的匹配逻辑相对应 -->
<el-menu-item index="/vue">微应用</el-menu-item>
</el-menu>
<router-view />
<!-- 定义存放微应用的容器 -->
<div id="micro-one"></div>
</div>
</template>
⑤ Define store (store/index.js)
Used to store the passed data.
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
mainData: {}
},
mutations: {
saveMain(state, data) {
state.mainData = data;
}
}
});
⑥Main application content (views/main.vue)
methods: {
emitMain() {
this.$store.commit("saveMain", this.input); // 点击按钮向 store 中存入input的值
}
}
micro application
① Modify the port number to correspond to when registering the micro-app (config/index.js)
dev: {
host: 'localhost',
port: 8087,
},
②Enable cross-domain access between applications (webpack.dev.conf.js)
devServer: {
headers: {
"Access-Control-Allow-Origin": "*" // 开启应用间的跨域访问
}
},
③Packaging tools add configuration (webpack.base.conf.js)
output: {
library: "micro",
libraryTarget: "umd",
},
④Define the store, the same as the main application
⑤ Export the corresponding life cycle hook (main.js)
bootstrap
The micro-app needs to export , , mount
and unmount
three lifecycle hooks in its own entry js (usually the entry js of your configured webpack) , so that the main application can call it at an appropriate time.
import Vue from "vue";
import App from "./App";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
let instance = null;
function render(props = {}) {
if (props.data) {
// 将主应用传递的值存放至 store 中
store.commit("saveMain", props.data.mainData);
}
const { container } = props;
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector("#app") : "#app");
// 解决微应用的根 id 与其他 DOM 冲突:修改根 id 的查找范围
}
if (!window.__POWERED_BY_QIANKUN__) { // 如果是独立运行,则手动调用渲染
render();
}
if (window.__POWERED_BY_QIANKUN__) { // 如果是 qiankun 使用到了,则会动态注入路径
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 根据 qiankun 的协议需要导出 bootstrap/mount/unmount
export async function bootstrap(props) {
console.log("micro bootstraped");
}
export async function mount(props) {
render(props);
console.log("micro mounted");
}
export async function unmount(props) {
instance.$destroy();
console.log("micro unmounted");
}
⑥Set micro-app routing (router/index.js)
const routes = [
{
path: "/",
name: "micro",
component: Micro
}
];
const router = new Router({
mode: "history",
base: "/vue", // 此处的"/vue"与注册微应用时的匹配逻辑相对应
routes
});
⑦ Micro application content (views/micro.js)
mounted() {
this.mainData = this.$store.state.mainData; // 取出 store 中存放的来自主应用的值
}
at last
Run main app and micro app at the same time.
qiankun official website: https://qiankun.umijs.org/zh/guide