查看原文
其他

【第1899期】调研 Federated Modules,应用秒开,应用集方案,微前端加载方案改进等

云谦 前端早读课 2020-10-15

前言

Federated Modules,Webpack 5的一个功能,可以期待一下。今日早读文章由蚂蚁金服@云谦授权分享。

正文从这开始~~

昨天看到的,好久没看到这么令人心动的功能了,感觉可能会改变未来几年的打包方式。同时可以解一些我们目前面临的问题,比如编译提速,应用集群方案,微前端方案改进。

是什么?

大家可以先看下这篇文章(https://www.bram.us/2020/03/12/introducing-federated-modules-in-webpack-5/)中的视频,解释地很清楚。

我的理解,

  • Webpack 5 的新特性,允许在多个 webpack 编译产物之间共享模块、依赖、页面甚至应用

  • 提供了一种轻量级的运行时,通过全局变量组合,有种之前用 seajs 的感觉

  • 提供了一种解决应用集的官方方案

应用场景

看到的介绍文章里更多说的是在微前端方面的加载改进,我结合我们遇到问题说下我想到的应用场景。

  • 编译提速,秒开(10 s 内)

Shared library

感觉之前想做的 Bundlerless 一下子没那么重要了。

试验了一把 react + react-dom + antd,remote 外部依赖全部 remote 掉,1.59s 完成编译。

示例仓库:https://github.com/sorrycc/test-federated-modules

先拆了一个应用专门做依赖打包,把 react, react-dom 和 antd 打进去;另一个应用使用这些依赖的时候配 remote,不做实际打包,通过 runtime 的方式引之前打包好的文件。

和 external 的区别?
  • external 需要自行在 html 引入相关 script,此方案只需引一个 runtime 文件,runtime 里维护了 chunk 的映射表

  • external 需要自行处理库的依赖,比如 antd 依赖 moment,那么就需要分别引 moment 和 antd 的 umd 文件,并且保证顺序

  • external 没法拆包,比如 antd 只能引一个大的 antd,此方案可以拆,比如只用了 Button,可以不引整个 antd

此外,

  • 结合平台可以做一些自动化的事情,可以发挥更大价值。比如自动把我们的常用依赖定期打包,然后大家不管是开发环境还是生产环境都依赖统一的 runtime。打包可以是打大包,比如 ant-design-pro 可以把相关的;也可以是打小包,然后利用 cdn 的 combo 机制合到一起,如果是打小包,大量重复的 runtime 合一起还是有点大,需要提下

  • Umi 内置的开发依赖比如 socket.io、webpack-hot-middleware、@babel/runtime、core-js 等也可以提前打出来通过 runtime 的方式引入

  • 和此前大量利用缓存的方案不同,不是二次编译快,而是首次编译就快

  • 可以支持多版本,比如同时有 antd 3 和 antd 4

  • codesandbox 之前做过 webpack dll 的 cdn,我觉得和这个的思路很像,常用依赖全部上 cdn,项目开发只打包本地依赖

  • 借助 http/2(现在的 cdn 基本都是了),性能不一定受影响,可能因为整体尺寸小了而变得更好了

  • 有 library cdn 后,Bundlerless 更容易做了

  • 在中后台这种不太介意整体尺寸的场景更容易快步推进,但性能问题可解

说下缺点,主要是引入的方式需要改成异步,比如:

  1. - importReactfrom'react';

  2. + constReact= awaitimport('libs/react');

所以,对于某些依赖来说 external (比如 react 和 react-dom)可能更合适,但也有一些自动化的方式可以系统地解决此问题,使用此方案的同时并既然使用老的写法,比如:

  • 渲染前通过先挂载 react 和 react-dom

  • 通过 babel 插件的方式自动编译

总之,终极目标就是让时可以只编译项目代码,依赖全部通过 runtime 的方式引入。

应用集方案

Shared component, library, page, subapp

应用集不一定是微前端方案。

一个应用集之前会有很多的共享,比如:

  • 依赖共享

  • 一个应用依赖另一应用的组件

  • 一个应用依赖另一应用的页面

  • 一个应用依赖另一应用

之前的微前端方案需要提一个中心主应用,而这个方案不一定要有中心主应用,应用之间可以直接共享 chunk,当然也可以提一个虚拟不对外的应用,只做模块的生产,供其他应用消费。

注:只适用于分开独立打包发布的应用集,如果是合在一起打包发布,用 monorepo 更合适。

微前端方案改进

Federated Modules 对于微前端而言,在加载策略上也能有一些改进。

之前画的这张微前端需要解决的问题的图里,

最下面的 “公共依赖加载” 一直是没有非常优雅的方案,比如 A 应用依赖 antd4,B 应用依赖 antd3,C 应用也依赖 antd3,如何让 B 和 C 的 antd3 不重复打包和加载。借助 Federated Modules 可以比较好地解决此问题。

参考

  • https://www.bram.us/2020/03/12/introducing-federated-modules-in-webpack-5/

  • https://indepth.dev/webpack-5-module-federation-a-game-changer-in-javascript-architecture/

  • https://zhuanlan.zhihu.com/p/115403616

  • https://github.com/mizx/mfe-webpack-demo

  • https://github.com/module-federation

  • https://github.com/sorrycc/test-federated-modules

关于本文 作者:@云谦 原文:https://mp.weixin.qq.com/s/WAYezuzMKJjn3SECiy1KVA

@云谦曾分享过


发布 UMI 3,插件化的企业级前端应用框架


【第1783期】蚂蚁前端研发最佳实践


【PPT】umi架构、生态和未来


为你推荐


【第1260期】图说 ES Modules


【第1887期】Async Generators 作为状态管理的替代方案


【第1087期】TypeScript体系调研报告

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存