一、实践是检验真理的唯一标准
确定了三个可选框架,接下来就要开始尝试了,实践是检验真理的唯一标准,只有真正使用一下,才能体会到其中的异同,才能更好的选择一款合适自己的框架。
1、选型的考虑因素
首先把需要考虑的因素列一下:
- 易上手:因为时间周期较短,需要选择一款上手难度不高,封装较好的框架,这样才可以在前期的准备工作花费较少的时间,为后面写自己的业务逻辑腾出时间
- 易扩展:虽然与第一点可能存在一些矛盾,但是却也是十分重要的,因为不可能存在一款完全适合我们需求的开源产品,所以,定制化开发是一定要的,并且也要做好后期修改源码的可能。
- 稳定:框架要求一定要稳定,因为微前端,必然是作为前端子应用的载体,是基座,如果基座本身都不够稳定强大,那后面所有都不能保证。
- 社区良好,项目活跃:为了保证以上三点的技术需求,就要保证这一点,才不至于走到死胡同。
2、确定技术栈
采用 vite + vue3 + elementPlus 作为整个核心的技术栈:
- vite + vue3 + elementPlus 作为基座应用,即父应用
- vite + vue3 + elementPlus 作为最佳推荐子应用
- 要支持 原生 h5+css3 子应用支持
- 要支持 angular 子应用支持
- 要支持子应用使用 iframe 组件
3、qiankun 试用
i、创建两个个基础模板工程、一个作为主应用、一个作为子应用,我这里使用了vue-cli 构建的 vue3+vite 模板工程
附:豆包:如何用vue-cli3 生成一个 vite+vue3 项目
- 首先,确保已经安装了 Node.js。Vue CLI 3 需要 Node.js 环境。可以从 Node.js 官方网站(https://nodejs.org/)下载并安装适合你操作系统的版本。
- 打开终端(命令提示符),使用以下命令安装 Vue CLI 3:
npm install -g @vue/cli
- 安装完成后,可以通过
vue --version
命令来检查 Vue CLI 的版本。
- 使用 Vue CLI 3 创建项目,在终端中运行以下命令:
vue create my - vite - vue3 - project
- 这里
my - vite - vue3 - project
是你的项目名称,可以根据自己的喜好进行修改。 - 在创建项目的过程中,会出现一个交互式的命令行界面,让你选择一些项目配置。选择手动选择特性(Manually select features)。
- 在特性选择界面,需要选择以下特性:
- Babel:用于将 ES6 + 代码转换为浏览器兼容的 JavaScript 代码。
- CSS Pre - processors:用于处理 CSS 预处理器,如 Sass、Less 等。
- Linter/Formatter:用于代码检查和格式化,帮助保持代码风格的一致性。
- 取消选择TypeScript(如果不需要 TypeScript 支持),因为 Vite 本身对 JavaScript 和 TypeScript 都有很好的支持,这里主要关注 JavaScript 和 Vue 3 的组合。
- 如果选择了 CSS Pre - processors 特性,会提示你选择一个 CSS 预处理器。Sass(包括 SCSS 语法)是一个很受欢迎的选择。
- 对于 Linter/Formatter,可以选择 ESLint + Prettier 的组合,以获得更好的代码检查和格式化效果。配置相关规则,如代码缩进、变量命名等规则,以符合你的团队或个人的编码风格。
- 安装 Vite 相关依赖:
- 进入项目目录:
cd my - vite - vue3 - project
。 - 安装 Vite 和相关的 Vue 3 插件:
npm install vite @vitejs/plugin - vue -compat
- 创建
vite.config.js
文件:
- 在项目根目录下创建
vite.config.js
文件,内容如下:
- 修改
package.json
文件中的启动脚本:
- 将
"serve"
脚本修改为使用 Vite 启动,例如:
"scripts": {
"serve": "vite",
"build": "vite build",
"lint": "eslint --ext.js,.vue src"
}
- 根据 Vite 的最佳实践,可能需要对项目的文件结构进行一些微调。例如,将
public
目录下的一些静态资源按照 Vite 的推荐方式进行组织。
- 在终端中,运行
npm run serve
,Vite 会启动一个开发服务器,并且可以在浏览器中访问项目,默认地址是http://localhost:3000
。
ii、下载依赖
在主应用中,添加 qiankun 需要的依赖
yarn add qiankun # 或者 npm i qiankun -S
iii、主应用注册
在主应用的 main.ts 中(也可以是其他文件,看你的需求),引入qiankun提供的一些api,并按照格式注册你的子应用地址
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
import { registerMicroApps, start, addGlobalUncaughtErrorHandler } from 'qiankun';
// 注册应用
registerMicroApps([
{
name: 'vue app',
entry: '//localhost:5174/',
container: '#vuecontainer',
activeRule: '/vueapp',
props: {
title: '测试传入数据'
}
},
]);
// 启动!
start({
prefetch: 'all',
sandbox: {
experimentalStyleIsolation: true
}
});
addGlobalUncaughtErrorHandler((ev) => {
console.log('异常: ', ev)
})
在你的界面,选择一块地,租给子应用,就是下面那个 <div id="vuecontainer"></div>
<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
<div class="wrapper">
<HelloWorld msg="You did it!" />
</div>
</header>
<div id="vuecontainer"></div>
</template>
<style scoped>
header {
line-height: 1.5;
max-height: 100vh;
}
.logo {
display: block;
margin: 0 auto 2rem;
}
nav {
width: 100%;
font-size: 12px;
text-align: center;
margin-top: 2rem;
}
nav a.router-link-exact-active {
color: var(--color-text);
}
nav a.router-link-exact-active:hover {
background-color: transparent;
}
nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}
nav a:first-of-type {
border: 0;
}
@media (min-width: 1024px) {
header {
display: flex;
place-items: center;
padding-right: calc(var(--section-gap) / 2);
}
.logo {
margin: 0 2rem 0 0;
}
header .wrapper {
display: flex;
place-items: flex-start;
flex-wrap: wrap;
}
nav {
text-align: left;
margin-left: -1rem;
font-size: 1rem;
padding: 1rem 0;
margin-top: 1rem;
}
}
</style>
iv、子应用入口配置
打开子应用,在入口文件main.ts中(这次真的得是他,不能是别人),做微应用相关配置
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { renderWithQiankun, qiankunWindow, type QiankunProps } from 'vite-plugin-qiankun/dist/helper'
import App from './App.vue'
import router from './router'
import { useCounterStore } from './stores/counter'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.use(router)
// app.mount('#app')
const initQiankun = () => {
renderWithQiankun({
bootstrap() {
console.log('bootstrap')
},
mount(props) {
console.log('mount', props)
const useCounter = useCounterStore()
useCounter.setTitle(props.title)
render(props)
},
update(props) {
console.log('update', props)
},
unmount(props) {
console.log('unmount', props)
},
})
}
const render = ({ container }: QiankunProps) => {
const appDom = container ? container : '#app'
app.mount(appDom)
}
qiankunWindow.__POWERED_BY_QIANKUN__ ? initQiankun() : render(null)
v、运行查看效果
vi、分析与总结
总结:其实微前端要实现的需求很简单,不同的系统,不同的技术栈要在同一个页面上不留痕迹的显示出来,让人看不出他们不是同一个项目。而基于这个目的,微前端做了两件事:
- 在主应用中做了注册,主应用应该知道子应用从哪里来
- 子应用重新改了自己的渲染方式,让自己可以根据需要走不同的渲染方式。我们可以简单分析一下子应用main.ts 中的代码,即可猜到一点微前端是怎么做的:
const initQiankun = () => {
renderWithQiankun({
bootstrap() {
console.log('bootstrap')
},
mount(props) {
console.log('mount', props)
const useCounter = useCounterStore()
useCounter.setTitle(props.title)
render(props)
},
update(props) {
console.log('update', props)
},
unmount(props) {
console.log('unmount', props)
},
})
}
const render = ({ container }: QiankunProps) => {
const appDom = container ? container : '#app'
app.mount(appDom)
}
qiankunWindow.__POWERED_BY_QIANKUN__ ? initQiankun() : render(null)
从上面代码可以看出,子应用根据 qiankunWindow.__POWERED_BY_QIANKUN__ 这一变量进行判断当前应用是否在qiankun框架中进行,如果不在,则执行render函数,与普通运行已知;如果在的话,则要根据qiankun给的生命周期函数去实现,qiankun每一个生命钩子要做的内容,最终交由qiankun 框架去渲染他的页面,最重要的就是 mount 挂在阶段,可以看到,在挂在阶段,子应用从框架中获取到props 变量,并给他动态渲染到了页面上。
分析:在本文开篇,就已经论述过,我选型要参考的依据,现在依次分析:
- 易上手:整体来说,Demo难度不是很高,但是需要自行封装的东西过多但是封装程度较低,可能需要自行实现与封装:路由,静态资源,keep-alive 等
- 易扩展:同上点,封装程度较低,扩展程度就很高,但是需要花时间去沉淀
- 稳定:框架出来的比较早,因此较其他框架相对应该稳定
- 社区良好,项目活跃:框架出来的比较早,使用沉淀的比较多,git star 15.9k,可以说很活跃
3、wujie 试用
见 《微前端的不断探索之路(三)—— 无界》
4、microApp 试用
见 《微前端的不断探索之路(四)—— microApp》
二、理论要结合实际
见 《微前端的不断探索之路(五)—— 技术选型与扩展规划》
三、最终选型
见 《微前端的不断探索之路(五)—— 技术选型与扩展规划》