Skip to content

Commit

Permalink
Merge pull request #2 from Selleo/k1eu/recipes-part-1
Browse files Browse the repository at this point in the history
docs: add glimpse of basic recipes
  • Loading branch information
k1eu committed Jun 7, 2024
2 parents b2786e9 + 26ec8ad commit 9186ede
Show file tree
Hide file tree
Showing 34 changed files with 9,700 additions and 4,185 deletions.
34 changes: 11 additions & 23 deletions docs/docs/index.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
# Overview

Guide book is a set of practices that focus on providing efficient development of web and mobile apps.
This includes the project setup practices, set of patterns, examples of features
so developers can easily add new features without reinventing the wheel.

This includes:

<!-- TODO: for whom is this guide intended?
- application developers
- devops engineers
- business owners and CISOs, CTOs, CIOs, DPOs
- Project setup practices
- Set of patterns
- Full feature examples
- Deployment possibilities

For whom is this guide intended?

## WHAT'S INSIDE
- Tech leads
- Project leaders
- Application developers

TODO: list of topics covered in this guide -->
Every tool mentioned in the docs is a PROPOSAL that has been tested in production, but feel free to use alternatives if you prefer them. Let us also know them (`@mikoscz` `@bart` `@kieu`) so we can also test them and update if necessary!


<!-- ## Commercial offering
We offer:
- Deployment
- Maintenance
- Cloud Transformation
- Consulting
- Cybersecurity
<div class="flex justify-center my-2">
<img src="./assets/certs/aws-solutions-architect.png" alt="AWS Solutions Architect" width="100" height="100" />
<img src="./assets/certs/iso-27001.png" alt="ISO 27001" width="100" height="100" />
</div> -->
Every project part recommendation has been tested in production and if you're taking a diffrent approach on your project, please leave an ADR with the decision and let us know (`@mikoscz` `@bart` `@kieu`) so we can valuate it into our stack.
11 changes: 11 additions & 0 deletions docs/docs/recipes/01-node.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NodeJS

In this guidebook we'll be mostly covering apps created in the NodeJS ecosystem. At the time of writing (25.05.2024) starting new project should use the newest LTS version **Node 20**.

## Managing NodeJS versions

To manage versions between diffrent projects you should be using version manager like [ASDF](https://asdf-vm.com/) or [Volta](https://volta.sh/)

## Locking project into specific NodeJS version

To have source of truth on the Node version for the project it is recommended to use `.tool-versions` (which is BTW a good place for storing many more tool versions).
9 changes: 9 additions & 0 deletions docs/docs/recipes/02-package-manager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Package Manager

For the speed, disk efficiency, workspaces (monorepo) handling we chose to use [PNPM](https://pnpm.io/) as our main package manager.

It flawlessly integrates with Turborepo for the monorepo stuff we're having, offers easier CI management when deploying apps located in the monorepo.

```
TIP: alias pnpm as `p`
```
17 changes: 17 additions & 0 deletions docs/docs/recipes/03-monorepo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Monorepo

One of the advantages of Full Stack Typescript approach is the ability to easily shared the code between the diffrent parts of the systems we're building. And this part is mostly achieved with monorepo approach.

The proposed approach is to use [PNPM workspaces](https://pnpm.io/workspaces) in combination with [Turborepo](https://turbo.build/repo/docs). It offers great flexibility, speed, caching with minimal setup and overhead.

## Starting point

Turborepo has a really great page to get you started [here](https://turbo.build/repo/docs/getting-started/create-new#quickstart).

## Some useful knowledge about turborepo

- You should run the project (typically BE + FE + Proxy etc.) by using `pnpm dev` in the main project directory. You can achive it by having `dev` script in every package that is needed to be started and setting `turbo.json` config file.
- You can use the `cache` in `turbo.json` for tests and lint scripts to save time
- Whenever you have package that should be built before consuming you can use field `dependsOn` in `turbo.json`
- You should be having consistent package versions between your apps/packages
- To install package in correct apps/package you can navigate to its directory and just `pnpm add` inside it or run `pnpm --filter @appname add package`
44 changes: 44 additions & 0 deletions docs/docs/recipes/04.proxy-and-certs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Proxy and certs

Have you ever found yourself in the ports hell? Having multiple applications and looking on which port it is? Or have you ever needed https on your localhost to test specific features? Reverse proxy is here to help! Also you'll get pretty address like `yourproject.localhost`.
For the tool we will use [Caddy](https://caddyserver.com/)

## How to setup Caddy

// TODO: Docker setup?
Caddy can be installed via [Homebrew on MacOs](https://caddyserver.com/docs/install#homebrew-mac),

![Monorepo structure](proxy.png)

Once we got it installed we can create a new folder inside `apps` called `reverse-proxy`(look img above). Inside of it we can create a `package.json` with the following content:

```json
{
"name": "project-reverse-proxy",
"scripts": {
"dev": "caddy run"
}
}
```

Now we are able to create the file called `Caddyfile`. The content should be the following adjust to the project needs and ports.

```
api.project.localhost {
reverse_proxy localhost:3137
}
app.project.localhost {
reverse_proxy localhost:5137
}
mailbox.project.localhost {
reverse_proxy localhost:8025
}
storage.project.localhost {
reverse_proxy localhost:8069
}
```

Last step is to run the `caddy run` in the console manually so it can create the certificates. After that you'll be able to run it with `pnpm dev`
78 changes: 78 additions & 0 deletions docs/docs/recipes/05-external-deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Docker compose

Whenever you need a database or any external server stuff you should be using docker compose in the development for the ease of use and project installation.

## How to add Postgres with Docker compose

To add Postgres via Docker Compose you should add `docker-compose.yml` in you desired application with the following content:

```yml
services:
project-db:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_PASSWORD: projecthjkl
POSTGRES_DB: project
volumes:
- project-db-data:/var/lib/postgresql/data
ports:
- 5438:5432

volumes:
project-db-data:
driver: local
```
This file would setup developmnet postgres instance on port 5438 and a test DB instance on port 5439
## Redis
```yml
services:
redis:
image: "redis:alpine"
ports:
- "6379:6379"
volumes:
- "redis-data:/data"

volumes:
redis-data:
driver: local
```
## How to store files in SWS
To store eg. images in on your local disk and easily expose them you can use Static Web Server
```yml
services:
sws:
image: joseluisq/static-web-server:2.31.1
environment:
- SERVER_ROOT=/uploads
- SERVER_CORS_ALLOW_ORIGINS=https://app.projectname.localhost
- SERVER_CORS_ALLOW_HEADERS=orgin, content-type, cache-control
volumes:
- ./uploads:/uploads
ports:
- 8069:80
```
With this configuration whatever is ./uploads folder will be exposed on localhost:8069
## Mails on localhost
Whenever working with nodemailer you can use Mailhog to inspect the mails you are sending locally.
```yml
services:
mailhog:
image: mailhog/mailhog
ports:
- 1025:1025
- 8025:8025
```
With this configuration you're able to inspect the mails on localhost:8025
Binary file added docs/docs/recipes/proxy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions docs/docs/remix-recipes/01-remix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Remix Intro + Setup

Vite community is huge and Remix intergration with it was the milestone we were waiting for. Now merging the Remix into React Router 7 let's us migrate older projects easier, and have great `framework` environment with patterns for the new apps.

## How to create new apps with remix

The app should be a part of our monorepo, so in the `apps` folder you should run `pnpm dlx create-remix@latest --template remix-run/remix/templates/express`. During creation DO NOT initialize new git repository.
Why are we creating it with Express Template? If we ever want to switch to the SSR it'll be few clicks away already configured.

## Enable SPA mode

This step is optional but recommended for recommended for the Nest + Remix setup. Without it you'll be server rendering your application which we'll be focusing on later.

- in `vite.config.ts` add `ssr: false` to the remix plugin
- in `package.json` replace the dev script with `vite dev`

You should be good to go! You're now able to use remix features such as client loaders, client actions, automatic page code splitting and more!

## Routing

By default Remix uses [flat file based routing](https://remix.run/docs/en/main/discussion/routes#route-configuration). It's not the best convention and we mostly believe in the config based routing as it's easier to work with and provides more flexibility.

To set it up we'd like to create a `routes.ts` file at the top level of remix app with the following content (adjusted with proper file paths):

<i>update sidenote - Remix 3 and React Router 7 will both use the routes.ts syntax as standard</i>

```typescript
import {
DefineRouteFunction,
RouteManifest,
} from "@remix-run/dev/dist/config/routes";

export const routes: (
defineRoutes: (
callback: (defineRoute: DefineRouteFunction) => void
) => RouteManifest
) => RouteManifest | Promise<RouteManifest> = (defineRoutes) => {
return defineRoutes((route) => {
route("", "modules/Landing/Landing.layout.tsx", () => {
route("", "modules/Landing/Landing.page.tsx", {
index: true,
});
route("/about", "modules/Landing/About.page.tsx");
});
route("dashboard", "modules/Dashboard/Dashboard.layout.tsx", () => {
route("", "modules/Dashboard/Dashboard.page.tsx", {
index: true,
});
});
});
};
```

It uses our modules strategy with `.page.tsx` extension for pages and `.layout.tsx` for layouts.

Disclaimer: If you really wanna use file based routing check out [remix-flat-routes](https://github.com/kiliman/remix-flat-routes) package that improves on the basic approaches
21 changes: 21 additions & 0 deletions docs/docs/remix-recipes/02-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# App architecture

Flexibility of React is a great strength and great pitfall. In this chapter we will cover how to store the files, what conventions to use etc.

## Folder organization

Colocation is gonna be the the theme in the described approach.

- Your code should be inside `app` folder in the Remix app.
- `modules` is the most important folder inside where most of your UI and business logic is gonna be living. For example we can have `Auth` module that should have everything related to auth inside of it - from compoents to pages, layout, hooks, it's "util functions".
- `api` folder where we'll be storing all data related to the API communication.
- `components` folder should consist of highly reusable components used throughout the whole app - Button, Input
- `lib` for highly reusable utilities
- `assets` / `locales` are other commonly used folders

## Route components

Route and Layout components should be living in their corresponding modules. Their names should be `module.page.tsx` & `module.layout.tsx` respectively.
It allows for easy fuzzy search while not introducing any specific, not semantic file based syntax.


Loading

0 comments on commit 9186ede

Please sign in to comment.