0
点赞
收藏
分享

微信扫一扫

微前端的不断探索之路(二)—— qiankun

一、实践是检验真理的唯一标准

确定了三个可选框架,接下来就要开始尝试了,实践是检验真理的唯一标准,只有真正使用一下,才能体会到其中的异同,才能更好的选择一款合适自己的框架。

微前端的不断探索之路(二)—— qiankun _qiankun

1、选型的考虑因素

首先把需要考虑的因素列一下:

  • 易上手:因为时间周期较短,需要选择一款上手难度不高,封装较好的框架,这样才可以在前期的准备工作花费较少的时间,为后面写自己的业务逻辑腾出时间
  • 易扩展:虽然与第一点可能存在一些矛盾,但是却也是十分重要的,因为不可能存在一款完全适合我们需求的开源产品,所以,定制化开发是一定要的,并且也要做好后期修改源码的可能。
  • 稳定:框架要求一定要稳定,因为微前端,必然是作为前端子应用的载体,是基座,如果基座本身都不够稳定强大,那后面所有都不能保证。
  • 社区良好,项目活跃:为了保证以上三点的技术需求,就要保证这一点,才不至于走到死胡同。

2、确定技术栈

采用 vite + vue3 + elementPlus 作为整个核心的技术栈:

  • vite + vue3 + elementPlus 作为基座应用,即父应用
  • vite + vue3 + elementPlus 作为最佳推荐子应用
  • 要支持 原生 h5+css3 子应用支持
  • 要支持 angular 子应用支持
  • 要支持子应用使用 iframe 组件

3、qiankun 试用

i、创建两个个基础模板工程、一个作为主应用、一个作为子应用,我这里使用了vue-cli 构建的 vue3+vite 模板工程

微前端的不断探索之路(二)—— qiankun _vite_02

附:豆包:如何用vue-cli3 生成一个 vite+vue3 项目

  1. 安装 Vue CLI 3(如果尚未安装)
  • 首先,确保已经安装了 Node.js。Vue CLI 3 需要 Node.js 环境。可以从 Node.js 官方网站(https://nodejs.org/)下载并安装适合你操作系统的版本。
  • 打开终端(命令提示符),使用以下命令安装 Vue CLI 3:

npm install -g @vue/cli

  • 安装完成后,可以通过vue --version命令来检查 Vue CLI 的版本。
  1. 创建项目
  • 使用 Vue CLI 3 创建项目,在终端中运行以下命令:

vue create my - vite - vue3 - project

  • 这里my - vite - vue3 - project是你的项目名称,可以根据自己的喜好进行修改。
  • 在创建项目的过程中,会出现一个交互式的命令行界面,让你选择一些项目配置。选择手动选择特性(Manually select features)。
  1. 选择特性
  • 在特性选择界面,需要选择以下特性:
  • Babel:用于将 ES6 + 代码转换为浏览器兼容的 JavaScript 代码。
  • CSS Pre - processors:用于处理 CSS 预处理器,如 Sass、Less 等。
  • Linter/Formatter:用于代码检查和格式化,帮助保持代码风格的一致性。
  • 取消选择TypeScript(如果不需要 TypeScript 支持),因为 Vite 本身对 JavaScript 和 TypeScript 都有很好的支持,这里主要关注 JavaScript 和 Vue 3 的组合。
  1. 配置 CSS 预处理器(可选)
  • 如果选择了 CSS Pre - processors 特性,会提示你选择一个 CSS 预处理器。Sass(包括 SCSS 语法)是一个很受欢迎的选择。
  1. 配置 Linter/Formatter(可选)
  • 对于 Linter/Formatter,可以选择 ESLint + Prettier 的组合,以获得更好的代码检查和格式化效果。配置相关规则,如代码缩进、变量命名等规则,以符合你的团队或个人的编码风格。
  1. 修改项目配置为 Vite
  • 安装 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"
}


  1. 调整项目结构(可选)
  • 根据 Vite 的最佳实践,可能需要对项目的文件结构进行一些微调。例如,将public目录下的一些静态资源按照 Vite 的推荐方式进行组织。
  1. 运行项目
  • 在终端中,运行npm run serve,Vite 会启动一个开发服务器,并且可以在浏览器中访问项目,默认地址是http://localhost:3000


通过以上步骤,就可以使用 Vue CLI 3 为基础,构建一个基于 Vite + Vue 3 的项目。不过在实际操作过程中,可能会根据项目的具体需求进行更多的配置和调整。

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、运行查看效果

微前端的不断探索之路(二)—— qiankun _微前端_03

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》

二、理论要结合实际

见 《微前端的不断探索之路(五)—— 技术选型与扩展规划》

三、最终选型

见 《微前端的不断探索之路(五)—— 技术选型与扩展规划》

举报

相关推荐

0 条评论