<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Andrii Vankovych on Medium]]></title>
        <description><![CDATA[Stories by Andrii Vankovych on Medium]]></description>
        <link>https://medium.com/@vankovych?source=rss-a32a95db7744------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*7LwwzvUrnsKasuMv3HLUtg.jpeg</url>
            <title>Stories by Andrii Vankovych on Medium</title>
            <link>https://medium.com/@vankovych?source=rss-a32a95db7744------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 20:30:33 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@vankovych/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How I upgraded Angular v4 + Material beta + Gulp project]]></title>
            <link>https://medium.com/@vankovych/how-i-upgraded-angular-v4-material-beta-gulp-project-498e49b672ae?source=rss-a32a95db7744------2</link>
            <guid isPermaLink="false">https://medium.com/p/498e49b672ae</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[lodash]]></category>
            <dc:creator><![CDATA[Andrii Vankovych]]></dc:creator>
            <pubDate>Fri, 23 Nov 2018 16:06:50 GMT</pubDate>
            <atom:updated>2020-05-04T12:40:36.966Z</atom:updated>
            <content:encoded><![CDATA[<h3>How I upgraded out-of-date Angular 4 project</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nya1mLyKQPo-YYtn" /><figcaption>“boy sitting while holding electronic device part” by <a href="https://unsplash.com/@kjarrett?utm_source=medium&amp;utm_medium=referral">Kevin Jarrett</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Introduction</h3><p>In this article, I want to share my experience of upgrading Angular project with out-of-date and low maintainable code base. I will guide you through all preparations, steps, best practices and mistakes I found and made during the process. Also, I introduce some fun metrics for complex tasks.</p><h3>Project description and history</h3><p>My current project is the web app that has first commits about five years ago with frontend based on Angular.js. On Angular 2 RC release most important pages or completely new ones are developed using the second generation of the framework. So there are two apps that run on two different ports and a user simply navigates between them. E.g. you see a list of entities on a new Angular app but on row click you are redirected to details view on legacy Angular.js app. Having the same UI style guide brings a consistent look and feel.</p><p>With a rush of new features requests, the code base was not maintained properly in time and tech debt increased dramatically. No separate resources were allocated for keeping up-to-date libraries being used and general ecosystem. The only significant task was done is Angular upgrade to version 4. So when I joined a project about a year ago the state of a new Angular app was:</p><ul><li>Angular 4.3</li><li>Angular Material 2 beta</li><li>No <a href="https://cli.angular.io/">Angular CLI</a>, just some custom build tool instead, based on <a href="https://gulpjs.com/">Gulp.js</a>. As a result, two key optimization approaches like <a href="https://angular.io/guide/aot-compiler">Ahead-of-Time compilation</a> and <a href="https://angular.io/guide/lazy-loading-ngmodules">lazy loading modules</a> were not applied.</li></ul><p>The main goal of the upgrade was not just changing Angular version from 4 to 6, but the upgrade of Angular ecosystem, improve initial application load speed and have the latest Material library with completely new components and extended functionality of existing ones. And one risky item was that <a href="https://angular.io/guide/releases">LTS of version 4 was ending soon</a>.</p><h3>Where to start</h3><p>Angular team created a useful <a href="https://update.angular.io/">Angular Update Guide</a>. Just select current and target version, app complexity and you will see check-list of tasks to be done. This will create some preliminary plan and help to avoid tricky issues in advance instead of “stackoverflowing” numerous build/lint/runtime errors. At the moment of the upgrade was started the latest Angular version was 6.0.7.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uZ_nRkqG2q01V7wu8GNhBQ.png" /><figcaption>Angular Update Guide</figcaption></figure><p>Before I started I set three rules for myself:</p><ul><li>Make granular commits, commit changes after any sub-task is done. This will help to better track all changes and easily share results in future. All these commits are highlighted below with ✔️<strong>COMMIT</strong>✔️.</li><li>Don’t do any additional refactor or fixes, even if it looks easy and obvious, only Angular upgrade related changes. Otherwise, one can be lost in finding problem root cause, was it upgrade or refactor.</li><li>When I face some minor error that takes me more than 5 minutes to solve or investigate I will comment that code (if possible) and add specific to-do comment (e.g.TODO: Angular upgrade) to come back later and easily find and resolve instead of wasting time on early phases of the upgrade. Custom code snippet with this comment will be useful.</li></ul><p>To have some metrics for upgrade sub-task I introduce MoJoR (<strong>Mo</strong>nkey <strong>Jo</strong>b <strong>R</strong>ating) with the value from 🐒 to 🐒🐒🐒🐒🐒. This rating will reflect time consumption and monotonous work. Every sub-task will have MoJoR value in paragraph title.</p><h3>1. New project🐒</h3><p>The first step was a complete replacement of project folder content with a newly CLI-generated project, but keeping existingsrc folder. As a result, there are out-of-date app files within the latest Angular engine. Definitely, this won’t even build but at least we have the foundation to start upgrading app files. From this point, we can observe the evolution of app modules, components, templates and services. Feeling optimistic and ✔️<strong>COMMIT</strong>✔️.</p><h3>2. Make it build🐒🐒🐒</h3><p>My first aim was to make application at least buildable. First of all, I generated a checklist from the upgrade guide, selected <em>“Advanced”</em> app complexity and went through items one by one. Two major items of current sub-task are described below, the rest were a couple of minor issues. On such global things like upgrade to latest <a href="http://reactivex.io/rxjs/manual/index.html">RxJS</a> 6 and switching to <a href="https://angular.io/guide/http">HttpClient</a> I worked a bit later. Also in Angular CLI generated project default Typescript lint rules were more strict in comparison to rules we already had. So I postponed Typescript linter errors fix too.</p><h4>RxJS (phase 1)🐒</h4><p>Angular 6 comes with a new version of RxJS 6 that has breaking changes. But there is a special <a href="https://www.npmjs.com/package/rxjs-compat">compatibility package</a> that will help to postpone resolving this version change. So I installed it temporarily without saving in package.josn. More info about RxJS changes one can find in the video below:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fwww.youtube.com%2Fembed%2FX9fdpGthrXA%3Ffeature%3Doembed&amp;url=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttp%2Fwww.youtube.com%2Fwatch%3Fv%3DX9fdpGthrXA&amp;image=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fi.ytimg.com%2Fvi%2FX9fdpGthrXA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/641a176ba8bc7e2a2db090a9dc2695fb/href">https://medium.com/media/641a176ba8bc7e2a2db090a9dc2695fb/href</a></iframe><h4>Material🐒🐒🐒</h4><p>Another big amount of build errors were related to <a href="https://material.angular.io/">Angular Material</a>. Beta version uses legacy prefixes ( mdinstead of mat). So careful bulk change will help: element tags, directives, CSS class names, modules and components names.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ERvy03ba0-geO-d19ZC2zQ.png" /><figcaption>Angular Material components diff sample</figcaption></figure><p>The rest of build errors were caused by some deprecated/renamed properties/methods/directives of Angular or Material. Another source of issues could be some specific code related to custom Gulp.js based build tooling. E.g. in all decorators of components classes it was necessary to make the following changes:</p><ul><li>removed explicit module definitions moduleId: module.id</li><li>in style file paths changed the file extension from css to scss.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8NglwubAphtkXPbF9hk9Tw.png" /><figcaption>Component diff sample</figcaption></figure><p>So after changing almost every application file (about 600), I managed to build and launch the application 🎉. Feeling happy and ✔️<strong>COMMIT</strong>✔️.</p><h3>3. HttpClient🐒🐒🐒</h3><p>The next step was to move to modern <a href="https://angular.io/guide/http">HttpClient</a>:</p><ol><li>Replace imports of all Http module related stuff with HttpClient module</li><li>Remove all calls of json()<em> </em>method of response object as it is already JSON by default</li><li>Refactor building of URL query parameters. Prior to HttpClient simple strings concatenation was used. But with a new client I started to use new immutable HttpParams object</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rkcJ1b50gHxhl2voXcQ3yQ.png" /><figcaption>Http params build diff sample</figcaption></figure><p>This may look a bit overcomplicated but building queries became more strict and clear to understand. Feeling confident and ✔️<strong>COMMIT</strong>✔️.</p><h3>4. RxJS (phase 2)🐒🐒🐒🐒🐒</h3><p>Then it was the right time to get rid of old RxJS 5:</p><ol><li>Now delete rxjs-compat package that was installed earlier</li><li>Delete separate file with all Rx operators (was considered as <a href="https://loiane.com/2017/08/angular-rxjs-imports/">best practice</a> in RxJS ≤ 5)</li><li>Go through almost every component class, service, directive and wrap all RxJS operators in <em>pipe()</em> operator and rename operators with changed names in version 6.</li></ol><p>This was defenitely the most monotonous piece of work. Feeling bored and ✔️<strong>COMMIT</strong>✔️️.</p><h3>5. TSLint 🐒🐒🐒</h3><p>To make the code more safe and standardized it was necessary to turn on default TSLint rules and fix corresponding errors. Also, I added application prefix to angular.json, so this prefix was added to all custom components. Feeling refreshed and ✔️<strong>COMMIT</strong>✔️️.</p><h3>6. Lazy load🐒</h3><p>The application has about ten feature modules, so it was not a big deal to change routings. Size of the main bundle was decreased. As a result, if a user opened app just to check dashboard or some notifications, the rest heavy functionality was not loaded. Feeling fresh and ✔️<strong>COMMIT</strong>✔️️.</p><h3>7. Ahead-of-Time Compilation🐒🐒</h3><p>Originally fixing AOT compilation errors was estimated for about one day. Earlier there was no possibility to run it and it was considered that codebase has a lot of related errors. But in fact, the number of errors was minimal. In an hour of fixing I have finally achieved the main goal of upgrade that can be clearly measured, AOT compiled application with the initial load of about 2 seconds 🎉. Feeling blessed and ✔️<strong>COMMIT</strong>✔️️.</p><h3>8. Bonus: Lodash🐒🐒</h3><p><a href="https://lodash.com/">Lodash</a> is used in the project. I’m not a big fan of such libraries and agree with <a href="https://codeburst.io/why-you-shouldnt-use-lodash-anymore-and-use-pure-javascript-instead-c397df51a66">this article</a>. Anyway, it looked like there was some space for optimization by importing operators in a <a href="https://medium.com/@armno/til-importing-lodash-into-angular-the-better-way-aacbeaa40473">better way</a>. I created a separate file with only those Lodash operators that are used in the app (similar approach as in RxJS ≤ 5). Afterwards simply replaced import path and refactored usage of chainoperator. Also, I blacklisted direct imports from <em>lodash</em> in <em>tslint.json</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A0f3eO_kYqB5BfJpZ-gixw.png" /><figcaption>Lodash import diff sample</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*ICAkVVUjaQWdY9kqjD2EbQ.png" /><figcaption>Lodash operators file sample</figcaption></figure><p>With a help of <a href="https://www.npmjs.com/package/webpack-bundle-analyzer">Webpack Bundle Analyzer</a> I can clearly see results of optimization:</p><ul><li>full Lodash import 711 KB</li><li>selective Lodash import 184 KB</li></ul><p><em>“Gzipped” difference is only about 30 KB. Frankly speaking, I’m not sure if this can be really called “optimization”. And at the moment of writing this article, separate file with operators looks an over-engineering and extra work. Especially for unit tests, where I did not manage to include this file during the test run of Karma. Anyway, a bad experience is still experience. And there can be cases and projects where size decrease of the main bundle by 30 KB will be a significant improvement.</em></p><p>Feeling good and ✔️<strong>COMMIT</strong>✔️️.</p><h3>9. Upgrade to latest minor version🐒</h3><p>In a meantime of upgrade process, a couple of minor versions of Angular were released. So the final chord was upgrading the application to the latest minor version 6.1.1. And in this case, the upgrade was done easily in a one minute with a help of CLI commandng upgrade. The result was modified package.json, no other changes were required. This was the last development step. Feeling accomplished and ✔️<strong>COMMIT</strong>✔️️.</p><h3>Results sharing</h3><p>The last but not least was sharing results of this huge amount of work (and paid work hours) with a team and customer. Naturally, each of them will be interested in different aspects of the upgrade.</p><p>For the rest frontend engineers, I made a small demo. I walked them through every commit to show the evolution of code.</p><p>Also, there was some information to share with QA engineers. We do not use Protractor. Automation QA team uses Python-based test framework for E2E testing. So with Material library upgrade a lot of XPath locators became invalid, in most cases due to prefix change (md to mat). So I provided QA engineers with a commit URL that has code diffs related to the Material upgrade. This simplified their work as they could analyze code changes that affected tests and easily fix them.</p><p>And with product owner I shared and demonstrated the following results:</p><ul><li>Initial load time of application decreased. More details in performance profiling summary charts:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*A3DSnydARK18NqAa7uiB_A.png" /><figcaption>Before upgrade</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*O8wz_etn1VLYmPnO3kISLQ.png" /><figcaption>After upgrade</figcaption></figure><ul><li>In future with new feature modules being added initial load time won’t be affected due to the usage of lazy loaded modules.</li><li>The latest Material library has more components we can use so there will be no need of creating new ones from scratch that is time-consuming. Also, existing components received more customization and functionality.</li><li>LTS of new project’s framework version ends in <a href="https://angular.io/guide/releases">November 2019</a>.</li><li>No critical issues were found after releasing the app with upgraded Angular. And this was achieved mainly by adding AoT compilation and step-by-step upgrade.</li></ul><h3>Conclusion</h3><p>This was an interesting task that helps to understand Angular ecosystem better, how it evolved, and in general great experience of making complex system up-to-date. There is a nice Ukrainian word “перелопатити” that means something like “go through with a shovel”, that exactly characterizes what was done.</p><p>One can be curious about unit tests. There is a dozen of them. But they were not been maintained even before the upgrade. So this is the task for future sprints. Anyway, the process of the upgrade will be the same.</p><p>At the moment of the article being written Angular 7 has been released. And now with a help of Angular CLI future upgrades will be definitely less painful and with MoJoR 🐒.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=498e49b672ae" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>