Behind 1k stars repository 😂

Frontend Engineer

AngularAir - 21 Nov 2020

About me

Hi, My name is Trung 😊

  • Experienced FE engineer, specialized in branding, interactive application
  • Frontend Engineer @cakedefi
  • Organizer @Angular Vietnam
  • Write, code, and talk about Angular
  • Biggest Angular group in APAC
  • Advocate and grow the Angular developer community in Vietnam
  • 13k members
  • Founded in 2017 by
  • 100 Days Of Angular series

Agenda

  • What is Angular Jira Clone?

  • Motivation

  • High Level Architecture

  • Technical Decisions

    • ​TailwindCSS

    • ngrx vs Akita

    • Deploy to Netlify/Heroku

  • Q&A

What is Angular Jira Clone?

Motivation

  • There are Angular examples on the web but most of them are way too simple
  • Experiment what I wanted to try for a long time: Akita, TailwindCSS, ng-zorro
  • Demonstrate my experience after working with Angular for four years
  • Part of our technical series angular-vietnam/100-days-of-angular - only available in Vietnamese 🤓

Techstack

High Level Design

TailwindCSS 

A utility-first CSS framework packed with classes like flex, pt-4, text-center and rotate-90 that can be composed to build any design, directly in your markup.

5/10 Front end engineer that I know don' really enjoy writing CSS

Trung Vo

Why TailwindCSS? 

I always encounter some use case where I need to set a simple CSS

 

padding-left: 5px
margin: 0 auto
cursor: pointer

1. Quick and dirty way: inline style

<button style="padding-left: 5px;">Submit</button>
<i style="cursor: pointer;"></i>

✅ Quick

❌ Difficult to override
❌ Messy code base

2. Create a new class for each element 

<button class="my-button">Submit</button> 
<i class="fa fa-help my-icon"></i>

✅ More structure code,
✅ Encapsulated in a component

❌ If scoped inside a component, won't be able to reuse

.my-button {
  padding-left: 5px;
}

.my-icon {
  cursor: pointer;
}

3. Create a common CSS on a top-level component

<button class="pl-1">Submit</button> 
<i class="fa fa-help pl-1 icon-active"></i>

✅ Can reuse the class

❌ Need to spend effort to structure CSS code
❌ Difficult for team member to follow without guideline

.pl-1 {
  padding-left: 5px;
}

.icon-active {
  cursor: pointer;
}

4. TailwindCSS

✅ Clear documentation with most of the util class written

✅ Maintain by a big community

✅ Integrated IDE support

✅ Support PurgeCSS, only load what you actually use for production bundle

✅ Reuse the same class, bundle size could be smaller

✅ Easy customization

Learning curve for new team member

TailwindCSS @apply

<button
  class="bg-transparent 
    text-blue-700 
    font-semibold 
    hover:bg-blue-500 
    hover:text-white 
    hover:border-transparent
    py-2 
    px-4 
    border 
    border-blue-500
    rounded"
>
  Submit
</button>
.btn-tailwind {
  @apply bg-transparent text-blue-700 font-semibold py-2 px-4 border border-blue-500 rounded;

  &:hover {
    @apply bg-blue-500 text-white border-transparent;
  }
}

TailwindCSS @apply

TailwindCSS + Jira Layout

Content

Sidebar

Nav

TailwindCSS + Layout

TailwindCSS + Layout

State Managment: Akita vs ngrx

✅ Avoid state manipulation everywhere
✅ Predictable data flow
✅ Easy to isolate bug
✅ Consistent when dealing with asynchronous

NOT an easy concept to grasp.

What is state?

  • The data (whatever that is!).
  • All the variables in all the of the components.
  • All the variables in the entire application.
  • A store, like a Redux or Flux store.
  • The behavior of the app at a given moment in time (this is my definition!).

When you should use state management?

When you should use state management?

<ProjectComponent [data]='data'>
  <BoardComponent [data]='data'>
    <BoardDndComponent [data]='data'>
      <BoardDndListComponent [data]='data'>
      </BoardDndListComponent>
    </BoardDndComponent>
  </BoardComponent>
</ProjectComponent>

When you should use state management?

When you should use state management?

What is state management?

  • Provides with tools to create the data structure
  • Provides a way to update them when the new actions occur
  • Provides development tool

ngrx

Why not NgRx? Too much boilerplate

Let’s start with the boilerplate issue. Whenever I needed to use ngrx, I had to:

  1. Create a set of actions.
  2. Create a reducer function with a big switch statement.
  3. Add the reducer to the StoreModule.forRoot or StoreModule.forFeature call.
  4. Call select function in my component or create selectors to get the current state.
  5. Call the dispatch function to dispatch an action.

Why not NgRx? Fetch Data

  • Add an action that will be dispatched when data needs to be:
    • Fetched
    • Finished successfully
    • Failed
  • Add an Effects class that will call the data service

It’s not a big problem if it’s not often needed. But fetching data from API is what front end dev do, though!

Too many concepts

RxJS

Angular

Modules

Dependency Injection

Components

Service

Observable

Decorator

switchMap

concatMap

whateverMap

Subject

BehaviorSubject
ReplaySubject

ngrx

Action

Dispatcher

Reducer

Effect

Selector

Akita

A state management pattern

  • Built on top of RxJS
  • Encourages simplicity, less boiler plate
  • Based on object-oriented design principles

Akita

Deploy to Netlify

Netlify is an automation platform for web projects that is focused toward frontend developers.

The main features include continuous integration out of the box, free SSL, and CDN. The platform is great of the easy of use, fast deployment, and continuous integration.

I used Netlify to host the frontend

Heroku

Heroku is a cloud application platform

Heroku lets app developers spend 100% of their time on their application code, not managing servers, deployment, ongoing operations, or scaling.

I used Heroku to host my API

Demo

Q&A

Thank you!

Special thanks to Connie Leung 😁

Behind a thousand stars repository

By Trung Vo

Behind a thousand stars repository

Deck for talk.js #40 https://github.com/SingaporeJS/talk.js/issues/40

  • 3,382