条件限制下的升级原则
遇到的主要难点
小结
参考
1. 序言
Angular 官方网站针对 提供了比较详细的文档,并给出了一个 的案例演示,指导一步步如何改造。但总的来说,这个案例还是太过简单,并不能很好地还原一个最原始的、相对复杂的、版本更低的遗留项目该如何一步步升级,以及升级过程中可能需要考虑的一些额外因素。
本篇文章会以一个相对复杂的遗留项目为原型来探讨该如何一步步进行渐进式地升级改造,以及针对不同情况可以采取哪些策略,算是一篇结合了实际项目改造后的经验之谈。
2. 遗留项目概述
遗留项目按照不同业务拆分成了多个业务模块和一个公共模块,即有多个代码仓库,如下图:
从上图可知,遗留项目中主要使用的是 AngularJS 1.4,只有一个模块D使用了高版本的 Angular 。其实如果正确的业务划分,模块D是属于模块C的一个子模块(或一部分)。
原本是考虑将模块C拆分为更多更小的模块,再加上想尝试用较新的 Angular 技术栈来写新功能,在种种原因的促使下最终有了 Angular 高版本的模块D。但是,在后续的开发实践中发现这样的拆分是存在一定问题的(比如维护两套类似逻辑的代码、修改容易疏漏等等),不过由于已经用了高版本的 Angular,无法再简简单单地合并回去。
最终,除了需要考虑如何将 AngularJS 1.4 一步步升级到高版本的Angular ,也需要考虑在升级到一定程度之后将相同业务模块的代码仓库进行合并。
3. 条件限制下的升级原则
这部分主要包含实际改造中遇到的一些硬性限制以及相对应的升级改造原则。
(1)代码量与时间上的限制
首先,作为遗留项目,各个仓库的代码量不一(有多有少),但总体的量是非常庞大的。因此不可能在短期内或一次性全部改造完成。对此较好的策略是从较小的仓库开始着手,这样既能用较小的成本来做技术预研,判断改造方案的可行性,也能较好地控制改造后的风险。改造成功一个之后,则可以依葫芦画瓢慢慢铺开,改造剩余的仓库。
其次,现有遗留项目还在不断地改旧增新,这也将占据大部分的编码时间,并且还存在定期的发版上线,在做技术升级改造的同时需要优先保证正常的功能开发与发版。简而言之,升级改造和改旧增新是并行的,升级改造需要兼顾改旧增新。
不论是从代码量上考虑,还是从改造时间的不连续性上考虑,新旧代码必然是长期共存的,并且为了保证正常的发版,升级改造也必须是渐进式的增量升级。
(2)公共模块便利带来的升级限制
所谓成也萧何败萧何,在升级改造中,公共模块的存在是最为尴尬的。正是因为其复用得多,对其改造后的影响范围也是最大的,比如改一个公共的组件就需要检查并修改所有引用了公共模块的仓库。
特别是如果要对公共模块中使用的某个库进行升级,那么所有引用公共模块的模块也都必须同时升级,并且还需要检查 break changes 的影响,这很有可能需要较大的工作量才能完成。因此有时不能只从升级的可行性上考虑,还需要考虑升级的必要性和其后所能带来的收益大小等等。(这个问题在 angular-ui-boostrap 的升级改造中遇到,后面详谈。)
总的来说,虽然不同的遗留项目可能面对的情况和限制或多或少会有所差异,但大体上升级改造无法做到一步到位,将会是一个长期的过程是比较常见的情况,对此所需要的则是一个渐进式、增量升级的过程与解决方案。
4. 升级改造的演进方向
这部分所谈的演进方向主要是一些概要描述,不包含具体的实践细节。
(1)代码风格改造
遗留项目中第一优先需要改造的就是代码风格。由于 AngularJS 1.4 版本本身的特性限制,遗留项目中存在着大量的 replace:true 、变量绑定在 $scope 上、文件目录不清晰等与 Angular 规范不太匹配的代码。
而要改造好代码风格,与升级相比还是较为容易实现,只需要约定好相应的规范(可以参考 Angular 官网推荐的 风格指南),之后则是花费工作量的事情。
(2)AngularJS 1.4 升级到 1.5
从以下三方面综合考虑,有必要将遗留项目中使用的 AngularJS 1.4 至少升级到 AngularJS 1.5 :
第一: 升级的代价相对较小。因为毕竟是小版本的升级,虽然存在一定的 breaking changes,但根据官方提供的迁移文档,所需更改相对较少,只需要针对性的检查一番和做少量修改即可。
第二: AngularJS 1.5 新增的特性将有助于更方便地实现新功能(比如 component、单向绑定、新的生命周期等)。