拆分大型 Angular 应用四种策略

Posted phodal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拆分大型 Angular 应用四种策略相关的知识,希望对你有一定的参考价值。

上一个月,我们花了大量的时间设计方案来拆分一个大型的 Angular 应用。从使用 Angular 的 Lazyload 到前端微服务化,进行了一系列的讨论。最后,我们终于有了结果,采用的是 Lazyload 变体:构建时集成代码 的方式。

主要是为了达成以下的设计目标:

  • 构建插件化的 Web 开发平台,满足业务快速变化及分布式多团队并行开发的需求

  • 构建服务化的中间件,搭建高可用及高复用的前端微服务平台

  • 支持前端的独立交付及部署

简单地来说,就是要支持应用插件化开发,以及多团队并行开发。

应用插件化开发,其所要解决的主要问题是:臃肿的大型应用的拆分问题。大型前端应用,在开发的时候要面临大量的遗留代码、不同业务的代码耦合在一起,在线上的时候还要面临加载速度慢,运行效率低的问题。

最后就落在了两个方案上:路由懒加载及其变体与前端微服务化。

前端微服务化:路由懒加载及其变体

路由懒加载,即通过不同的路由来将应用切成不同的代码快,当路由被访问的时候,才加载对应组件。在诸如 Angular、Vue 框架里都可以通过路由 + Webpack 打包的方式来实现。而,不可避免地就会需要一些问题:

难以多团队并行开发,路由拆分就意味着我们仍然是在一个源码库里工作的。也可以尝试拆分成不同的项目,再编译到一起。

每次发布需要重新编译,是的,当我们只是更新一个子模块的代码,我们要重新编译整个应用,再重新发布这个应用。而不能独立地去构建它,再发布它。

统一的 Vendor 版本,统一第三方依赖是一件好事。可问题的关键在于:每当我们添加一个新的依赖,我们可能就需要开会讨论一下。

然而,标准 Route Lazyload 最大的问题就是难以多团队并行开发,这里之所以说的是 “难以” 是因为,还是有办法解决这个问题。在日常的开发中,一个小的团队会一直在一个代码库里开发,而一个大的团队则应该是在不同的代码库里开发。

于是,我们在标准的路由懒加载之上做了一些尝试。

微服务化方案:子应用模式

除了路由懒加载,我们还可以采用子应用模式,即每个应用都是相互独立地。即我们有一个基座工程,当用户点击相应的路由时,我们去加载这个独立 的 Angular 应用;如果是同一个应用下的路由,就不需要重复加载了。而且,这些都可以依赖于浏览器缓存来做。

除了路由懒加载,还可以采用的是类似于 Mooa 的应用嵌入方案。如下是基于 Mooa 框架 + Angular 开发而生成的 html 示例:

 
   
   
 
  1. <app-root _nghost-c0="" ng-version="4.2.0">

  2.  ...

  3.  <app-home _nghost-c2="">

  4.  <app-app1 _nghost-c0="" ng-version="5.2.8" style="display: none;"><nav _ngcontent-c0="" class="navbar"></app-app1>

  5.  <iframe frameborder="" width="100%" height="100%" src="http://localhost:4200/app/help/homeassets/iframe.html" id="help_206547"></iframe>

  6.  </app-home>

  7. </app-root>

Mooa 提供了两种模式,一种是基于 Single-SPA 的实验做的,在同一页面加载、渲染两个 Angular 应用;一种是基于 iFrame 来提供独立的应用容器。

解决了以下的问题:

  • 首页加载速度更快,因为只需要加载首页所需要的功能,而不是所有的依赖。

  • 多个团队并行开发,每个团队里可以独立地在自己的项目里开发。

  • 独立地进行模块化更新,现在我们只需要去单独更新我们的应用,而不需要更新整个完整的应用。

但是,它仍然包含有以下的问题:

  • 重复加载依赖项,即我们在 A 应用中使用到的模块,在 B 应用中也会重新使用到。有一部分可以通过浏览器的缓存来自动解决。

  • 第一次打开对应的应用需要时间,当然预加载可以解决一部分问题。

  • 在非 iframe 模式下运行,会遇到难以预料的第三方依赖冲突。

于是在总结了一系列的讨论之后,我们形成了一系列的对比方案:

方案对比

在这个过程中,我们做了大量的方案设计与对比,便想写一篇文章对比一下之前的结果。先看一下图:

Angular 代码拆分对比

表格对比:

拆分大型 Angular 应用四种策略

详细的介绍如下:

标准 LazyLoad

开发流程:多个团队在同一个代码库里开发,构建时只需要拿这一份代码去部署。

行为:开发、构建、运行一体

适用场景:单一团队,依赖库少、业务单一

LazyLoad 变体 1:构建时集成

开发流程:多个团队在同不同的代码库里开发,在构建时将不同代码库的代码整合到一起,再去构建这个应用。

适用场景:多团队,依赖库少、业务单一

变体-构建时集成:开发分离,构建时集成,运行一体

LazyLoad 变体 2:构建后集成

开发流程:多个团队在同不同的代码库里开发,在构建时将编译成不同的几份代码,运行时会通过懒加载合并到一起。

适用场景:多团队,依赖库少、业务单一

变体-构建后集成:开发分离,构建分离,运行一体

前端微服务化

开发流程:多个团队在同不同的代码库里开发,在构建时将编译成不同的几个应用,运行时通过主工程加载。

适用场景:多团队,依赖库多、业务复杂

前端微服务化:开发、构建、运行分离

总对比

总体的对比如下表所示:

拆分大型 Angular 应用四种策略


So,你怎么看呢?

扫码关注最新前端技术实践



感谢支持~~



以上是关于拆分大型 Angular 应用四种策略的主要内容,如果未能解决你的问题,请参考以下文章

分布式软件架构中的捆绑优化

重新学习Mysql数据13:Mysql主从复制,读写分离,分表分库策略与实践

pandas GroupBy上的方法apply:一般性的“拆分-应用-合并”

ExtJS 架构师:将大型应用程序拆分到多个项目中是不是明智?

Entity Framework数据库初始化四种策略

大型网站架构演进业务拆分