Use React tools for better Angular apps

How to leverage the best from React ecosystem and beyond to make our daily task easier and more effective within Angular apps and in the end become the best friends ever !

Are you ready for some solid fight ? Angular vs React ha ?!

Fight leads to the dark side ( to Twitter /clone/ flame wars )

After seeing that cover image of this article, your first impression must be like: OMG! another clickbait article about why X sucks and Y is the silver bullet. Well, I have to disappoint you. This article is about the complete opposite :)

Why

Angular is a great piece of technology on it’s own indeed, so why should you look somewhere else?

Everything Angular, is tightly coupled to Angular and its ecosystem…

I don’t know about you, but I really hate to have boundaries for achieving my goals…

How

To answer the question “How to leverage other ecosystems” we need to to introduce and take a look at 3 categories that cover an integral part of software development:

  • Architecture
  • Libraries

As a baseline we will use “Industry standard” for booting up new Angular apps — Angular CLI

Angular CLI, industry standard for booting up Angular apps
npx @angular/cli new my-app
  • Architecture: Component driven architecture with Service layer, but no restrictions on this front ( use what you want )
  • Tools:
Angular CLI defaults from our 3 categories perspective

Tools

Tooling is indeed crucial for our productivity. Let’s see what can be done on this front.

Package Manager/Task Runner

Most of you are probably using npm, which was super annoying to use and slow until version 5. While npm is constantly improving, you don’t have to wait and instead you can switch to a better tool -> yarn

npm vs yarn ( from task runner perspective )
yarn upgrade-interactive

Formatting

CLI comes with pre-configured TSLint supported by Codelyzer, which helps us lint our code and adhere to strictly set style guides within our project. TSLint takes also care of consistent spaces at various places ( functions, module imports, etc… ), empty lines, single/double quotes, semicolons/no-semicolons… But if you think that this is the right way to do formatting, you are fundamentally wrong. Anyway, Lint is for linting not for formatting !

Prettier

is an opinionated formatter created by Facebook and OSS community. You can read more about it on prettier website.

yarn add -D prettier
{
"scripts": {
"format": "prettier {src/e2e}/**/* --write"
}
}

tslint-config-prettier

Thanks to OSS we can leverage tslint-config-prettier package, which handles everything for us!

yarn add -D tslint-config-prettier
{
"extends": [
"tslint-config-prettier"
],
"rulesDirectory": [
"node_modules/codelyzer"
],
"rules": {...}
}
yarn tslint-config-prettier-check ./tslint.json
tslint-config-prettier-check output

I see a great PR opportunity here, to automate removal of those conflicting lint rules ;)

Formatting/Linting Done!

Hey Robot! Do your work!

  • husky 🐶 Git hooks made easy
yarn add -D lint-staged husky
lint-staged config within package.json
{
"scripts": {
"precommit": "lint-staged"
}
}

Excellent, you will never ever have to argue with your PR reviewer about semicolons vs no-semicolons, spaces…you name it…👌.

With that said, let’s switch to more serious stuff…

Unit Testing

Jest

  • jest-preset-angular, which handles everything for test environment setup specific to Angular ( zones and stuff ya know ? )
yarn add -D jest jest-preset-angular
// jest.config.js
module.exports = {
preset: 'jest-preset-angular',
setupTestFrameworkScriptFile: '<rootDir>/src/setupJest.ts',
}
{
"scripts": {
"test": "jest --watch",
"test:ci": "jest --runInBand",
"test:coverage": "jest --coverage"
}
}

Jest speed

I briefly mentioned, that Jest is fast. How fast ?

Unit testing speed comparison Karma vs Jest

Jest snapshot testing

Jest comes with snapshot testing, you just need to use toMatchSnapshot matcher within your test expectation on component fixture:

Component snapshot testing
Component snapshot diff change

Jest interactive mode

Jest comes with advanced watch mode — a CLI like tool with lot of perks, like filtering, running only tests that changed and various other features:

Behold — Jest interactive watch mode:

Other Jest features

There are moar things that comes with Jest, I will name just few:

  • Code coverage — 0CJS jest --coverage
  • Pluggable ( run Puppeteer with Jest )
  • Huge ecosystem: jest-axe ( a11y ), jest-images-snapshots

E2E Testing

End to End testing is equally or even more important than unit testing. Let’s see what we get by default with CLI.

Selenium you said ? You monster !

Selenium was indeed useful at some point in our development carer history, but it’s 2018 and there are much better tools out there nowadays.

Please welcome, the cure for your E2E testing sickness, Dr. TestCafe 👨‍⚕️

TestCafe

TestCafe is pure NodeJS, non framework specific, open source tool for all our E2E scenario needs !

yarn add -D testcafe testcafe-live
npm scripts for running e2e with TestCafe

Let’s see it in action ( TestCafe watch mode )!

TestCafe demo example

E2E tests run in watch mode — brilliant DX for writing our scenarios

Components Development

Angular CLI doesn’t come with anything related to developing Components in isolation or for building a Demo project with components showcased in various state. Thanks to React community we can leverage Storybook !

Storybook

Storybook is powered by React under the hood and generates whole UI catalogue of your component demos/stories. Within Angular scope, it supports much more than just components. You can write stories for Services, Modules etc…

Storybook UI with Angular
npx @storybook/cli@alpha getstorybook

While we are enjoying our morning quick shot of espresso, everything is setup for us. Amazing!

add storybook to angular CLI
yarn storybook
Angular Componet Story
Final folder structure
  • unit test with snapshots
  • external styles
  • story

Tooling summary

Thanks to other communities and ecosystems, we are able to leverage better exisitng tools for our Angular toolkit.

Architecture

Let’s talk briefly about architecture which is the 2nd category we mentioned in the beginning.

  • State management

Architecture: Components

Following image compares both Angular and React in terms of Component creation patterns, and as we can see those are almost identical.

  • HOC/@Directive ( HOC just decorates behaviour of an Component in immutable way. Directive can do the same in Angular )
  • render JSX/Inline template ( Always use Inline templates to have everything in one file, logic + rendering )
  • Inline/External CSS
  • Immutable props/@Input with CDS.OnPush ( React triggers re-render only when reference changes, Angular allows the same via OnPush strategy )

Architecture: State management

How to handle state ?

  • Hierarchical DI in React via Context API / Hierarchical DI in Angular via SOA => suitable for whole app state
  • FLUX architecture powered by Redux => most suitable for app state, universal solution for both Angular and React

So as we can see, Flux Architecture ( via Redux ) is the ultimate solution for both React and Angular in terms of true State separation.

Thanks to this separation, we can write Redux boilerplate once and literally reuse it in both Angular or React. With FLUX architecture, only feature that we’re leveraging in any UI framework is hydration of data to our view ( components ) and rendering.

Libraries

Ok we are almost done. Let’s talk about what libraries can be used in both React and Angular so we can reuse our knowledge.

yarn add redux @angular-redux/store
yarn add reselect

Handling Side Effects

What about handling side effects? Well again, in Angular world, there is another package from ngrx — > @ngrx/effects, which is unfortunately for us, again, coupled to Angular 😢.

Have no fear, universal solution is here:

Redux-observable — RxJS 5 — based middleware for Redux which uses Epics.

yarn add redux-observable rxjs

What is an Epic?

  • Epics are executed after all reducers have been run ( Actions always run through your reducers before your Epics even receive them )
  • Epic needs always return an Action Stream ( Actions in, Actions out — thanks to that, it prevents us to introduce anti-patterns, like for instance, using tap and similar noop operators, for triggering new side effects within effects )
What is an Epic

Http Client

One last thing to cover… How to communicate with our API.

This may be quite controversial, but do you really need that Observables laziness, for executing GET/POST requests agains your API? Especially, when those are executed within Epics/Effects, which use Observables, so you get all that laziness and reactive composition over there? So yeah, probably not, at least I didn't find much use for it in real life projects...

My services for REST endpoints look something like this ( in both Angular/React):

const base = 'users'
class HeroService {
constructor(private httpClient: HttpClient) {}
getOne(id: number): Promise<User> {
return this.httpClient.get<User>(`${users}/${id}`).then(normalize)
}
getAll(): Promise<User[]> {
return this.httpClient.get<User[]>(base).then(normalize)
}
create(payload: NewUser): Promise<User> {
return this.httpClient.post(base, payload).then(normalize)
}
update(payload: User): Promise<User> {
return this.httpClient.put(base, payload).then(normalize)
}
remove(id: number): Promise<boolean> {
return this.httpClient.delete(base, payload).then(normalize)
}
}
Using Promise based Axios within Services simplifies/reduces Epics boilerplate

Summary

In this article we covered what tools, architecture and libraries from React ecosystem can be used for Angular app development and for reusing existing solutions, so in the end we leverage the same tools and knowledge, no matter what rendering solution/Component framework are we using.

Angular and React devs — Best Friends
Better Angular CLI defaults with tools from React ecosystem and beyond

Principal Engineer | Google Dev Expert/Microsoft MVP | @ngPartyCz founder | Speaker | Trainer. I 🛹, 🏄‍♂️, 🏂, wake, ⚾️& #oss #js #ts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store