Webpack 5模块联邦会不会引发微前端的革命呢? 本文详解

Webpack 5的模块联邦提供加载部分编译好的代码能力,这个似乎会成为微前端架构的标准实现。

Webpack只是我分享的一小点,我是08年出道的高级前端架构师,有问题或者交流经验可以进我的扣扣裙 519293536 我都会尽力帮大家哦

引言

在当前的微前端实现中,我们需要通过一系列的技巧去实现。正如上图所示,微前端的公共依赖加载目前并没有非常好的实现方案。然后,Webpack 5中的模块联邦将会改变这一现状。

模块联邦可以去依赖一个远程模块,这个依赖会在运行时生效,并不影响编译时。因此,这个远程依赖的模块就可以是一个微前端独立模块。同时,每个独立模块都可以申明公共的依赖库,这样也可以避免独立模块间的依赖包的冗余和冲突。

这篇文章将一步步告诉你如何通过Webpack 5的模块联邦特性来搭建一个微前端应用。这里可以找到源代码

示例

这个例子首先包含一个空壳涵盖两个模块(Home、Flights),这个空壳应用可以按需的加载各个微前端模块。

下面是微前端模块的部分-Flights,这部分其实也可以独立运行。

通过这样的架构可以实现各个模块的独立开发发布,同时有能够按需的进行集成整合。

模块联邦

在过去要实现微前端的架构是非常困难的,尤其是像Webpack这类工具是需要在编译阶段保证全部代码的完整性。懒加载是有可能的,但需要在编译阶段排除掉才行。

在微前端架构下,每个独立模块都需要独立编译打包,并且需要人工引入。大体的代码如下:

import('http://other-microfrontend');
复制代码

这样的实现需要依赖external方式的JavaScript人工引入,在Webpack 5中这一实现方式将会得到改变。

模块联邦背后的原理非常简单:宿主系统通过配置名称来引用远程模块,同时在编译阶段宿主系统是不需要了解远程模块的,仅仅在运行时通过加载远程模块的入口文件来实现。

宿主系统实现

宿主系统用于引入远程模块。这个例子会加载一个远程模块mfe1/component,mfe1是配置的远程模块名,component是其中提供的一个文件。

const rxjs = await import('rxjs');

const container = document.getElementById('container');
const flightsLink = document.getElementById('flights');

rxjs.fromEvent(flightsLink, 'click').subscribe(async _ => {
    const module = await import('mfe1/component');
    const elm = document.createElement(module.elementName);
    […]
    container.appendChild(elm);
});
复制代码

在Webpack配置中,采用ModuleFederationPlugin可以来申明要使用的远程模块信息。

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

[…]

plugins: [
  new ModuleFederationPlugin({
    name: "shell",
    library: { type: "var", name: "shell" },
    remotes: {
      mfe1: "mfe1"
    },
    shared: ["rxjs"]
  })
]
复制代码

这样远程模块mfe1就声明完成了,Webpack在编译阶段就会把mfe1相关的引用都忽略,避免将其进行打包。

在shared中可以定义依赖的公共库,这个例子就是rxjs。这样就可以保证整个应用仅仅会加载rxjs库一次,否则的话公共库会被打包进入宿主应用,同时也会在各个子模块中重复出现。

当然,shared的公共库需要保证是一样的版本。同时,宿主系统需要通过dynamic import的方式进行加载:

import * as rxjs from 'rxjs';
复制代码

远程模块的实现

远程模块也是一个独立系统,这里采用web component方式实现:

class Microfrontend1 extends HTMLElement {

    constructor() {
        super();
        this.attachShadow({ mode: 'open' });
    }

    async connectedCallback() {
        this.shadowRoot.innerHTML = `[…]`;
    }
}

const elementName = 'microfrontend-one';
customElements.define(elementName, Microfrontend1);

export { elementName };
复制代码

当然,你可以采用任何一种前端框架来实现,通用的框架库可以用shared的方式在宿主和远程模块之间实现公用。

在远程模块的Webpack配置中,也需要使用ModuleFederationPlugin,将模块暴露出去。

output: {
      publicPath: "http://localhost:3000/",
      […]
 },
 […]
 plugins: [
    new ModuleFederationPlugin({
      name: "mfe1",
      library: { type: "var", name: "mfe1" },
      filename: "remoteEntry.js",
      exposes: {
        component: "./mfe1/component"
      },
      shared: ["rxjs"]
    })
]
复制代码

name定义了远程模块的配置名称。通过远程模块名称和暴露出来的组件名,宿主就可以远程进行依赖引用:

import('mfe1/component')
复制代码

最后,宿主还需要知道远程模块的url来真正引入。

宿主连接远程模块

宿主系统需要加载远程的入口文件,这个文件是远程模块通过ModuleFederationPlugin打包产生的。

入口文件名定义在filename的配置中,这个例子定义为"remoteEntry.js"。微前端模块的url定义在publicPath属性上。

在宿主系统中引入远程模块入口文件:

<script src="http://localhost:3000/remoteEntry.js"></script>
复制代码

在这个例子中,我们提供了两个系统

  • 宿主系统:地址是localhost:5000,会加载远程模块入口文件
  • 远程模块:地址是localhost:3000,提供了远程模块组件

结论

Webpack 5的模块联邦机制给微前端势必会带来革命性的变化。远程的模块可以独立编译,然后在运行时进行加载,同时还能够定义公共库来避免重复加载。

现在Webpack 5依旧还是beta版本,但我们已经可以预见在不久的将来,模块联邦将成为微前端架构中标准解决方案之一。

觉得我写的不错的话,交个朋友,我是08年出道的高级前端架构师,有问题或者交流经验可以进我的扣扣裙 519293536 我都会尽力帮大家哦
本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理

(0)

相关推荐

  • 超级变变变,动态云组件加载实践

    动态组件可以说在可视化配置系统中常用的组件,也是能够实现可视化中,实现组件的核心要点. ○ 背景 这篇是作者在公司做了活动架构升级后,产出的主文的前导篇,考虑到本文相对独立,因此抽离出单独成文. 题目 ...

  • 如何打造一款标准的JS SDK?

    阿里妹导读:岳鹰全景监控,是阿里UC官方出品的先进移动应用线上监控平台,为开发者及企业提供一套完整的移动应用线上质量监控解决方案.岳鹰WEB前端监控,可实时监控页面性能.JS异常.资源加载异常.API ...

  • 如何搭建一个vue-cli4+webpack移动端框架?本文详解

    简介 这是基于 vue-cli4 实现的移动端框架,其中包含项目常用的配置,组件封装及webpack优化方法,可供快速开发使用. 技术栈:vue-cli4 + webpack4 + vant + ax ...

  • webpack打包首页如何优化及路由懒加载?本文详解

    前言 最近做了一个小型的vue的h5项目,发现在手机上运行的时候,第一次进去的首页比较慢,然后同事提了下可以在生产环境用cdn,于是我尝试了下 生产环境开启cdn 1. 在vue.congfig.js ...

  • Webpack如何打包才能尽可能的缩小体积(详解)

    Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 从图中我们可以看出,Webpack 可以将多种静态资源 js.css ...

  • 图文详解:骨科常用负压封闭引流技术

    负压封闭引流技术(Vacuum Sealing Drainage,VSD)是1992年德国ULM大学Fleischman博士首创发明的.1994年裘华德教授率先将VSD技术引进中国,并创造性地应用于骨 ...

  • 肠道菌群决定心理健康?科研突破引发微生态制药“淘金热”

    Holobiome--一家总部位于美国马萨诸塞州的初创公司,正在以肠道菌群为切入点,寻找自闭症.焦虑症和阿尔茨海默症等多种疾病的治疗方案. 自 2015 年成立以来,在 5 年的时间内,Holobio ...

  • 高中物理90 高分指南:6大模块解题思路详解,原来学霸这样学习

    高中物理想学好为什么这么难!同一道物理题中,可以包含了光学.电学.电磁学等几个知识点.同时做两件事很容易,把两件事都做好就很难了. 高中物理要求我们不仅需要具备严谨的逻辑思维,而且还需要非常细心.物理 ...

  • Python模块详解

    Python模块详解

  • Python运维自动化psutil 模块详解(超级详细)

    psutil 模块 参考官方文档:https://pypi.org/project/psutil/ 一.psutil简介 psutil是一个开源且跨平台(http://code.google.com/ ...

  • 八字时柱时引断法详解

    原创/琴鹤堂易学 常见有易友询问笔者:八字时柱到底作用在哪里? 憾于笔者平时忙碌于给各地朋友算命,一直没有时间综合系统回复大家.趁此霪雨霏霏,静坐一炉香,偷得浮生半日闲,乃得此文,愿与天下有识之士共同 ...