IT资讯 Fes.js 微前端,轻松拿捏巨石应用新需求~

jadon · 2021-08-12 11:30:06 · 热度: 65

巨石应用,往往技术古老、逻辑耦合、性能较差、体验欠佳,再加上前期对系统定位不清晰,积年累月,包袱越来越重,一个很小的改动就可能牵一发而动全身,让人望而却步。而近期的开发任务都是在"巨石应用"上新增需求,然后就探到宝藏: Fes.js 微前端.

什么是微前端?为什么使用微前端?这些问题有很多文章都可深扒,这里就不赘述啦~本文我们主要扒一扒 Fes.js 微前端。先简单唠下 Fes.js 和微前端的关系: Fes.js 是一个前端应用解决方案,以 Vue 3.0 和路由为基础,覆盖编译时、运行时生命周期完善的的插件体系,支持各种功能扩展和业务需求;Fes.js 通过 @fesjs/plugin-qiankun 插件扩展了微前端,除了常规微前端功能,还提供了 复杂场景加载、样式隔离、最佳通讯 等进阶功能。

近期陆陆续续基于 Fes.js 微前端实现了几个巨石应用的新增需求,总结一下这么去玩的流程和推荐方案~对于老项目使用 Fes.js 微前端如何迁移,可以扒一扒 这篇 文章。

1.如何规划微应用、主应用

通常拿到新需求,做需求拆分时,我们就会根据需求的独立性、可复用性、使用场景和项目现技术栈几个角度考虑是否可以用、需要用微前端实现。那对于使用微前端实现的项目,一般规划如下:

代码库及结构

主应用、微应用各自独立的代码库。通常,微应用代码库建议以主应用代码库-micro命名。

  • 简单微应用:微应用代码库内部的 src/pages/ 下每个文件为一个独立微应用。
  • 复杂/通用微应用:如果一个微应用需要被多个主应用引用,且多个主应用之间数据处理差异较大,一个更好的处理方式是在 src/pages/ 下根据主应用创建不同的微应用路由入口,并在路由入口处抹平数据差异,最后统一在 src/components/ 通用组件处理相同逻辑。

Fes.js 微前端,轻松拿捏巨石应用新需求~

技术栈

微前端的核心是技术栈无关,微应用、主应用使用自己的技术栈独立开发。

  • 微应用: Fes.js、Vue3、UI 组件库自选(Fes UI 敬请期待中~)
  • 主应用: 老项目原有技术栈无需变更,新项目推荐 Fes.js 。

微应用接入主应用

  • 由于技术栈无关,所以微应用接入是一个协议接入。微应用不需要额外安装任何其他依赖,只需要在自己的入口 js 导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。

主应用加载微应用

  • 基于 Fes.js 的主应用: 按照 @fesjs/plugin-qiankun 指引配置加载微应用即可。
  • 其他技术栈的主应用: 在主应用安装 qiankun 插件,通过 loadMicroApp() API 加载微应用。

打包、部署、更新

  • 打包: 主应用、微应用各自独立打包,完全解耦。
  • 部署: 主应用、微应用各自独立部署,互不影响,更有利于独立迭代。
  • 更新: 主应用、微应用各自独立更新。对于仅涉及微应用的更新,微应用部署完成后(所有引用它的)主应用自动完成同步更新。

2.微应用相关

基于 Fes.js 如何开发微应用,官方文档和上面 ???? 文章都有写,十分清楚啦~这里着重讨论一下关于微应用的样式隔离,这趴我们内部项目是踩了一些坑的,也讨论过最佳实践,这里完整总结一下。

微应用样式隔离最佳实践

1. qiankun Shadow DOM:

qiankun 会为每个微应用的容器包裹上一个 shadow dom 节点,从而确保微应用的样式不会对全局造成影响。Shadow DOM 大部分情况下都需要主应用做一些适配后才能正常在 Shadow DOM 中运行起来。需要适配的点跟项目相关联,很具有未知性,成本较大!

2. qiankun experimentalStyleIsolation: true

当 experimentalStyleIsolation 设置为 true 时,编译后会给微应用的 最外层容器 添加一个特殊选择器,并将这个特殊选择器添加到所有样式规则上,来限定微应用样式影响范围。无法解决“主应用与微应用有同名选择器”情况下的样式污染。

3. BEM

通过一些 约定 (如统一加微应用前缀) 来避免冲突,比较有效的方案。强依赖约定。

4. scoped CSS【推荐】

scoped 的原理是生成一个 data-v-[hash] 形式的data属性选择器作为唯一标识,在编译后生成的每句 css 选择器的末尾加一个当前元素的"data属性选择器"来私有化样式。这样局部样式可以做到极大程度上避免样式冲突,但也无法解决方案2的问题。

5. css Module【推荐】

css Module 会根据 文件名+类名+hash 生成一个唯一标识,然后直接替换掉原类名,比 scoped 更为彻底。这样只要不直接通过标签选择器去修改样式,基本可以做到完全避免冲突。当前 css module 已经是非常成熟一种做法,通过在构建 工具 里加一些 css 预处理器即可实现。如果是基于 Fes.js 的微应用,则更无需关心任何额外配置,直接在代码里面使用即可,其他工序都暗戳戳帮你搞定啦~

Fes.js 微前端,轻松拿捏巨石应用新需求~

Fes.js 微前端,轻松拿捏巨石应用新需求~

3.主应用相关

主应用相关的主要讲一下 如何加载、如何通讯 两个方面。

主应用如何加载微应用?

在主应用加载微应用,在主应用封装一个 microCommon 组件, 来统一处理加载、通讯、微应用 unmount 等逻辑,然后在主应用按需引入 microCommon。以一个基于 vue2 的主应用为例,通过上面【主应用加载微应用】第2种类型接入微应用。

1. 实现 microCommon.vue 组件

<template>
    <div></div>
</template>
复制代码
import { loadMicroApp } from 'qiankun';
export default {
    props: {
        microName: String,
        microContainer: String,
        microEntry: String,
        microPropsUrl: String
    },
    data() {
        return {
            microApp: null
        };
    },
    mounted() {
        this.microApp = loadMicroApp({
            name: this.microName,
            container: `#${this.microContainer}`,
            entry: `${this.microEntry}`,
            props: {
                url: this.microPropsUrl
            }
        });
    },
    async beforeDestroy() {
        if (this.microApp) {
            const status = this.microApp.getStatus();
            if (status === 'MOUNTED') await this.microApp.unmount();
        }
        return Promise.resolve();
    }
};
复制代码

2. 主应用引用 microCommon 组件:

<template>
    <div id="materialManage_materialEditing">
        <micro-common
            :microName="'materialManageEditing'"
            :microContainer="'materialManage_materialEditing'"
            :microEntry="'/s/web-mas-micro/'"
            :microPropsUrl="'/materialManage/materialEditing'"
        ></micro-common>
    </div>
</template>
复制代码
import MicroCommon from '@/components/microCommon';
export default {
    components: {
        MicroCommon
    }
};
复制代码

主应用如何与微应用通讯?

1. 基于 props 通讯

在 qiankuan loadMicroApp API 有详细关于 props 传参的示例,并结合 initGlobalState API 实现传递数据的更新和管理。除了参数,方法也可以通过 props 传入微应用使用。

2. Fes.js 最佳实践:基于 useModel 通讯

基于该通讯方式,子应用获取 props 的方法是相同的,子应用中会自动生成一个全局名为 qiankunStateFromMain 的 model,可以在任意组件中获取主应用传递的 props 的值。主应用的传递 props 方式有所差异:

  • 基于 Fes.js 的主应用:按照 @fesjs/plugin-qiankun 文档指引区分不同微应用引入方式传递 props。
  • 其他技术栈的主应用:通过 loadMicroApp API 传递 props。
 

作者:tian_xuan
 fes.js 社区微信:geniusWanc
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册