Let's rework dev !

Quentin LAFFONT

Full Stack JS Developer

 

https://qlaffont.com

           

            @qlaffont

How most projects work ?

BACKEND

- Framework NestJS

- ORM : TypeOrm

- Lib integration : Depends on projects

- Return : GraphQL

 

FRONT

- Framework NextJS

- Query : GraphQL Client

- CSS : Tailwind + HeadlessUI

Inconvenients

BACK

- Use express server under the hood who are not maintained since 2 years

- Current ORM is hard to use, find and select on sub relations is complicated and not strictly typed

- Type generation are not generated from schema

- GraphQL is not optimized on Query fetching (Fetch a request independtly for each Class in case of field resolving)

- If you want to apply update or fix for a lib (ex: file upload), you need to apply it on every project

- Long to develop because we have a strong architecture

Inconvenients

FRONT

- Graph Client is not optimized for caching, no debugger on client, hard to configure, and used only for GraphQL

- Form error validation

   - No global message

   - Some validations are not handle in Schema

   - Validation is not trigger on onChange

- Tailwind Typography Plugin is use in an unrecommended way

- Icons utilization are not well separated (some icon doesn't work because they have the same name)

- Design system depends on Layout and are hard to test

Solutions ?

ALL - Versioning + Quality

 

Use Husky and lint-staged to

- Check security deps before push

- Check linting before commit (TS + ESLINT x Prettier)

- Use the latest node version for new projects

= CODE QUALITY

 

Use Conventional Commit

- Make commit more readable

- Lint commit 

- Changelog Generation + Tag release

ALL - GIT

Stop doing merge and use rebase

- git config --global pull.rebase true

 

Why ?

- Create a commit message for nothing

- Can create merge conflict more frequently

 

Merge Request

- Title : Respect conventional commit message

- Enable squash commits and branch deletion

ALL - RUN

Run every kind of project with the same port

- API -> 3000

 

- WEB -> 3100

- WEB (Admin) -> 3101

 

Create for each project, a run file (ex: launch.json for vscode) to be able to use debugger for client and api.

ALL - ENV + Readme

A README need to be present to

- tell which technologies are used

- required server (Redis, Postgres, etc.)

- How to start project (Local/Preprod/Prod)

 

Environment file need to not be commited !

But, we need to commit a .env.example where we can found all environment variable name

BACK

BACK - Use a modern web

Fastify (https://www.fastify.io)

21K ⭐


Plugins :

- fastify-cors

- fastify-formbody

- gquittet/graceful-server (Shutdown + live endpoints)

- fastify-multer (File Upload)

- fastify-secure-session

- etc.

BACK - GraphQL or Rest ?

If we use GraphQL : (use Mercurius)

- disable all field resolving (to reduce fetching time and complexity)

- all relations are optional

 

If we use Rest :

- document every route with Swagger

- Validate and Serialize with AJV

 

- https://www.fastify.io/docs/latest/Validation-and-Serialization/

- https://github.com/fastify/fastify-swagger

BACK - ORM

Prisma 2 (https://www.prisma.io)

17K ⭐

 

Plugins :

- typegraphql-prisma : Export InputFields/Class/Mutation/Query

- Prisma Studio : Integrated DB Management

Features :

- Auto migration with Prisma Migrate

- Generation of types and connector to DB with Prisma Client

- Seed your database with an independent app

- Simple data management from 1 file + integrated linter

BACK - ORM

Prisma Validation before data is process in DB

 

- Able to display error before processing in DB in dev

- Able to hide easely DB validation error in production

 

https://www.prisma.io/docs/concepts/components/prisma-client/advanced-type-safety/prisma-validator#combining-prismavalidator-with-form-input

 

BACK - Queue Management

Bull (https://github.com/OptimalBits/bull)

11K ⭐

 

Features :

- Synchronized with Redis

- CRON Management

- Concurrency Free

- Repeatable jobs

- Typescript Ready

- Can be manage easily with arena https://github.com/bee-queue/arena

BACK - Architecture

src

   - components (Business logic)

   - loaders (Route resolvers, Graph resolvers)

   - services (Every service without any business logic)

   - types (Typescript types)

   - index.ts


prisma

   - generated (Prisma Client auto-generation)

   - migrations

   - schema.prisma

BACK - Architecture

components

   - name of your business logic (Ex: Post)

      - PostRoutes.ts

      - PostController.ts

      - PostSchema.ts (Who contain Rest Swagger Schema)

      - PostResolver.ts (Who contain GraphResolvers)

      - Post.ts (Types)

      - PostQueue.ts (Who contain Queue Management)

      - PostService.ts

BACK - Architecture

Make global :

- Prisma : to use DB query management

- Loging : to use logging management

 

Logging is managed by Fastify or by Pino.

 

Pino https://github.com/pinojs/pino

8K ⭐

BACK - External Library

Between projects, we have many libraries who are share and not updated cross-projects.

-> Create a library + npm repo

 

- Open Source

- Inside or Outside contributors

- Without any business logic

- Need to be global and able to configure easily

- Tested

 

Ex : Authentication, Mail, Stripe, File Upload, etc.

FRONT

FRONT - Architecture

- locales (Locale file in Typescript)

- pages (NextJS Pages)

- public (Public files)

- services

  - api (Contain all GQL, API Hooks, REST endpoints)

  - hooks (Hooks without business logic)

  - i18n : Lang, Date, Number, Currency

  - store (Global Store, ontext)

 - constants/enums

FRONT - Architecture

- components

   - atoms (Form components, simple)

   - molecules (Specified atoms + linked atoms)

   - organisms (by business logic)

 

- scss

  - icons (who contains all icons files)

  - lib (who contain all css import for libraries + override)

  - app (who contain all special app design)

  app.scss

FRONT - Architecture

Custom Hooks are usefull but we don't need it everytime

 

 

FRONT - Query

React Query https://react-query.tanstack.com

23K ⭐

 

- Better Caching management

- Can generate query and hooks from Codegen

- Have a debugger

- Query agnostic : Can use Rest OR GQL

FRONT - FORM

React Hook Form

- Use revalidateMode and mode options to onChange

- Use devTool for each form (Hide it in production)

 

- Use a hook to return translation key for errors

- Use only YUP schema validation

- Use YUP test function to handle custom validation

 

 

FRONT - Icons

Use a file and a different class for each utilisation

 

- icons.scss (Global Icons), Ex : icon icon-add

- brands.scss (Brands Icons), Ex : brand icon-stripe

- illustrations.scss, Ex : illus icon-happy

 

Every icon files need to have :

- icon- -> Use mask to edit colors

- bg- -> Use bg to use current colors

FRONT - Tailwind

- Use Tailwind Debug screens to debug responsive

- Use Nightwind to handle Dark mode automatically

 

- Tailwind Typography Plugin is currently used in an un-recommended way

 

We need to use this syntax :

 

https://tailwindcss.com/docs/plugins#adding-components

FRONT - Design System

Use Storybook for each atom and molecules components

 

More informations : https://storybook.js.org/docs/react/writing-stories/introduction

DevOps

DEVOPS - Gitlab

For each project

  - Deploy pipeline from master/main (Auto Build & Deploy)

  - Deploy pipeline from preprod (Auto Build & Manual Deploy)

  - Deploy pipeline from prod (Auto Build & Manual Deploy)

 

For each MR

  - Lint pipeline to check if quality is accepted

  - Check deps security criticity

DEVOPS - Deps update

Activate a cron for each projects

- to update dependencies (minor)

- fix security issues

 

-> Renovatebot

DEVOPS - Uptime

Use BetterUptime for :

  - Receive events on API or Client server is down

  - Generate status page if customer need it

Made with Slides.com