qiankun?可能这些微前端框架更适合你

大家好,我是多喝热水。

最近咱们编程导航网站需要去集成一些工具库,而这些工具又是一些独立存在的个体且技术栈不同,我们在想如何能够以最低成本去接入这些工具的功能,因此我们调研了一些主流的微前端框架并进行了实践。

本文将深入探讨微前端应用的架构设计,分析社区中主流的微前端解决方案,并通过实际案例演示如何跑通一个微前端应用~

一、微前端应用的架构?

主应用

微前端需要一个主应用,它负责去调度不同的微应用,相当于是一个应用基座。

微应用

微应用可以有多个,可以是不同技术栈开发的项目,如 Vue.js、React.js、Solid.js 等。

二、社区微前端的解决方案

1、无界

腾讯在维护的,后起之秀,非常轻量,3k star,无痛接入 vite,对比下来个人比较喜欢的一种微前端方案。

无界的运行模式

此图为无界官方文档的运行模式图

file_1710405791889_432.png

跑通一个案例

1)第一步安装主应用基座,执行如下图命令:

image.png

2)第二步初始化package.json文件并基于 pnpm 配置 monorepo 架构(详细文档移步从理解软/硬链接掌握PNPM),如下:

image.png

3)编写 pnpm-workspace.yaml 文件,如下:

packages: - 'main' # main目录下的packge.json需要安装 - 'packages/**' #packages目录下的所有项目的package.json需要安装

4)创建多个微应用,如下:

image.png

image.png

4)安装无界并将所有微应用关联起来

无界对于Nodejs的版本有要求,需要Nodejs > v18,参考此处文档无界

在主应用安装wujie-vue3(同时会把我们主/微应用所需要的所有依赖的都安装完),这个是作者封装的组件,可以减少用户配置的成本,如下:

image.png

此时我们的目录是这样的,node_modules中只保留最核心的包,一些辅助用的包,如Babel会被提升到最外层的node_modules,如下:

image.png

5)在主应用中注册无界组件,如下:

image.png

6)启动主应用和所有微应用

这里我们可以给最外层的package.json配置一下scripts脚本,避免每次都需要进入packages文件夹启动微应用,配置完成依次启动,如下:

image.png

image.png

7)启动后在主应用中引入对应的微应用

image.png

8)完成启动

image.png

总结

从跑通这个案例来看,无界的接入非常简单轻量,且完全支持 vite(这是其他微前端框架没有的)

简单了解一下原理

1)CSS 隔离:使用 shadowDOM 隔离

2)JS 隔离:使用一个空的 iFrame 隔离

3)多应用通讯:使用 Proxy

2、qiankun

该框架是蚂蚁在维护的,15k star,目前官方使用的是 webpack 作为构建工具,没有明确表示支持 vite,社区有 vite-plugin-qiankun 插件支持,但是配置起来还是有一定的心智负担,且可能存在不确定的问题,故此处使用webpack进行演示。

跑通一个案例

1)创建主应用(这次我们使用create-react-app来创建基于react的主应用)

image.png

2)配置monorepo架构(与无界中一致,这里不再赘述)

3)创建微应用(这里我们统一都使用 webpack 作为构建工具)

首先我们安装一下 vue/cli,如下:

image.png

再创建一个基于vue/cli的微应用,如下:

image.png

4)在主应用中注册微应用

import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'vue app', entry: '//localhost:7100', container: '#vueapp', activeRule: '/vueapp', }, ]); start();

在主应用中配置微应用的显示位置,如下:

image.png

5)配置微应用,根据文档所述,我们需要在微应用的入口导出对应的生命周期钩子给到qiankun在合适的时机调用,且需要根据不同的运行时设置不同的publicPath,参考此处文档 项目实践 - qiankun

第一步,在微应用入口文件的同级目录下创建一个public-path.js文件,并写入如下内容:

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

第二步,在微应用的package.json中加入如下声明,告诉 eslint 这个 webpack_public_path 全局变量时存在的,不要抛出错误,如下:

"eslintConfig": { ... "globals": { "__webpack_public_path__": true }, ... },

第三步,在微应用入口文件抛出生命周期钩子函数给到qiankun调用,如下:

import "./public-path"; import { createApp } from "vue"; import App from "./App.vue"; let instance = null; function render(props = {}) { const { container } = props; createApp(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?.unmount(); instance.$el.innerHTML = ""; instance = null; }

第四步,在vue.config.js文件中配置微应用的打包方式,并配置跨域【重要】

const { defineConfig } = require("@vue/cli-service"); const { name } = require("./package"); module.exports = defineConfig({ transpileDependencies: true, devServer: { headers: { "Access-Control-Allow-Origin": "*", }, }, configureWebpack: { output: { library: `${name}-[name]`, libraryTarget: "umd", // 把微应用打包成 umd 库格式 chunkLoadingGlobal: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal }, }, });

6)启动微应用和主应用

image.png

7)访问/vue-app 路由成功渲染微应用

image.png

总结

1)配置比较繁琐,个人感觉需要用户去配置的东西太多了,单从启动一个微前端应用来说,确实没有无界方便

2)暂时无法支持 vite 作为开发服务器,只能使用 webpack,接入相对比较重

3、两者实现原理对比(拓展)

参考文章:https://juejin.cn/post/7221366548077707321

4、两者优缺点对比


三、对微前端的一些看法

什么时候需要用到它?

1)不同项目使用的技术栈不同,想将它们组合到一起

2)为了解决项目代码组织问题,而不是性能问题

一个使用场景

假如我有一个系统是用 jQuery + PHP 写的,但是它已经在线上稳定运行了好几年的时间,而现在需要在这个系统上加一些新需求,但是碍于技术栈过于老旧而导致开发效率低下,想使用新的技术栈来开发(如Vue.js、React.js),重构又浪费时间和人力,那这个时候就可以考虑接入微前端,把旧系统作为一个微应用,新的业务逻辑重开一个项目写(也是一个微应用),这样我们使用最小的成本提升了开发效率。

优点

1)老旧技术栈项目也能平滑迁移至新的技术栈,提升项目的可扩展性

2)主应用不限制接入应用的技术栈,微应用可以自主选择技术栈

3)独立部署,降低一个前端应用每次部署涉及的范围,一定程度上减少了项目风险

缺点

1)应用拆分的越小,架构就会变得复杂、维护成本就会变高

2)技术栈多样化,同时也意味着技术栈混乱(但一般也不会超过2种以上?)

四、其他补充

micro-app

star 5k,也是一个微前端框架,京东推出,micro-app 的接入和wujie的步骤一致,仅仅只是将 wujie-vue3 换成了 @micro-zoe/micro-app

如下所示:

import { createApp } from "vue"; import "./style.css"; import App from "./App.vue"; import microApp from "@micro-zoe/micro-app"; createApp(App).mount("#app"); microApp.start();

注意:在主应用中如果子应用是采用vite接入,那么需要使用 iframe, 官方的解释

<template> <micro-app url="http://localhost:5173" height="500px" name="vue-app" iframe></micro-app> <micro-app url="http://localhost:5174" height="500px" name="react-app" iframe></micro-app> </template>

否则你可能会看到如下错误:

image.png

五、最后

大家还知道有哪些微前端框架可以在评论区讨论~

#前端# #技术# #系统设计#

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP