Cadre de micro-service frontal Qiankun

1. Remarques

Cet article configure en fonction de différents ports du même serveur

  • Application principale : prend en charge n'importe quelle pile technologique, illimitée
  • Micro-application : la version vite2.x n'est pas prise en charge pour l'instant, car lorsque vite empaquete le code, l'esbuild interne se débarrassera des hooks de cycle de vie liés à qiankun
  • Document officiel : qiankun

Si vous avez besoin de déployer sur le même port sur le même serveur,
veuillez consulter cet article : framework de microservice frontal qiankun - même port sur le même serveur

2. Configuration principale de l'application

  • La configuration principale de l'application est relativement simple, seules certaines méthodes dans main.js et app.vue sont requises

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 app.view

<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. Configuration des micro-applications

3.1 Inscription

Avis:

  • Toutes les ressources (images/audio et vidéo, etc.) doivent être placées dans le répertoire src. Ne mettez pas de
    ressources publiques ou statiques dans le répertoire src. Elles seront traitées par webpack et pourront être injectées uniformément dans le publicPath. Sinon, ce sera 404 dans le projet principal

3.1.1 Configuration 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 Ajouter un nouveau fichier publicPath.js

  • Créez un nouveau publicPath.js dans le répertoire src et l'utilisateur pourra s'y référer dans vue.config.js
if (window.__POWERED_BY_QIANKUN__) {
    
     
  //处理资源
   __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; 
  }

3.1.3 main.js de différentes versions de vue de micro-application

  • Le routeur est créé de différentes manières
  • Il existe différentes façons de désinstaller les instances de micro-application,
    vue2 est instance.$destory()
    et vue3 est instance.unmount()

vue2

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;
}

vue 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 L'espace de noms doit être unique

  • identifiant dans index.html
  • nom dans package.json

4. Articles de référence [fortement recommandé]

1. https://cloud.tencent.com/developer/article/1814160
2. Pratique et résumé de la solution micro-frontend qiankun
3. Résumé de la pratique micro-frontend qiankun (2)

Comment créer un projet 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

Guess you like

Origin blog.csdn.net/r657225738/article/details/116296040