qiankun微前端

什么是微前端

我个人理解就是,微前端就像一个游戏盒子,每个项目都是独立的游戏,有了这个微前端盒子平台,我可以快速启动任何一个项目,并且还能让项目之间进行联动(传参-通信)。

结构

— main 乾坤主应用
— v2 子应用
— v3 子应用

主应用

main 该项目我采用vue3开发的,实际上主应用可以是原生的,也可以是index.html页面都可以的。

不过这里还是使用相对高级的vue3项目搭建。

  1. 创建项目
    vue create main
  2. 安装qiankun
    npm i qiankun我的项目中是”qiankun”: “^2.7.3”
  3. src/qk.js 配置我们的乾坤服务
    import { registerMicroApps, start, setDefaultMountApp } from "qiankun";
    
    // 子应用的配置
    registerMicroApps([
      {
        name: "v3", // 必须唯一
        entry: "http://localhost:8080", // 用来匹配子应用程序的
        container: "#child", // 指的是子应用渲染在父应用的某个元素上
        activeRule: "/v3", // 匹配子应用的基础路由地址
      },
      {
        name: "v2", // 必须唯一
        entry: "http://localhost:8081", // 用来匹配子应用程序的
        container: "#child", // 指的是子应用渲染在父应用的某个元素上
        activeRule: "/v2", // 匹配子应用的基础路由地址
      },
    ]);
    
    start();
    // 自动打开一个子应用
    setDefaultMountApp("/v3/");
  4. 在main.js中引入qk.js
  5. 在App.vue中创建div,id值为child,这一步很重要,它是用来渲染子应用的根元素,相当于视图组件。不同的应用可以用不同的元素接收,我这里图省事,全都用一个元素来渲染了。
  6. App.vue里的代码
    <nav>
        <router-link to="/">主应用首页</router-link> |
        <router-link to="/about">主应用关于</router-link>|
        <router-link to="/v3/">子应用首页</router-link>|
        <router-link to="/v3/about">子应用关于</router-link>
      </nav>
      <!-- 这里的router-view只是用来显示主应用的路由组件的 -->
      <router-view /> 
      <!-- 挂载子应用的容器 -->
      <div id="child"></div>

    vue2子应用

  7. 创建子项目
    vue create v2
  8. 子项目不需要安装qiankun,只需要配置之后,启动就可以了
  9. 配置‘vue.config.js’
    const { defineConfig } = require("@vue/cli-service");
    module.exports = defineConfig({
      transpileDependencies: true,
      devServer: {
        port: 8081,
        headers: {
          "Access-Control-Allow-Origin": "*",
        },
      },
      configureWebpack: {
        output: {
          library: `v2`, // 这里得值和主应用得名称保持一致
          libraryTarget: "umd", // 把微应用打包成 umd 库格式
          // jsonpFunction: `webpackJsonp_${name}`, // 新版webpack5不支持此api
        },
      },
    });
  10. 在main.js中编辑如下内容
    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    
    // 这个主要解决的是子应用动态载入的脚本,样式,图片等地址不正确的问题。
    if (window.__POWERED_BY_QIANKUN__) {
      __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    }
    
    let instance = null;
    function render(props = {}) {
      const { container } = props;
      instance = new Vue({
        router,
        render: (h) => h(App),
      }).$mount(container ? container.querySelector("#app") : "#app");
    }
    
    // 独立运行项目时
    if (!window.__POWERED_BY_QIANKUN__) {
      render();
    }
    
    // 如下几个是给乾坤用得生命周期,可以用来子应用间通信等操作
    export async function bootstrap() {
      console.log("[vue] vue app bootstraped");
    }
    export async function mount(props) {
      console.log("[vue] props from main framework", props);
      render(props);
    }
    export async function unmount() {
      instance.$destroy();
      instance.$el.innerHTML = "";
      instance = null;
      router = null;
    }
  11. 子应用的router.js 配置
    const router = new VueRouter({
      mode: "history",
      // 如果是在乾坤里运行的话,使用主应用配置的路由,
      // 否则就是.env.xx 里配置的,默认是 / 
      base: window.__POWERED_BY_QIANKUN__ ? "/v2" : process.env.BASE_URL,
      routes,
    });
    
    export default router;

vue3子应用

// 1. vue.config.js
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*", // 解决了父子应用间的跨域问题
    },
  },
  configureWebpack: {
    output: {
      library: `v3`,
      libraryTarget: "umd", // 把微应用打包成 umd 库格式
      // jsonpFunction: `webpackJsonp_${name}`,
    },
  },
});
// 2. main.js 
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

let instance = null;
function render(props = {}) {
  const { container } = props;
  instance = createApp(App)
    .use(router)
    .mount(container ? container.querySelector("#app") : "#app");
}

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

export async function bootstrap() {
  console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
  console.log("[vue] props from main framework", props);
  render(props);
}

export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = "";
  instance = null;
  router = null;
}
// 3.router.js 

const router = createRouter({
  history: createWebHistory(
    window.__POWERED_BY_QIANKUN__ ? "/v3" : process.env.BASE_URL
  ),
  routes,
});

export default router;

总结

先启动所有的子应用,注意,所有项目的端口号不可以重复。最后启动微前端项目。

运行机制其实很简单,当我们在主应用里使用子应用路由的时候,乾坤会去匹配到子应用路由,并将其加载到主应用的指定dom元素中显示。

但是,每次都手动启动那么多项目,很烦,所以我们可以使用工具,来一次性启动多个项目。

这里我配置在主应用里了。

  1. 安装 concurrently 目前是”concurrently”: “^7.2.2”
    "scripts": {
       "all": "concurrently \"npm run serve\" \"cd ../v2 && npm run serve\" \"cd ../v3 && npm run serve\"",
       "serve": "vue-cli-service serve",
       "build": "vue-cli-service build"
     },
  2. 使用’npm run all’ 就可以启动所有项目了

参考1

参考2




如果你遇到了前端难题,或者需要一对一帮扶服务,请到淘宝搜索店铺:前端在线或扫下面二维码

  转载规则


《qiankun微前端》宋宇采用知识共享署名 4.0 国际许可协议进行许可。
 上一篇
国际语言对照表国际语言对照表
语言代码表 语言代码语言名称 af南非语 af-ZA南非语 ar阿拉伯语 ar-AE阿拉伯语(阿联酋) ar-BH阿拉伯语(巴林) ar-DZ阿拉伯语(阿尔及利亚) ar-EG阿拉伯语(埃及) ar-IQ阿拉伯语(伊拉克)
2022-08-04
下一篇 
mac虚拟机安装win11mac虚拟机安装win11
本篇记录我在mac中使用VMware安装win11的问题和解决方案
2022-07-28
  目录