next + nest를 이용한 풀스텍 프로젝트를 진행해보려한다
기획 내용은 이전 블로그에도 자세히 적진 않았지만 거기에 적어놨고기획 내용은 이전 블로그에도 자세히 적진 않았지만 거기에 적어놨고
일단 따로 레포지토리를 팔지, 모노레포로 팔지부터 고민이 들어가야하는데,
Monolithic Repository의 줄임말
여러 프로젝트, 패키지를 단일 Git 저장소에서 관리하는 방식
즉, 프론트엔드, 백, 공용 코드 등을 하나의 저장소에서 함께 관리하는 것
그러나 단점으론
이러한 모노레포에 대한 도구도 있다고 하는데
장점
단점
다른 것들도 찾아봤는데 엄청나게 큰 차이는 없는데 Next Nest 함께 사용하기 적합하고 학습 곡선도 낮아서 채택하기로 하였다 + 빌드 캐싱 개발 과정 빨라짐
패키지 매니저는 pnpm을 채택할건데
디스크 공간 효율성 뛰어나고 의존성 설치 속도빠르고 npm보다 더 효율적인 성능제공 + turborepo와 함께 사용되어서 채택하였다.
pnpm dlx create-turbo@latest
이것만 설치해도 기본 모노레포 구조 자동 생성해줌
이렇게 알아서 세팅해줬는데
엄청 많은 실행되는 주소가 떴다.
백과 프론트를 같이 실행해야하니 한번에 실행해주는 도움을 주는 부분인 것 같고, 초기화를 시켜야해서
# 불필요한 예제 앱 제거 (create-turbo가 생성한 기본 앱들)
rm -rf apps/docs
rm -rf apps/web
# 필요한 디렉토리 구조 생성
mkdir -p apps/web # Next.js 프론트엔드
mkdir -p apps/api # NestJS 백엔드
mkdir -p packages/ui # 공유 UI 컴포넌트
mkdir -p packages/types # 공유 타입 정의
mkdir -p packages/database # 데이터베이스 관련 패키지
일단 구조가 이렇게 짜지는게 맞는지 아직 모르겠지만 세팅은 챗봇의 도움을 받자 하나하나 공부하면서 검색하면서 하기엔 챗봇이 너무 잘되어있다.
# apps/web 디렉토리로 이동
cd apps/web
# Next.js 프로젝트 생성
pnpm dlx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias="@/*"
그리고 기본 옵션인 next의 tailwind와 app router ts 추가
+turbopack까지
이후 패키지에서 이름 변경
pnpm add -g @nestjs/cli
cd apps/api
nest new . --package-manager pnpm
이후 루트 디렉토리에서 nest 설치 + pnpm까지
여기서도 마찬가지로
@lottodolist/api
로 이름 package.json의 name 수정
여기까지 프론트와 백 구축했고 이제 재사용성을 위한 type, ui, database 패키지도 추가해보려한다
ui쪽은
cd packages/ui
pnpm init
{
"name": "@lottodolist/ui",
"version": "0.0.0",
"private": true,
"main": "./index.tsx",
"types": "./index.tsx",
"exports": {
"./*": "./src/*.tsx"
},
"scripts": {
"lint": "eslint . --max-warnings 0",
"generate:component": "turbo gen react-component",
"check-types": "tsc --noEmit",
"build": "tsup index.tsx --format esm,cjs --dts"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@turbo/gen": "^2.4.4",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"eslint": "^9.22.0",
"typescript": "5.8.2"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
여기선 main, types, build만 추가해주고
types에선
pnpm init
pnpm add -D typescript
까지 해준 후
{
"name": "@lottodolist/types",
"version": "1.0.0",
"description": "",
"main": "./index.ts",
"types": "./index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsup index.ts --format esm,cjs --dts"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"typescript": "^5.8.2"
}
}
.ts로 변경시켜준다
database는
pnpm add prisma @prisma/client
pnpm add -D typescript
prisma를 typeORM보다 많이 쓴데서 일단 추가는 시켰는데 왜 채택해야하는지 자세히 안알아봤기 떄문에 추 후 다룰 예정
{
"name": "lottodolist",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"db:generate": "turbo run db:generate",
"db:push": "turbo run db:push"
},
"devDependencies": {
"eslint": "^8.48.0",
"prettier": "^3.0.3",
"tsup": "^7.2.0",
"turbo": "latest"
},
"packageManager": "pnpm@8.6.10"
}
그리고 root의 package.json에서도 db관련된 명령어 추가
루트 디렉토리에 turbo.json도 있었는데 용도는
세팅을 하면서 pipeline을 쓰라고 권장했으나, 이전 버전의 문법이여서 tasks를 사용하였다.
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"cache": false,
"persistent": true
},
"db:generate": {
"cache": false
},
"db:push": {
"cache": false
}
}
}
이후 ORM 도구로 Prisma를 추천받았는데, TypeORM만 강의로 사용해보았다.
장단점을 비교해보면
그러나
정도다
여기서 GUI는 Graphical User Interface 즉 그래픽 사용자 인터페이스를 의미
그리고 최근엔 Prisma를 풀스택 프레임워크에서 더 많이 선호한다고 하니 Prisma채택!
pnpm add prisma @prisma/client
pnpm add -D typescript
이렇게 설치해주고
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client { provider = "prisma-client-js" }
datasource db { provider = "postgresql" url = env("DATABASE_URL") }
기본 내용은 pnpm prisma init으로 세팅해놨다
Prisma CLI를 사용하여 Prisma 프로젝트 초기화하는 명령
근데 pnpm prisma init으로 설치하면 이미 설치된 prisma 패키지를 ㅅ ㅏ용하려고 하고,
pnpm dlx prisma init으로 설치하면 임시 다운로드로 prisma 설치안되어있어도 사용가능하다는 차이가 있음
이후 공용 패키지로 사용할 것들을 프론트와 백에 각각 추가
프론트
cd apps/web
pnpm add @lottodolist/ui @lottodolist/types @lottodolist/database
백
cd ../api
pnpm add @lottodolist/types @lottodolist/database
여기까지가 말도 많고 탈도 많았던 기본 세팅 끝..!
내용은 서서히 구체화 해볼 예정……..