【微前端】qiankun + vite + vue3

news/2024/7/21 18:57:47 标签: 微前端, vite, vue3, qiankun

专栏:

一、整体结构

qiankun 体系下,一个微前端工程包含一个主应用和多个子应用。本质上,每个工程(主应用)都可以单独开发、运行。

1.1 开发时工程结构

共三个工程,一个主应用、两个子应用,目录结构:

.
├── app-01
│   ├── README.md
│   ├── index.html
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   └── vite.config.ts
├── app-02
│   ├── README.md
│   ├── index.html
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   └── vite.config.ts
├── main-app
│   ├── README.md
│   ├── index.html
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   └── vite.config.ts
└── readme.md

1.2 部署工程结构

部署方式可以选择多种,这里使用的方式是将三个工程部署在同一个 server、同一个 port 下,目录结构为:

.
├── index.html
├── static
│   ├── index-011eeef2.css
│   └── index-0ab867b1.js
├── sub
│   ├── app-01
│   │   ├── index.html
│   │   ├── static
│   │   │   ├── index-0244ff29.js
│   │   │   └── index-83c9dd61.css
│   │   └── vite.svg
│   └── app-02
│       ├── index.html
│       ├── static
│       │   └── index-cb440182.js
│       └── vite.svg
└── vite.svg

二、开发

开发时,三个应用对应的监听端口:

应用端口
main-app80
app-018081
app-028082

工程启动之后,可以在浏览器访问:

  • http://localhost:80 整体运行效果
  • http://localhost:8081 app-01 单独运行效果
  • http://localhost:8082 app-02 单独运行效果

2.1 主应用

主应用用于注册子应用,以及控制子应用之间的切换。

A. 注册子应用

在新建的 vue3 工程的 main.ts 中注册子应用:

// 开发模式时,entry的值为子应用的开发演示环境的地址
if ("development" === import.meta.env.MODE) {
  registerMicroApps([
    {
      name: "app_01",
      entry: "//localhost:8081/",
      container: "#container",
      activeRule: "/app_01",
    },
    {
      name: "app_02",
      entry: "//localhost:8082/",
      container: "#container",
      activeRule: "/app_02",
    },
  ]);
} else {
  // 生产环境时,entry的路径为app在部署时的真实路径
  registerMicroApps([
    {
      name: "app_01",
      entry: "./sub/app-01",
      container: "#container",
      activeRule: "/app_01",
    },
    {
      name: "app_02",
      entry: "./sub/app-02",
      container: "#container",
      activeRule: "/app_02",
    },
  ]);
}

setDefaultMountApp("/app_01");

// 启动 qiankun
start();

注册子应用时,分为两种模式,开发模式和部署模式,对应的 entry 的值是有区别的。

B. 子应用路由

<a @click="toApp('/app_01')">app 01</a>
function toApp(path: string) {
  history.pushState({}, "", path);
}

需要注意的是,这里不能使用 a 标签 的 href,会报错 404 错误,必须使用history.pushState控制路由。

因为href属性会导致浏览器刷新,获取不到资源。

2.2 子应用

A. 安装依赖

pnpm add vite-plugin-qiankun

viteconfigjs_166">vite.config.js

配置文件修改

export default defineConfig({
  // 打包时,这里填充的为绝对路径,对应的是部署路径
  base: "/sub/app-01",
  plugins: [
    vue(),
    qiankun("app-01", {
      useDevMode: true,
    }),
  ],
});

C. 入口改造

启动方式,分为两种:

  • 单独启动
  • 在主应用中启动

qiankun 需要子应用导出三个接口:

  • bootstrap
  • mount
  • unmount
import {
  renderWithQiankun,
  qiankunWindow,
} from "vite-plugin-qiankun/dist/helper";

import { App as VueApp, createApp } from "vue";
import router from "./router";
import App from "./App.vue";

let app: VueApp<Element>;
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  createApp(App).use(router).mount("#app");
} else {
  renderWithQiankun({
    mount(props) {
      console.log("--app 01 mount");

      app = createApp(App);
      app.use(router);
      app.mount(
        (props.container
          ? props.container.querySelector("#app")
          : document.getElementById("app")) as Element
      );
    },
    bootstrap() {
      console.log("--app 01 bootstrap");
    },
    update() {
      console.log("--app 01 update");
    },
    unmount() {
      console.log("--app 01 unmount");
      app?.unmount();
    },
  });
}

三、部署

三个工程依次打包后,在main-app的打包输出中,新建 sub 文件夹,将子应用的打包输出移动到 sub 文件夹中。结构:

.
├── index.html
├── static
│   ├── index-011eeef2.css
│   └── index-0ab867b1.js
├── sub
│   ├── app-01
│   │   ├── index.html
│   │   ├── static
│   │   │   ├── index-0244ff29.js
│   │   │   └── index-83c9dd61.css
│   │   └── vite.svg
│   └── app-02
│       ├── index.html
│       ├── static
│       │   └── index-cb440182.js
│       └── vite.svg
└── vite.svg

在本地启动一个静态 web 服务即可访问页面,比如使用serve命令启动服务:

serve . -p 5500

浏览器中访问:http://localhost:5500

四、坑点

001. 主应用注册 App 时,activeRule 有两种模式

hash 模式

const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);
registerMicroApps([
  {
    name: "app-hash",
    entry: "http://localhost:8080",
    container: "#container",
    activeRule: getActiveRule("#/app-hash"),
    // 这里也可以直接写 activeRule: '#/app-hash',但是如果主应用是 history 模式或者主应用部署在非根目录,这样写不会生效。
  },
]);

history 模式

registerMicroApps([
  {
    name: "app",
    entry: "http://localhost:8080",
    container: "#container",
    activeRule: "/app",
  },
]);

002. 主应用使用history时,如何控制子应用的切换

history 模式时,主应用会监听location.pathname的变化,从而切换子应用的加载与卸载。

主应用中,使用 a 便签切换应用时:

<!-- 开发环境时,没有问题 -->
<!-- 部署环境时,会报错:/app_01 404的错误 -->
<a href="/app_01">app 01</a>

404 的原因,静态部署时:a 标签会触发浏览器的刷新,刷新后,浏览器向后台发起请求/app_01,后台的确没有这个物理路径

改进方案,使用 history.pushState 接口:

<a @click="toApp('/app_01')">app 01</a>
function toApp(path: string) {
  history.pushState({}, "", path);
}

使用history.pushState的方式,不会出发浏览器的刷新行为。当浏览器的pathname发生变化时,qiankun会感知到路由发生变化,并加载对应的页面。

到这一步时,若不主动执行F5刷新操作,一切正常。但使用F5后,还是会报错 404,此时需要后台的路由进行配合,以 Nginx 为例子:

server {
  listen       8080;
  server_name  localhost;

  location / {
    root   html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  location /child/vue-history {
    root   html;
    index  index.html index.htm;
    try_files $uri $uri/ /child/vue-history/index.html;
  }
}

六、源码

源码地址:https://github.com/swlws/qiankun-vite-vue3


http://www.niftyadmin.cn/n/164795.html

相关文章

Java 基础学习总结(205)—— 后端接口设计实用技巧汇总

参数校验 入参出参校验是每个程序员必备的基本素养。你设计的接口,必须先校验参数。比如入参是否允许为空,入参长度是否符合你的预期长度。这个要养成习惯哈,日常开发中,很多低级bug都是不校验参数导致的。比如你的数据库表字段设置为 varchar(16) ,对方传了一个32位的字符…

1.7 日本蜡烛图技术之看透窗口

技术分析方法&#xff1a; 交易三要素 东方技术分析 K线图 西方技术分析 支撑头肩线 资本保全 剃头形态 没有上影线的K线图 长K线是强烈的上涨信号&#xff0c;特别是出现在下跌趋势之后 窗口 价格跳空&#xff0c;跳空越大&#xff0c;信号越强 前一天收盘价和后一天开盘价的…

从零开始学Python第02课:第一个Python程序

在上一课中&#xff0c;我们对 Python 语言的过去现在有了一些了解&#xff0c;我们准备好了运行 Python 程序所需要的解释器环境。相信大家已经迫不及待的想开始自己的 Python 编程之旅了&#xff0c;但是新问题来了&#xff0c;我们应该在什么地方书写 Python 程序&#xff0…

【博学谷学习记录】超强总结,用心分享丨人工智能 自然语言处理 迁移学习部分笔记

目录FastText作用优势安装文本分类种类过程训练词向量词向量迁移迁移学习标准数据集预训练模型加载和使用预训练模型的步骤FastText 作用 进行文本分类训练词向量 优势 保持较高精度的情况下, 快速的进行训练和预测 安装 pip install fasttext文本分类 种类 二分类单标…

k8s 1.18.20版本部署

身为k8s初学者&#xff0c;在掌握k8s理论知识的同时&#xff0c;也需要掌握一下实际部署k8s的过程&#xff0c;对于理论的学习起到一定的帮助作用。罗列了一下相关步骤&#xff0c;请各位参考&#xff1a; 一、环境准备 三台虚机&#xff1a; 操作系统&#xff1a; CentOS L…

DVWA_xss

反射型xsslow直接在输入框输入提前准备的代码&#xff0c;就可以得到回显cookie信息Medium在输入代码之后&#xff0c;回显的是hello 用户名&#xff0c;而没有发生弹窗回显cookie信息&#xff0c;这说明可能是源码里过滤 了<script>&#xff0c;想起了文件上传的大小写绕…

Nginx (location/rewrite) ——重写跳转

目录 1.Nginx常见模块 2. 常用的nginx正则表达式 3.访问路由location 1. location的分类 2.location 常用的匹配规则 3.location 优先级 4.location 示例说明 5.实际网站使用中的三个匹配规则定义 4.访问重新rewrite 1.rewrite的概述 2.rewrite 执行顺序如下 3.Rewri…

能快速构建和定制网络拓扑图的WPF开源项目-NodeNetwork

大家好&#xff0c;我是沙漠尽头的狼&#xff0c;今天介绍一个WPF开源项目-NodeNetwork&#xff0c;它可以帮助我们快速构建和定制网络拓扑图。 一、前言 在现代软件开发中&#xff0c;数据可视化和可交互性越来越受到关注。为了实现这一点&#xff0c;通常需要使用各种图表、…