微前端中的微模块概念与实现

3,575 阅读3分钟

微前端

目前前端行业,微前端概念特别火,为什么了?个人理解主要是解决目前大型团队在开发一个大项目的时候遇到的一些痛点:

一个中后台系统会有很多业务线,由于受微服务架构的影响,每个业务线其实都是由一个小团队负责(可以参考DDD,哈哈,码农我虽然没具体学习过这种很抽象的东西,但是发现这个理念的实践其实就在身边),这个小团队人员很齐全,包括产品、测试、后端、前端都有,这样业务系统就可以独立运行,但是用户(使用系统的人员)在使用时,前端不会单独为每一个业务系统就设置一个入口,都是聚合在一块形成一个大的平台体系提供给用户,这个平台和每个业务系统的关系,就是微前端诞生的原因,这里不说iframe这种设计,因为本人很抗拒,比较推崇的是蚂蚁开源的qiankun,有兴趣大家可以去研究一下,里面的代理和快照值得学习(赞),说了这么多,那么我们的微模块扮演什么角色呢?

其实微前端应该分为:

  • 微应用
  • 微模块

这个是参考single-spa的,哈哈,包括qiankun都是基于single-spa,在微应用这块,我这里就不多说,因为网上有很多这方面的实践,就不凑热闹了,通俗一点理解微应用和微模块,微应用就是会根据路由的变化去加载不通的模块;而微模块呢,就是不依赖路由呗,根据业务的需要加载不同的模块,其实可以理解成组件,而且这个组件抹平了技术栈不同给开发人员带来的影响,不废话,看一下我的实践。

子模块

这里子模块的实现其实和qiankun里面子应用的设计相同,为什么我就不解释了,展示一个react组件入口模型

import React from 'react';
import ReactDOM from 'react-dom';
import ComponentDemo from './ComponentDemo';

export async function bootstrap() {
  console.log('react component bootstraped');
}

export async function mount(props) {
// 这里的props.domElement是固定的挂载属性,别乱写
  return new Promise(resolve => {
    ReactDOM.render(<ComponentDemo
        microParcelName={props.microParcelName}
        changeFn={props.changeFn}/>,
    props.domElement, () => {
      resolve()
    });
  })
}

export async function unmount(props) {
  ReactDOM.unmountComponentAtNode(props.domElement);
}

微模块如何使用

这里展示一个vue框架的项目如何使用子模块

<template>
    <div>
    /* 业务代码不写了*/
    <MicroParcelLoader
        :parcelProps="parcelProps"
        parcelTag="div"
        :url="[
        '【这里是子模块的cdn路由】.js',
        '【这里是子模块的cdn路由】.css',
        ]"></MicroParcelLoader>
    </div>
</template>
<script>
import MicroParcelLoader from 'micro-parcel-loader/lib/vue'
// 如果是react项目需要引用
// import MicroParcelLoader from 'micro-parcel-loader/lib/react'
export default {
    data() {
        return {
            parcelProps: {
                microParcelName: '简单的微模块',
                changeFn: this.changeFn
            }
        }
    },
    components: {
        MicroParcelLoader
    },
    methods: {
        changeFn() {
          this.parcelProps.microParcelName = Math.random()
        },
    }
}
</script>

上面使用到micro-parcel-loader这个npm库,其实网上应该没有,因为我没发,但是坑我占了,嘿嘿,主要考虑到公司的规章制度。

至于这个micro-parcel-loader实现,说一下原理,针对不同技术栈的项目应该引入相对应的模块,这里目前有两个(micro-parcel-loader/lib/vue)(micro-parcel-loader/lib/react),为什么要这样,这是为了解决不同技术栈组件加载和通信的实现,我们还会重新定义一下生命周期钩子,上面示例没有写,然后就是子模块的加载了,这里使用systemjs.import方法载入,并将运行完毕的子模块的真实DOM挂载到业务项目的节点上,上面的子模块示例mount钩子里就可以看出来,所以子模块不需要考虑技术栈问题,按照规范改造就行。

结束

首先感谢大家百忙之中看我写的文章,写的比较烂,真的非常感谢!!!