Marco de microservicios front-end de Qiankun

1. Notas

Este artículo configura en base a diferentes puertos de un mismo servidor

  • Aplicación principal: admite cualquier pila de tecnología, ilimitada
  • Microaplicación: la versión vite2.x no es compatible por ahora, porque cuando vite empaqueta el código, el esbuild interno eliminará los ganchos del ciclo de vida relacionados con qiankun
  • Documento oficial : qiankun

Si necesita implementar en el mismo puerto en el mismo servidor,
consulte este artículo: qiankun front-end microservice framework: mismo puerto en el mismo servidor

2. Configuración de la aplicación principal

  • La configuración de la aplicación principal es relativamente simple, solo se requieren algunos métodos en main.js y app.vue

2.1 principal.js

import {
    
     createApp } from "vue";
import App from "./App.vue";
import Router from "./router";
import store from "./store";
// 导出qiankun函数
import {
    
     registerMicroApps, setDefaultMountApp, start } from "qiankun";
//匹配路由
function genActiveRule(routerPrefix) {
    
    
  return (location) => location.pathname.startsWith(routerPrefix);
}

let app = createApp(App);
app.use(Router);
app.use(store);
app.mount("#app");

let msg = {
    
    
  data: "传的值",
};

let apps = [
  {
    
    
    name: "a-child",
    entry: "//localhost:6601",
    container: "#subView",
    activeRule: genActiveRule("/a-child"),
    props: msg,
  },
  {
    
    
    name: "b-child",
    entry: "//localhost:6602",
    container: "#subView",
    activeRule: genActiveRule("/b-child"),
    props: msg,
  },
];

//注册的子应用 参数为数组
registerMicroApps(apps, {
    
    
  beforeLoad: [
    (app) => {
    
    
      console.log("beforeLoad");
    },
  ],
  beforeMount: [
    (app) => {
    
    
      console.log("beforeMount");
    },
  ],
  afterUnmount: [
    (app) => {
    
    
      console.log("afterUnmount");
    },
  ],
});
//设置默认初始入口
// setDefaultMountApp("/a-child/xixi");
//启动时配置
start({
    
     experimentalStyleIsolation: true, prefetch: "all" });

2.2 vista de la aplicación

<template>
  <div id="app">
    <div @click="onChangePage('/a-child/xixi')">微应用一号</div>
    <div @click="onChangePage('/b-child/wuwu')">微应用二号</div>
    <div id="subView"></div>
  </div>
</template>
<script>
import {
    
     mapState } from "vuex";
export default {
    
    
  data() {
    
    
    return {
    
    };
  },
  methods: {
    
    
    //改变路由
    onChangePage(url) {
    
    
      console.log(url);
      this.routerGo(url, "测试页面");
    },
    routerGo(href = "/", title = null, stateObj = {
    
    }) {
    
    
      window.history.pushState(stateObj, title, href);
    },
  },
};
</script>

3. Configuración de microaplicaciones

3.1 Registro

Aviso:

  • Todos los recursos (imágenes/audio y video, etc.) deben colocarse en el directorio src. No coloque
    recursos públicos o estáticos en el directorio src. Serán procesados ​​por webpack y se pueden inyectar uniformemente en publicPath. De lo contrario, será 404 en el proyecto principal.

3.1.1 Configuración de vue.config.js

const path = require("path");
const packageName = require("./package.json").name;

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

const dev = process.env.NODE_ENV === "development";

const port = 6601; // dev port

module.exports = {
    
    
  publicPath: dev ? `//localhost:${
      
      port}` : "/",

  outputDir: "dist",
  assetsDir: "static",
  filenameHashing: true,

  devServer: {
    
    
    hot: true,
    historyApiFallback: true,
    port,
    overlay: {
    
    
      warnings: false,
      errors: true,
    },
    headers: {
    
    
      "Access-Control-Allow-Origin": "*",
    },
  },
  // 自定义webpack配置
  configureWebpack: {
    
    
    resolve: {
    
    
      alias: {
    
    
        "@": resolve("src"),
      },
    },
    output: {
    
    
      library: `${
      
      packageName}-[name]`,
      libraryTarget: "umd",
      jsonpFunction: `webpackJsonp_${
      
      packageName}`,
      globalObject: "this",
    },
  },
};

3.1.2 Agregar nuevo archivo publicPath.js

  • Cree un nuevo publicPath.js en el directorio src , y el usuario puede consultarlo en vue.config.js
if (window.__POWERED_BY_QIANKUN__) {
    
     
  //处理资源
   __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; 
  }

3.1.3 main.js de diferentes versiones de microaplicaciones vue

  • El enrutador se crea de diferentes maneras.
  • Hay diferentes formas de desinstalar instancias de microaplicaciones,
    vue2 es instancia.$destory()
    y vue3 es instancia.unmount()

ver2

import "./publicPath.js";
import Vue from "vue";
import App from "./App.vue";
import routes from "./router";
import VueRouter from "vue-router";
import store from "./store";

Vue.config.productionTip = false;

let router = null;
let instance = null;

//下面的 /star  与主应用  registerMicroApps 中的  activeRule 字段对应
function render({
     
      container } = {
     
     }) {
    
    
  router = new VueRouter({
    
    
    base: window.__POWERED_BY_QIANKUN__ ? "/a-child" : process.env.BASE_URL,
    mode: "history",
    routes,
  });

  instance = new Vue({
    
    
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector("#aChild") : "#aChild");
}

if (!window.__POWERED_BY_QIANKUN__) {
    
    
  render();
}
/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
    
    
  console.log("[a-child vue] vue app bootstraped");
}

//应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
    
    
  //props 包含主应用传递的参数  也包括为子应用 创建的节点信息
  render(props);
}

//应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount() {
    
    
  instance.$destroy();
  instance.$el.innerHTML = "";
  instance = null;
  router = null;
}

ver 3

import "./publicPath.js";
import {
    
     createApp } from "vue";
import App from "./App.vue";
import routes from "./router";
import {
    
     createRouter, createWebHistory } from "vue-router";
import store from "./store";

let instance = null;
let router = null;

function render({
     
      container } = {
     
     }) {
    
    
  router = createRouter({
    
    
    history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? "/b-child" : "/"),
    routes,
  });

  instance = createApp(App);
  instance.use(router);
  instance.use(store);
  instance.mount(container ? container.querySelector("#bChild") : "#bChild");
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
    
    
  render();
}

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
    
    }

//应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
    
    
  render(props);
}

//应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount() {
    
    
  instance.unmount();   //和vue2的区别
  instance._container = "";
  instance = null;
  router = null;
}

3.1.4 El espacio de nombres debe ser único

  • identificación en index.html
  • nombre en paquete.json

4. Artículos de referencia [muy recomendable]

1. https://cloud.tencent.com/developer/article/1814160
2. Práctica y resumen de la solución de micro-frontend qiankun
3. Resumen de la práctica de micro-frontend qiankun (2)

Cómo crear un proyecto Vue3

vue3和vue2创建项目区别
- 安装到最新版后,初始化项目时可选择创建vue2还是vue3版本,更具人性化与兼容性

vue3

npm install -g @vue/cli --force:安装vue cli
vue create app:初始化项目


vue2

npm install --global vue-cli:安装vue cli
vue create app

Supongo que te gusta

Origin blog.csdn.net/r657225738/article/details/116296040
Recomendado
Clasificación