1. Preface

The Angular website provides detailed documentation for upgrading from AngularJS to Angular, as well as a case study of a PhoneCat upgrade tutorial that provides step-by-step instructions. Overall, however, this example is too simple to do a good job of illustrating how an original, relatively complex, lower-version legacy project should be upgraded step by step, as well as some additional factors that might need to be considered during the upgrade process.


This article will take a relatively complex legacy project as the prototype to discuss how to carry out gradual upgrade and transformation step by step, and what strategies can be adopted for different situations. It is a talk based on the experience of actual project transformation.


2. Legacy Project Overview

Legacy projects are split into multiple business modules and a common module according to different businesses, i.e., multiple code repositories, as shown below:

As you can see from the figure above, AngularJS 1.4 is the main legacy project, with only one module D using a higher version of Angular. In fact, if the business division is correct, module D is a submodule (or part of) of module C.


The idea of breaking up module C into more and smaller modules, combined with a desire to try to write new features on the newer Angular technology stack, led to a higher version of Angular module D. However, in subsequent development practice, such a split was found to be problematic (maintaining two sets of code with similar logic, making changes easily missed, etc.), but with a higher version of Angular, it could not simply be merged back.


Finally, in addition to thinking about how to upgrade AngularJS 1.4 step by step to a higher version of Angular, you also need to think about merging the codestores of the same business modules after upgrading to a certain level.


3. Upgrade rules under conditions

This part mainly includes some hard restrictions encountered in the actual transformation and the corresponding upgrading principles.


(1) Code quantity and time limitation

First, as legacy projects, the amount of code varies from repository to repository (more or less), but the total amount is enormous. Therefore, it is impossible to complete the transformation in a short time or at one time. In this regard, a better strategy is to start with a smaller warehouse, so that it can not only do technical pre-research at a smaller cost, judge the feasibility of the transformation plan, but also better control the risk after the transformation. After the successful transformation of one, can be slowly rolled out according to gourd gourd gourd gourd, transformation of the rest of the warehouse.


Secondly, the existing legacy projects are still being renovated and updated constantly, which will occupy most of the coding time, and there are regular release online, so we need to give priority to normal function development and release while doing technical upgrading. In short, upgrading and replacing old ones and adding new ones go hand in hand, and upgrading and replacing old ones and adding new ones needs to take into account both.


Both in terms of the amount of code and the discontinuity of the transformation time, the old and new code must coexist for a long time, and in order to ensure the normal release, the upgrade must be a gradual incremental upgrade.


(2) Upgrade restrictions brought by the convenience of public modules

In the upgrade, the existence of the public module is the most embarrassing. It is precisely because they are reused so much that the scope of their transformation is the greatest, for example changing a common component requires checking and modifying all repositories that reference the common module.


In particular, if you are upgrading a library used in a public module, all modules that reference the public module will have to be upgraded at the same time, and you will also need to check for the impact of break changes, which can be quite a bit of work. Therefore, sometimes we should not only consider the feasibility of the upgrade, but also consider the necessity of the upgrade and the size of the subsequent benefits, etc. (This problem is encountered in the Angular-UI-Boostrap upgrade, which will be discussed later.)


In general, although different legacy projects may face different situations and limitations, it is common for upgrading to be a long-term process that cannot be achieved in one step, and what is required is an incremental and incremental upgrade process and solution.


4. Evolution direction of the upgrade

The evolution direction discussed in this section is mainly a summary description, not practical details.


(1) Code style transformation

The first priority for legacy projects is code style. Due to the inherent limitations of AngularJS version 1.4, legacy projects have a lot of replace: True, variable binding to $scope, file directory ambiguity, and other code that doesn’t quite match the Angular specification.


Changing the style of your code is easier than upgrading it. Just agree on the specifications (see the style guide on Angular’s website), and then it’s a matter of effort.


Upgrade from AngularJS 1.4 to 1.5

It is necessary to upgrade to at least AngularJS 1.5 from AngularJS 1.4 used in legacy projects based on the following three considerations:


First: The cost of upgrading is relatively small. After all, it is a small version of the upgrade, although there are some breaking changes, according to the official migration document, the required changes are relatively few, only a targeted check and a small number of modifications. Details can be found here

Second: The new AngularJS 1.5 features will make it easier to implement new features (component, one-way binding, new life cycles, etc.).

Third: AngularJS 1.5 has added component apis that help restyle legacy code. It is more like the Angular equivalent, both in terms of code style and component lifecycle, on which it is easier to upgrade code to Angular.


(3) Introduce TypeScript

We don’t introduce TypeScript and change everything to.ts files as we did in the example on TypeScript. Instead, we do a gradual upgrade. Through the use of Webpack packaging tools, let the project support.js and.ts file formats at the same time, targeted use of relevant plug-ins, and ultimately unified generation of JS target files. In this way, instead of changing all files to.ts files at once, you can minimize the impact of the transformation. You only need to replace.js with.ts files step by step in the subsequent transformation.


In addition, in existing legacy projects, ESLint is used for code style checking and constraints on JS files. Now that TypeScript is added, esLint can also be used for TS files. Since ESLint 6.0 it has been possible to use different rules for different file suffixes so that both JS and TS files can be supported.


(4) Introduce angular-ts-decorator (optional)

After upgrading AngularJS to 1.5+, you can further modify legacy code in angular 2 code style by introducing Angular-ts-decorator or write new businesses directly. Angular-ts-decorator is simply a decorator that wraps up AngularJS module declarations, directives, and controller declarations without changing their underlying nature.


In short, you can use angularS-ts-decorator to change your AngularJS code style to look like Angular 2 code to enjoy the convenience of Angularized code while making subsequent updates easier.


At this point, you might be a little confused, because with the website’s upgrade, this step seems completely unnecessary. After the necessary code style changes + TypeScript is introduced, you can go straight to the AngularJS + Angular hybrid mode. Then you can happily write components in the higher version of Angular, with new functionality written entirely in the higher version. As for AngularJS components, you can mix components from both AngularJS and Angular using the upgrade/downgrade scheme. But is it really that simple and easy?


On the one hand, it is necessary to consider that the development of new functions will occupy the main time, while the time of technological upgrading is relatively small and discontinuous. The effort to introduce the Angular-ts-Decorator library into your project is minimal, and you can almost write one or two samples out of the box, and the entire team can write AngularJS in the new style. This will directly improve the overall development experience of the team, and the new script is similar to the updated Angular components (except that the HTML is still AngularJS), in addition to making subsequent upgrades easier to maintain.


On the other hand, both up and down components are not as simple as you might think. This is limited to filters/pipes, property directives, and third-party UI component libraries (more on the difficulties encountered later). Upgrading AngularJS components to Angular components is relatively easy if these three issues are well addressed.


Therefore, while this step is optional, it may become necessary in the context of the project.


(5) Enable AngularJS + Angular hybrid mode

Enabling mixed mode itself is as simple as importing angular-related libraries and bootstrapping AngularJS modules in Angular. Detailed visible


(6) Progressively upgrade and replace AngularJS

First, introduce HttpClient to handle Http requests and configure the relevant Http Intercepters. This corresponds to the AngularJS $resource and the configured $httpProvider policy.


Second: Import The RouterModule and configure Angular routing policies using adjacent exits to enable hybrid applications to support both AngularJS and Angular routes.


Third: If a legacy project uses a third-party AngularJS UI component library (such as Angular-UI-Bootstrap), consider whether you can upgrade to the corresponding Angular version first. If this is not possible or is too much work, then you need to consider whether there is an alternative Angular VERSION of the UI component library. Of course, this will lead to the existence of both AngularJS and Angular third-party UI component libraries in the project, which needs to be considered in terms of style and interaction consistency.


Fourth: New features and pages can be written entirely in Angular components and routes, while AngularJS components can be upgraded/degraded temporarily if they cannot be upgraded all at once. (General rule: Use higher versions of Angular components or services to implement relevant business functions.)


Fifth: Merge the same business modules. Because mixed mode is enabled and Http requests and routing policies are configured, you can consider incorporating older Angular modules into mixed mode enabled modules.


.


(7) Final goal

Regardless of the preparation and specific upgrade implementation, the end goal of the technical upgrade is simple and clear — merge the same business modules and upgrade all repository code to a higher version of Angular. The diagram below:


5. Main difficulties encountered


(1) Upgrade and transformation of routing and routing components

The Angular documentation is not very thoughtful or informative about routing changes, and they are not incremental. Typically, large legacy projects simply cannot replace all routing components at once. Therefore, we need to consider the possibility of long-term coexistence of AngularJS Router and Angular Router, and gradually replace AngularJS Router with Angular Router in transformation. The related solutions are not provided in the official upgrade documents, so you need to explore or search for them.


Tips: If you consider using only AngularJS Router routing in a hybrid application, it is also possible. One solution is to downgrade all Angular routing components, or if the AngularJS Router uses a UI-Router, the UI-Router provides a hybrid solution for angular-hybrid applications. However, if you consider that the upgrade itself is replacing AngularJS Router routes, the preferred hybrid route is better.


(2) The breaking changes in the upgrade

Updates to all third-party libraries, even the latest version, sometimes have breaking changes (e.g. Angular 1.4 to 1.5) that you should be aware of when upgrading. The corresponding breaking changes must be evaluated based on the actual project to determine the scope of influence or whether it is very large. If the scope of impact is large or the amount of change is too much, you need to consider whether an upgrade is necessary.


In addition, the upgrade process also encountered a dependency on the upgrade situation. After upgrading Angular 1.4 to 1.5, when using the component feature added to 1.5, it was not supported in the UI-Router 0.4.x used as a routing component in the project, which has been supported since 1.0 and later. Such a large version of the change is bound to bring about breaking changes. After combing the official UI-Router 1.0 Migration and the use of the project, the influence points brought by breaking changes are determined to be relatively small and acceptable. Hence the uI-Router upgrade to 1.0.


(3) Limitations of the official Angular upgrade scheme itself

The AngularJS filter and attribute Directive cannot be upgraded to use in Angular. The Angular Pipe and attribute Directive cannot be downgraded to Use in AngularJS.


There are two main problems with this:

First: unable to reuse, a certain period of time may exist at the same time two similar logic of the code.

Second: Sometimes upgrading an AngularJS component makes heavy use of the filter and custom attribute Directive. Upgrading a component can be a lot more work than expected.


(4) Upgrade and transformation of third-party UI component library

The main UI component library used in legacy projects is Angular-UI-Bootstrap, a pure AngularJS component library.


First of all, the component directive is implemented with unupgradable features such as replace: true and cannot be used directly in Angular because it is introduced in 0.14.x.


Second, the legacy projects not only use the Angular-UI-Bootstrap component directive extensively, but also use its attribute directive extensively. This also leads to the fact that even when angular-UI-Bootstrap itself is upgraded (at least to 2.0, with a lot of breaking changes), The component directive can be temporarily upgraded to use in Angular, but the attribute Directive cannot be used.


So instead of upgrading angular-UI-Bootstrap itself, we considered replacing it with a higher version of Angualr’s UI component library, as long as the styles and basic interactions were consistent.


6. Summary

To sum up, this paper mainly introduces the basic situation of the remaining projects, the limitations in the project and the upgrading and transformation principles that should be followed, the general direction of the upgrading and transformation and the main difficulties encountered. Future articles in this series will discuss some of the steps in the upgrade plan in detail and the pitfalls.


Reference 7.

Upgrade from AngularJS to Angular

AngularJS migrating from 1.4 to 1.5