前端微应用:前端大应用拆分为多个小应用(?前端 nginx?)

3,078 阅读4分钟

原文:www.yuque.com/xiezhongfu/…

single-spa 框架你值得研究,源码也比较简单:www.yuque.com/xiezhongfu/…

到底要不要微前端改造:mp.weixin.qq.com/s/ndNzkf1Gv…

隔离不同时期的代码: 你有一个大型单页面应用程序(SPA),参与开发的人来来往往比较多,多个迭代后业务代码的差异比较明显,应用的维护的成本比较高。
多个 spa 应用在一个上层 spa 中运行: 多个小 SPA 应用 独立运行太浪费,合在一起给打包和编译带来风险(一个应用出现问题导致整个前端应用运转不起来)。
三大框架共存于一个应用: 可以实现 react, vue, angular 共存在一个应用里吗?比如你前端写了好多 vue 组件,你想直接用在 react 体系里怎么办呢?single-spa 框架了解下:www.yuque.com/xiezhongfu/…

天下大事合久必分。除了可以使用ES2015模块,webpack和npm对代码进行模块化,还可以引入新的独立SPA,每个SPA独立开发或部署——这就是在前端成功引入了面向服务的架构(SOA)。

?前端 nginx?

react 应用中,router 可以分发到不同的页面。前端 historty 也可以做到分发到不同的子应用。
这种技术方案其实对后端同学来讲已经很常见了,比如 nginx。

面向服务的架构

面向服务的架构基本概念是服务,服务是一段孤立的代码,只能通过 API 进行交互,服务可以独立开发/部署,这些服务之间是隔离的,是独立的。 服务的概念需要和共享库的概念区分下。共享库是编译打包代码绑在一起,比如前端的 react库等,升级共享库必须重复发版到 npm 仓库。

前端为什么需要面向服务

业务场景举例

  • 前端业务模块 A(后台系统A)
  • 前端业务模块 B(后台系统B)
  • 前端业务模块 C(后台系统C)
  • ......

为了隔离不同时期,不同前端业务模块,对接的不同后台应用等,强烈想拆分开(代码拆分)。 面向服务的设计,公共代码不是公共的依赖项,是通过独立的服务,服务只是运行时加载。也正是因为是运行时加载,在应用启动时如果同步加载过多的服务,性能可能会收到影响。在应用启动后异步加载一些服务可以减轻一些负担。

代码拆分

当用户访问到不同路由时,加载对应的代码。随着路由和业务代码的增加,路由可能会变得比较大,每个路由对应的代码也会变得比较大。因此不能只使用基于路由的代码拆分。基于路径的拆分很不错(比如使用动态加载),那如何从单纯的静态加载变成有动态加载的呢?(比如多入口打包后动态加载 后者 独立应用打包)

singe-spa + 单仓库

拆分完后基于 history 怎么管理?singe-spa 源码分析参见:www.yuque.com/xiezhongfu/…
单仓库的实践可以参看 react 源码仓库对多个 package 的管理。把不同业务模块放到不同的 package 管理。每一个 package 是可以单独运行和部署的。

关联的技术

更多内容参考:mp.weixin.qq.com/s/6-yjR_CsH…

关键技术

  • JS 沙箱和 CSS 隔离,是为了让子应用之间互不影响。
  • Html Entry 和 Config Entry,是关于如何注册子应用信息。
  • 按需加载、公共依赖加载和预加载,是关于性能的,这些很重要,否则虽然上了微前端,但性能严重下降,或者由于升级引起线上故障,就得不偿失了。
  • 父子应用通讯,顾名思义,无需解释。
  • 子应用嵌套 和 子应用并行 是微前端的进阶应用,在某些场景下会用到。

关键技术实现
这是部分问题的实现原理。

  • 首先子应用提供样式、脚本等配置,有内联也有外链。
  • 先通过 SEMVER MAP 解决公共依赖不重复加载的问题,比如 antd、react 都只载一份。
  • 然后通过 xhr 拉外链的样式和脚本,实现按需加载。
  • 样式会合并成一份,通过 style 写入到 DOM 结构,子应用 unmout 时删除,以此做到 CSS 隔离。
  • 脚本通过记录和 diff window 变量上的属性来取到子应用导出的生命周期方法,然后通过 eval + 基于 Proxy 实现的 Sandbox 实现 JS 沙箱。

参考