[포스코 x 코딩온] 개인 프로젝트 회고

sima·2023년 10월 25일
0

KDT web-8

목록 보기
16/17
post-thumbnail

프로젝트 명

StackoBunflow

프로젝트 진행 기간

2023.10.09 ~ 2023.10.19(11일)

개발환경

Language, Framework - Javascript, React, Bun, Elysia, Prisma
DataBase - MySQL
Devops - AWS EC2, AWS RDS, Git Action, Nginx, WSL

프로젝트 URL

http://13.124.203.107

Github Repository URL

Server - https://github.com/papicc45/StackoBunflow_server
Client - https://github.com/papicc45/StackoBunflow_client

프로젝트의 주제선택 이유

간간히 유튜브를 통해서 최신기술스택이 어떤게 나오는지 보던 중, 새로운 자바스크립트 런타임 환경인 Bun이 나왔다는 영상을 접하였다. Bun은 기존 자바스크립트 언어로 백엔드 개발을 지원하기도 했었고,
정말 최근에 나온 기술들을 사용해보고 싶었지만, 쉽게 접근할 수 없었는데 이번엔 간단하게라도 할 수 있을것 같아서 개인적으로 개발을 시작했었다.
개발도중 문제상황을 마주할 때 공식문서 말고는 거의 레퍼런스할 자료들이 없었고, 마침 React를 활용한 개인 프로젝트 기간도 얼마 남지 않아 개발자들의 최대 질문 커뮤니티인 StackoverflowBun을 합쳐 Bun 환경에서 개발을 하는 개발자들을 위한 질문 커뮤니티 StackoBunflow 라는 주제로 개발을 하게되었다.

여담

사실 이번 프로젝트에서는 React를 사용하여 프론트엔드만 프로젝트를 진행했어야 했는데, 짧은 기간의 개인 프로젝트이기도 하고 백엔드가 없는 프로젝트는 메리트가 없다 생각해 정말 간단히 풀스택으로 진행하였다. 회고를 작성하기 전, 먼저 내가 사용한 기술에 대해 잠깐 소개하겠다.

Bun이란 ?


공식 사이트 - https://bun.sh

공식 사이트에 자세히 나와있긴 하지만.. 간단히 설명하면
Node, Deno와 같이 자바스크립트 런타임 환경 패키지이다. 자바스크립트 코어 기반으로 구축되어있고, Zig 언어로 개발되어 상당히 빠른 동작속도를 제공한다.
Node 환경에서 사용하던 npm 명령어를 bun으로 패키지 설치를 할 수 있으며, 설치, 실행속도가 npm보다 25배 빠르다고한다..(그정도까지인진 모르겠지만 사용해보았을 때 정말 빠르긴 했다)
Node와 호환성이 좋아 Node에서 사용하던 패키지들을 대부분? 사용할 수 있다고 한다.
타입스크립트 파일도 설치없이 바로 실행이 가능하고, nodemon과 같은 자동 재실행 기능이 내장되어있다. 추가적으로 웹소켓이나 파일처리, 암호화, 테스트, sqlite 내장 DB, 환경변수 바로 사용가능 등 여러 편리한 기능들을 기본적으로 제공한다.

Elysia란 ?


공식 사이트 - https://elysiajs.com

타입스크립트 기반, Bun 환경에서 사용하는 웹서버 프레임워크이다.
기본적인 구조는 express와 비슷하며, 공식문서에서는 Elysia가 Performance, Simplicity, Flexibility를 강조하였는데... 그냥 그럭저럭 사용할 만 하다.
사용 방법은 뒤에 회고에서 말하겠다.

전체 회고

WSL을 사용하여 Bun 개발환경 구성

일단 본격적으로 프로젝트기간이 되기 전, 미리 사용할 기능들을 구현해놓기 위해 개발환경을 만들어놔야했는데, 문제는 Bun이 아직 MacOS, Linux환경만 지원하고, Window는 아직 지원하지 않는다. 이에 대한 해결책으로, Window10 버전 이상부터 지원하는 WSL을 이용해야 한다.

WSL은 리눅스용 윈도우 하위 시스템으로, Window10, 11에서 네이티브로 리눅스 환경을 사용하기 위한 계층이다.

윈도우 시작 버튼, 검색창에 Microsoft Store를 검색하고 들어가면,

이러한 화면을 볼 수 있는데, 검색창에 wsl이라고 치면 Ubuntu를 설치할 수 있는데, 중요한건 그냥 Ubuntu를 설치하는게 아닌 최신에 가까운 버전을 설치해야 한다. 개발환경을 처음 만들 때 Ubuntu를 설치하고, Bun까지 설치해 프로젝트를 생성하였는데, 타입에러가 발생하였었다. any로 타입을 지정해줘도 에러를 해결할 수 없어 몇일동안 해결책을 찾지 못하다가, 처음부터 다시 해보자는 생각으로 설치부터 시작하였는데, LTS버전이 아닌 그냥 Ubuntu가 설치되어있었다.
LTS버전으로 설치하고 다시 프로젝트를 생성해보니 에러없는 프로젝트를 만날 수 있었다.

정상적으로 Ubuntu에 접속을 했다면,
sudo apt-get install unzipcurl -fsSL https://bun.sh/install | bash
순으로 Bun을 설치해 주면 된다.


Elysia 프로젝트 생성

Ubuntu에 Bun을 설치해주었다면,
bun create elysia "projectname" 명령어로 Elysia 프로젝트를 생성할 수 있다. 이제 이 프로젝트를 로컬에서 Intellij로 열어주면 된다.

Intellij 실행 후, Open Proejct의 여러 경로들 중,

C드라이브 아래 깔아두었던 Ubuntu를 찾을 수 있다. 해당 프로젝트 경로 클릭 후 OK

추가적으로 터미널 경로도 바꿔줘야 하기때문에, FileSettingsToolsTerminal 순서대로 들어가면,

이러한 창이 뜰텐데, Shell path에 설치한 Ubuntu로 바꾸고 OK

Prisma 설치


Prisma는 자바스크립트, 타입스크립트 기반 ORM 프레임워크이다.
이번 프로젝트를 진행하면서 유튜브와 공식문서를 거의 참고하였는데, 유튜브를 참고하면서 알게된 프레임워크다. 사실 처음엔 Bun의 sqlite, sequelize도 사용해서 테스트를 해봤는데, sqlite는 DB에 데이터 Insert까지는 했는데 직접 눈으로 확인하는 방법을 찾지 못했고, sequelize는 이미 한번 사용해봤기 때문에 Prisma를 선택하게 되었다.

뒤늦게 알게됬는데, 최근 1년간 javascript ORM 중에서 Git Stars 1등이다.. 그리고 drizzle-orm 도 최근 엄청나게 인기가 많은 ORM인데, 아무래도 typeORM 사용자들이 prisma, drizzle로 빠지는 추세인 것 같다. 나중에 기회가 되면 써봐야겠다는 생각이 들었다.

각설하고, Bun 환경에서 prsima를 설치해보자.

터미널에서, bun add prismabunx prisma init --datasource-provider mysql 순으로 진행하면,

루트 디렉토리에 prisma/schema.prisma 파일이 생성되고, .env 파일에 환경변수로 사용할 DB 정보들을 적어주면 된다. 환경변수에 들어갈 값은
선택한db://계정id:비밀번호:url:/스키마명 순으로 작성하면 된다.


Elysia, Prisma 사용해 API 구현

Prisma DB 테이블 생성

먼저 직전에 작성했던 prisma/schema.prisma 파일 아래부분에 테이블과 컬럼들을 작성해준다.
각 테이블엔 필수적으로 @id@unique를 하나 가지고있어야하며, 연관관계 매핑 1:N일 경우, 1에서 N 테이블을 필드에 배열로 선언하고, N 테이블에서 @relation을 사용해 참조할 컬럼, 자신 테이블에 어떤 필드로 사용할 것인지 명시해준다. 연관관계를 맺고 싶을 경우, 위의 datasource db 부분에 relationMode = "prisma"를 작성해줘야 한다.

다 작성하였으면, 터미널에 bunx prisma migrate dev --name init 명령어를 실행시켜 마이그레이션을 진행해주면

prisma/migrations 경로 안에 정상적으로 실행된 걸 확인할 수 있다.


미들웨어 정의

Elysia 프로젝트를 생성했다면, 위와 같은 index.ts 파일이 생성된다. 이번 프로젝트는 몇가지 간단한 기능들만 사용할 에정이니, 코드분리를 하지 않고 바로 진행하였다.


new Elysia()로 서버를 생성하고, 미들웨어를 메서드 체이닝과 같은 방법으로 정의한다. use() 함수로 미들웨어를 적용하는데, 내 프로젝트엔 CORSPrismaClient, jwt, cookie를 적용시켰다. express를 사용할 땐 생성만 해도 바로 사용할 수 있었는데, Elysia는 미들웨어에 사용하겠다고 정의해야 뒤에 나올 요청 context 에서 가져와 사용할 수 있다.
decorate() 함수는 첫번째 인자로 String 키값, 두번째 인자에는 콜백함수를 받는데, 개발 중 반복적으로 쓰이는 로직들을 미들웨어에서 정의하여 사용한다. 이렇게 하면 여러 api에서 정의해둔 키값으로 호출만 해주면 콜백함수에 정의한 로직을 수행할 수 있다.
이런식으로 매핑된 키값으로 함수를 호출하는 방식이다.


api 작성

Elysia에서는 group() 함수로 라우팅을 할 수 있다. 리턴받는 app 에서 CRUD를 작성하면, group 함수의 첫번째 인자의 url에 이어서 명시가 된다. (/user/signup)
Elysia 역시 마찬가지로 GET, POST, PATCH, DELETE 로 api를 작성한다. 이 함수들의 두번째 인자로는 특이하게 context라는 객체를 받는데, 이 객체 안에는 request에 들어가는 body, param, query string, headers, form-data 등 필요한 것들이 다 들어가 있다. 추가적으로 미들웨어에서 정의한 외부 모듈(jwt, db...)도 들어가는 것을 확인할 수 있다.
비밀번호 암호화는 Bun에서 기본적으로 제공하는 암호화를 사용하였다.
데이터 액세스를 마치고, 응답을 보내줄 땐 그냥 return을 사용하여 응답을 보내주면 된다.
마지막으로, HTTP 함수의 세번째 인자로 요청을 받은 값들(body, param, headers...)의 Type을 정의해줘야 한다. Elysia를 사용하면서 가장 불편한 부분이였는데, 각각의 함수마다 계속 나열하여 정의하는게 너무 지저분했기 때문에
이런식으로 외부 파일에 정의를 하고 내보내는 식으로 작성하였다. 타입을 지정할 때는 Elysia에서 제공하는 t를 사용하여, 객체인지, 숫자인지, 문자열인지 등 body에 담아 보낸 값들 하나씩 전부 다 타입을 지정해줘야 한다.
이런식으로, 외부모듈이 아닌 것들은 안에 들어있는 값까지 다 타입을 지정해줘야한다.


Pagination, join

프로젝트의 기능 중 질문들을 키워드를 통해 검색할 수 있는데, 동시에 페이징처리도 구현하였다.
Prisma에서 페이징처리는 skiptake를 사용하여 구현할 수 있는데, skip 값만큼 넘기고 take 값 만큼 가져온다는 의미이다.

질문의 상세내용을 보는 기능인데, 질문에 대한 답변과, 사용자가 해당 답변추천 유무를 알기 위해 관계되어 있는 answer 테이블과, 또 answer와 관계되어있는 recommend 테이블의 컬럼들을 가져와야 했다.

애플리케이션 실행


Bun 환경에서 프로젝트를 생성했으면, package.json의 script에 기본적으로 위와 같이 작성되어있다.
bun run dev 명령어로 애플리케이션을 실행시킬 수 있고, 자세히 보면 --watch라고 적혀있는 것을 볼 수 있는데, 이는 Bun에서 기본적으로 제공하는 모드로, nodemon과 같이 소스코드에 변화가 있을때 자동으로 감지해 애플리케이션을 재실행해주는 역할을 한다.


React 사용하여 Front-end 구현

사실 이번 프로젝트의 메인 기술스택이었어야 했다. 그러나 백엔드 개발을 희망하는 나에게 백엔드 없는 프로젝트는 의미가 없다 생각하여 Bun, Elysia를 사용하여 간단히 백엔드를 구현했고, 프론트엔드에서는 학습했던 것들 전체적으로 다 사용해보면서 이해하는 것을 목표로 하였다.
이번 회고에서는 간단하게 어떤 라이브러리를 사용해 적용시켰는지만 간략하게 작성하겠다.

React-quill

개발하면서 생긴 문제에 대한 질문을 해야하기 때문에, 일반 텍스트가 아닌 코드블럭이 있는 에디터를 사용해야 했었는데, React-quill을 사용하여 구현하였다. 추가적으로 벨로그에서 사용하는 백틱처럼 간단한 단어나 한줄코드도 표현하고 싶어 inlineCode를 확장해 추가시켜줬다.


zustand

부트캠프에서 전역상태관리로 redux를 학습하였었다. 마찬가지로 프로젝트 초기엔 redux를 사용하여 전역 상태관리를 하였었는데, 적용시킬만한 라이브러리가 없나 찾다가 zustand를 발견하게 되었다.
zustand의 createset 으로 정말 간단하게 상태관리를 할 수 있다. redux에서는 createSlice, reudcer, store 를 사용하여 복잡하게 구현하였었는데, zustand에서는 그런거 필요없이 create 하나면 전역으로 상태관리를 할 수 있다.


React-js-pagination

패키지 설치만 하면, 간단하게 페이지네이션을 적용할 수 있는 라이브러리이다.
activePage 에서는 useState로 page 상태관리를 하며, pageRangeDisplayed는 화면에 몇 개의 페이지를 보여줄 지 명시해줄 수 있다. prevPageTextnextPageText 는 페이지 번호 양옆에 아이콘같이 구성할 수 있으며, 다음, 이전페이지로 넘어가게 해준다.
onChange로 페이지 변경에 대한 핸들링을 할 수 있는데, 해당 컴포넌트에선 useEffect()의 의존배열로 page를 추가해줬기 때문에, page값만 바꾸어 api를 요청하는 방식으로 구현하였다.


후기

사실 정식 릴리즈된지 1달밖에 안된 개발환경에서 프로젝트를 진행한건 위험한 도전이었다고 생각하지만 이번 도전을 계기로 새로운 프레임워크, ORM을 사용해볼 수 있어서 나름 얻은게 있는 것 같다.
프로젝트 기간이 시작하기 전 Elysia를 써보면서 미리 백엔드를 어느정도 구현해놨고 수정할 일이 거의 없을줄 알았는데, React로 프론트엔드를 구현하면서 정말 많이 수정하였었다. 다행히도 Git Action으로 배포를 자동화해놓아서 어느정도 불필요한 시간을 줄일 수 있었다.
React로 프론트엔드 개발을 하며 부트캠프에서 학습했던 것들을 전부 다 활용을 해서, 어떤식으로 구상을 해야하는지 감을 잡을 수있었지만, 마감시간이 다가오면서 Component 분리를 완벽히 하지 못해 너무 아쉬웠다.
그리고.. Bun과 Elysia는 이렇게 개인 프로젝트로 사용하기엔 정말 나쁘지않고, 오히려 다른것들보다 좋은 면도 있었다. 하지만 아직도 버전업데이트를 하며 개발중이기 때문에 좀 더 안정적으로 자리잡았거나 사용하는 사람들이 많아졌을때 사용해도 괜찮을 것 같다는 생각이 들었다.

0개의 댓글