AngularJS to Angular:

How We Did it

David Stanich

https://dstanich.github.io/angularjs-to-angular-presentation/

About Me

  • Advisory Software Engineer
  • IBM Watson Health (website)
  • Frontend development
  • Co-organizer Rochester FED@IBM
  • JavaScript, Angular, Java
  • Twitter: @dstanich
  • GitHub: dstanich

Terminology

AngularJS === 1.x
Angular === 2+
http://blog.angularjs.org/2016/12/ok-let-me-explain-its-going-to-be.html

What we'll cover

One experience in migration and culture changes
(May 2017 - June 2018)

  • Justifying the conversion
  • Education
  • Development methodology
  • Culture changes
  • Tool improvements
  • Angular pitfalls we encountered

Not Covered


  • How-to / guide / one size fits all
  • ngUpgrade
  • Migrating to React / Vue
  • Framework comparison

Setting the Stage

Application State

  • 5-6 UI developers
  • Medical application
  • Very dynamic, lots of configuration flags
  • Deployed in customer environments
  • Customer support / new features still required
  • Automated Selenium tests validating logic
  • Supports: IE11, FF, Chrome, iOS

Code History

  • Originally built in Dojo Toolkit
  • Ported to AngularJS (early 1.x)
  • Minimal usage of 1.5 components
  • $scope soup
  • Accessible
  • Translated into several languages
  • Right-to-left language support

Tech/Tooling Stack

  • AngularJS 1.5
  • JSPM dependency management and packaging
  • Custom Gulp builds
  • Data provided by REST APIs
  • Heavy bootstrap usage

Justifying the Conversion

Justify to the Business

Common concerns:
  • What is the value of converting?
  • What are we sacrificing by converting?
  • How long is this going to take?

Justify to the Business

Bad answers:
  • Everyone else is using this technology
  • It will be good on my resume
  • Want to try out something I just learned

Our Value Justification

  • New UX flow
  • New branding
  • Built with application's future in mind
  • Lower maintenance cost
  • Pilot tech base for future products
  • Sacrifices:
    • Some bugs only fixed in new UX
    • Limit features development in old UX

Our Plan

  • Estimate: 5-6 months
  • Install side-by-side with old UI
    • Won't disrupt other parts of project
    • UX Research
    • Compare behaviors
  • Angular 4 (was just released at the time)

In Place or Rewrite?

In place (ngUpgrade) Rewrite
+ Less risk in breaking + Cleaner code
+ Incremental + Experience in new framework
- Difficult w/new UX - More time required
- Bundle size increases - Requires more developers

Over Promising

  • Realistic expectations
    • Learning
    • Vacations
    • Maintain existing product
    • Mistakes - "learning opportunities"
    • Unexpected complications

Learn / Education

Learn

  • Important to spend time to learn framework
  • Started with a few team members
  • Share summary of learning with team
  • Follow best practices (style guide)
  • Learn potential pitfalls

Mob Programming

  • Work as a team on a single function at same time
  • Different developer 'drives' each meeting
  • Learning opportunity for knowledge sharing
  • Start finding potential issues right away
  • 3+ times each week initially

Frontend Masters

Locally based (Minneapolis) online, and in person, training workshops
Building Awesomer Apps with Angular
11+ hour workshop on Angular essentials
Reactive Angular2
Observables and RxJS with Angular
https://www.frontendmasters.com

Safari Books Online

O'Reilly online learning website
  • Books
  • Video training
  • Online workshops
https://www.safaribooksonline.com

Pluralsight / Udemy

Online learning platforms published by various creators; lots of content
https://www.udemy.com
https://www.pluralsight.com

Identifying Dependencies

Process

  1. Define all 1.x dependencies
  2. Are there Angular versions?
  3. Validate in dependency test app
1.x Angular
ng-idle ng2-idle
angular-ui/bootstrap ng-bootstrap
ngx-bootstrap
angular-translate ngx-translate
select2 ng2-iq-select2
ui-router @angular/router
d3 Test within Angular

Dependency Test App

  • No frills app to test libraries
  • Inject all dependencies at same time
  • Validate use cases
  • Test AoT build

Package Checklist

  • Use case validation
  • IE11, FF, Chrome, iOS
  • Accessibility
  • Right-to-left support
  • Translation support
  • Acceptable license
  • Works in AoT build
  • Issues, contributors, activity

Reuse

Identify Potential 1.x Reuse

  • Services
  • Filters
  • Directives
  • Some controller functions
  • Translations

Reusing Code

  • Migrate as needed; get rid of dead code
  • Update to 2+ syntax
  • Update injected services
  • Add types
  • Decide between Promises / Observables
  • Fight urge to rewrite logic

Library Projects

Library Projects

  • Two libraries shared for future projects
  • Publish packages via internal NPM registry
  • Versioned via semver (major.minor.fix)
  • Custom build for Angular package format
    • Gulp
    • tsc
    • Rollup

Suggestion: Use angular-cli

angular-cli (v6) now supports library projects

							ng generate library my-lib

							ng build my-lib
						
https://github.com/angular/angular-cli/wiki/stories-create-library

API Package

  • Common data used across several products
  • Package contains shared:
    • Services
    • Interfaces / models
    • Views (complex components)

Component Library

  • New UX/design requiring custom styling
  • Includes demo application
  • Generated doc with compodoc (via JSDoc)
  • Supports: right-to-left, accessibility, translation
  • Source is mix of:
    • Custom developed source
    • Wrappers around open source

Versioning

  • semver criteria
  • Automatic releases via semantic-release
  • Every commit/merge triggers release
  • Application locks major.minor when preparing release
  • Release branches only when critical issue and version advanced too far

Tooling/Process Change

Tooling/Process Change

  • Source control
  • Builds
  • Code reviews
  • Standups
  • Technical meetings
  • Demos

Source Control

Rational Team Concert (RTC) ==> GitHub Enterprise
  • Better code review tooling
  • More efficiently able to collaborate
  • GitHub is company's direction
  • Act as pilot for other projects
  • Keep team up to date with industry

Builds

Jazz Build Engine ==> Travis CI Enterprise
  • Automatic branch builds
  • Concurrent builds
  • More developer focused
  • Integration with GitHub Enterprise

Code Reviews

  • Helps educate each other on Angular
  • No one can push to master
  • Approved PRs enforced by GitHub
  • Slack channel to consolidate open PRs
  • Daily Slackbot reminders

Standups

  • Critical to success; need communication
  • Decentralized team (3 locations)
  • Standups often turned into long discussions
  • Moved standup to Slack vs. phone
  • Slackbot reminder at 9am for status

							/remind #channel at 9am every weekday "@here STANDUP!  Use this format:
							Y:
							> - What you did yesterday
							T:
							> - What you doing today
							B: Blockers
							"
						

Daily Technical Meetings

  • Communication / sharing important
  • Daily meeting for:
    • Education topics
    • Code walkthroughs
    • Mob programming
    • Planning

Demos

  • Need feedback from stakeholders (new UX)
  • Weekly Friday demos
  • Create work items for each action
  • Schedule followup discussions if needed

Pitfall:
Differing Developer Styles

Problem

  • Developers have code style preferences
  • Commit messages are inconsistent
  • No established styles on team
  • When fixing defects, often unnecessary changes made due to style
  • Makes diffs very difficult to parse

Solution: Tooling

Configuration


							// package.json
							{
							  "husky": {
							    "hooks": {
							      "pre-commit": "lint-staged",
							      "commitmsg": "commitlint -e $GIT_PARAMS"
							    }
							  },
							  "lint-staged": {
							    "*.{ts,js,json,scss}": ["prettier --write", "git add"],
							    "*.ts": ["tslint"]
							  }
							}
						

							// commitlint.config.js
							module.exports = { extends: ['@commitlint/config-conventional'] };
						

Example

Interesting TSLint Rules

Rule Purpose
"ordered-imports": true Grouping, ordering imports
"no-unused-variable": true Flag unused variables (and imports)
"arrow-parens": true Require parenthesis around params in arrow functions
"array-type": [true, "generic"] Force Array<T> syntax
"object-literal-shorthand": true Force ES6 shorthand (ex: no myVar: myVar)
"member-access": true Force devs to be explicit on public/private
member-ordering Ideally, force ordering
Remove no-inferrable-types rule Allow redundant type declarations
Remove quotemark rule May conflict with Prettier

Pitfall:
OnPush Change Detection

DEMO

Problem

  • Default change detection (CD) strategy doesn't always scale well
  • Some event listers may trigger a lot of CD
  • Expensive function impls will slow down CD
  • Demo:
    • Every mouse event is triggering CD to run
    • Expensive function being called every time

Solution

  • Use ChangeDetectionStrategy.OnPush
  • Inject ChangeDetectorRef and manually execute CD if needed
  • Treat @Input values as immutable
  • Demo:
    • OnPush prevents calculated-value from being re-rendered
    • Ideally, OnPush should be applied everywhere

Pitfall:
Not Unsubscribing

DEMO

Problem

  • Very easy mistake to make
  • Not always clear when unsubscribe is required
  • Causes memory leaks
  • Possible extra change detection cycles
  • May trigger unnecessary code to run
  • Unpredictable state changes

Solution

  • Memory profiling to find leaks
  • Utilize async pipe more often
    • Auto unsubscribes
    • Renders again when appropriate
  • Ensure subscription is completed:
    • .take(xx) completes observable
    • .unsubscribe()

Pitfall:
Trying to do everything the "Angular" way

Problem

  • Angular has a lot of abstraction layers
  • Often frustrating/annoying to understand abstraction
  • Harder for non-Angular developers to understand
  • Several discussions on we should be using Angular

Solution

  • Decided to use abstractions when it makes sense
    • @HostListener, some Renderer2
    • Just use window natively
    • Ignore difficult to use abstractions
  • Team knew we wouldn't be server side rendering
  • Things became more simple when we didn't need to look it all up

Success!!

  • Completed in roughly 6-7 months
  • Well received by customers
  • Has proven to be less difficult to debug
  • Team was able to adopt better practices
  • Library projects usable on other applications

Questions??