혼자서 개발하는 사이트는 어떻게 만들어야 할까? 소프트콘 뷰어쉽 제작기 (2)

정연진·2023년 10월 22일
37
post-thumbnail

소프트콘 뷰어쉽, 스트리밍 뷰어쉽을 한눈에!

https://viewership.softc.one
소프트콘 뷰어쉽은 아프리카, 트위치에서 방송중인 크리에이터들의 정보를 실시간으로 수집하여 해당 크리에이터의 데이터 및 순위를 보여주는 뷰어쉽 어플리케이션입니다.

제공해주는 정보는 아프리카 + 트위치 통합 방송 랭킹, 뷰어쉽 순위 및 크리에이터 별 상세 방송 데이터 등 입니다. 이런 데이터를 바탕으로 광고주, 크리에이터, 시청자 모두가 만족할만한 정보를 확인할수 있게 하는것이 이 사이트의 궁극적인 목표입니다.

요약하자면,

  1. 트위치+아프리카 랭킹 ( 갈드컵 유발용 X )
  2. 광고주 및 객관적인 데이터 확인
  3. 세줄까지는 요약할게 없어용~

이렇게 되겠습니다.

저번 연재에 이어서 이번에는 어떤 순서로 개발이 이뤄지게 되었는지 적어보겠습니다!


어떤 순서로 제작해야할까

아이데이션과 검증은 저번시간을 통해 전부 완료했습니다. 이제 와이어프레임부터 기획해봐야겠죠.
이 프로젝트는 저 혼자 진행하기에 최대한 단순하고 확실한 디자인, 그리고 명확한 기준을 가지고 제작을 진행해야 합니다.

보통 저의 경우 참고할만한 디자인 컴포넌트, 시스템을 참고하고 이에 맞춰 와이어프레임을 피그마로 제작하는 편입니다. 강력하고 유연하며 단순한 디자인 컴포넌트를 생각해보니 제가 자주사용하는 vercel의 디자인이 꽤 괜찮다고 생각이 되더라구요.


카드형태로 만들게 되면 반응형 제작에도 강점이 있고, 사용자들에게 굉장히 깔끔하고 유연한 느낌을 줄수 있을것 같습니다. 그러면 이 형태를 기반으로 피그마로 와이어프레임을 제작해봅시다!

최고의 아이디어를 끌어내기위해 카페인 풀도핑하고 본격적으로 디자인을 시작해보죠.. ☕️

[ ... 제작중 ... ]


자 이렇게 완성되었습니다.

딱 이런 느낌으로 순위를 보여주고 현재 크리에이터가 LIVE면 그에 맞춰 화면을 보여주는식으로 제작해봅시다. 그래프에는 그라데이션도 좀 넣고 굉장히 단순해보이지만 각 크리에이터의 썸네일이 단순해보이는 화면에 화려함을 제공해줄것으로 생각됩니다.

디자인적으로 어색한건 개발하면서 수정하면 되고, 디자인 컴포넌트만 잘 갖춰진다면 나중에 추가하는건 전혀 문제가 없을겁니다.

그럴듯해 보이는군요! 그럼 이제 VS Code를 켜볼 시간이군요

개발 시작

서버부터 개발해봅시다.

이전화에서 말했듯 저는 프론트엔드에 강점이 더 있는 개발자입니다. 서버쪽은 어깨넘어 배웠을뿐 자세히는 잘 모른단 말이죠. nest.js를 사용하여 node 기반의 무언가를 만드는것을 하는건 문제 없지만 그렇다고 본격적으로 DB를 설계하고 만드는 일은 아직 부족한 실력입니다.

그렇다면 vercelserverless Function을 적극적으로 활용해보면 어떨까요?


기존 데이터를 수집하는 크롤링 크론 서버는 aws ec2 인스턴스에서 올려놓고, 해당 DB를 serverless Function 으로 연결하면 완벽할것 같습니다!

오호.. 해치웠나?
( 아님 나중에 문제생겼음 )

자 그러면 이제 next.js를 통해 서버 API와 프론트엔드를 동시에 개발해봅시다!

크롤링을 위한 nest.js 서버

javascript 개발자의 최대의 장점이자 단점

"너 자바스크립트 할줄 알아?"
지금은 장점입니다.

특히 Prisma라는 사용하기 편한 ORM이 있으니 Prisma + nest.js를 이용해서 크롤링 서버를 만들어 봅시다. 일단 여기서 필요한건 딱 1개 입니다. 바로 아프리카TV를 크롤링해서 데이터를 쌓는거죠.

nest.jsplaywright를 이용해서 크롤링하는 첫번째 API가 만들어졌습니다. 물론, API를 사용하지는 않고 cron을 해주는 task.service에서 6분마다 한번씩 해당 서비스를 이용해 데이터를 쌓아주게 됩니다.

// task.service.ts  

@Cron('0 */6 * * * *', {
 disabled: !!process.env.IS_CRAWLING,
})
async crawlingAfreecaTV() {
   this.logger.debug(`[CRON] Crawling AFTV : ${new Date().toISOString()}`);
   const createdAt = dayjs().startOf('minute').toISOString();
   const result = await this.crawlingService.postAPICrawlingAFTV({
     createdAt,
   });
   return result;
 }

이제 DB에 데이터가 잘 들어가는지까지 확인해봅시다.
흠.. 아주 잘 들어가는군요.. 좋습니다!

API의 Next.js, 프론트엔드의 Next.js

next.js로 API와 프론트엔드를 모두 만들어야 합니다.
그렇다면 이참에 Next.js 13App Router를 이용해봅시다.

이번 Next.js 13.4 에서 Stable로 추가된 App router는 새로운 프레임워크라고 할 정도로 대격변이 일어나있는 개발 방법입니다. 기존처럼 /app 폴더의 파일들이 실제 도메인이 된다는것 까지는 비슷하지만 이제는 그 하위에 여러 역할을 가진 여러 파일들이 나뉘어 페이지를 표시합니다.

또한 기존의 getStaticProps, getServersideProps와 같은 구현방식은 완전히 사라지고 async component, fetch 등 새로운 방법을 통해 서버 사이드 렌더링을 구현하게 됩니다.

한 페이지 내부에 일부는 CSR로, 일부는 SSR/ISR 방식으로 구현할 수 있으며 이는 Streaming API를 이용하여 제작되게 됩니다.

기존처럼 더이상 한 페이지 전체를 서버 사이드 렌더링으로 할 필요 없이, 필요한 부분만 서버 사이드로 하고 나머지는 클라이언트 사이드로 렌더링을 할수 있게 만든다? 정말 혁신적이죠!

물론.. 안정적이라고는 하지만 여러 버그도 존재합니다! 13.5에서는 많이 개선되었구요.
어차피 Next.js 는 이 방향으로 갈것 같고 미래이기도 하니 한번 사용해보는것도 좋다고 생각합니다!

이제 Next.js 13 에 대한 설명은 충분한것 같습니다.
이제 개발해보죠!

API, prisma와 함께

// Prisma ORM
await prisma.user.create({
  firstName: “Alice”,
  email: “alice@prisma.io”
})

프리즈마, 최고죠.

nest.js에서도 쓰지만 이를 그대로 next.js에서도 사용할 수 있습니다.
동일한 DB를 사용하기 때문에 이 ORM을 그대로 next.js에서 이어서 사용할 수 있습니다.

빠르게 서버 API를 만들어 갑니다.

디자인 CSS

vercel에서 사용하는 UI를 차용하여 개발합니다.
극한의 효율성을 위해 <button> <h1> <input> 등 아주 기본적인 시멘틱 태그에 CSS를 입혀 어떤일이 있더라도 기본적인 태그를 이용하여 모든것을 만들도록 합시다.

button {
  background-color: inherit;
  border: none;
  color: inherit;
  cursor: pointer;
  transition: 0.15s;
  margin: 0;
  padding: 0;
  text-align: left;
}

button:hover {
  transition: 0.15s;
  box-shadow: inset 0px 0px 999px 5px rgba(255, 255, 255, 0.05);
}

button:active {
  transition: 0.15s;
  transform: scale(0.97);
}

이렇게 하면 모든 버튼엔 동일한 효과가 발생하게 됩니다.
hover시에는 연한 하얀색의 호버 효과가, 누를시에는 버튼이 살짝 작아지는 효과가 구현됩니다.

가장 이상적이고 효율적인 방법입니다. 이 프로젝트는 디자인을 위한 개발이 아닌 개발을 위한 디자인이 핵심입니다!

프론트엔드, Server Component + Client Component

// page.tsx

export default async function LiveTopViewersGraph({
  flex = 2,
}: {
  flex?: number;
}) {
  const all150 = await getStatsTopViewers();
  ...
  
  return (
    <div>
      ...
      <LiveTopGraph data={all150} />
    </div>
  )

그리고 사용하는 클라이언트 컴포넌트는 아래와 같이 작성합니다.

// LiveTopGraph.tsx
'use client'

export default function LiveTopGraph({
  graphData,
  colors,
}: {
  graphData: any;
  colors?: string[];
}) {
  return (
    <ResponsiveLine
      curve='cardinal'
      data={graphData}
      margin={{ top: 20, bottom: 20, left: 24, right: 24 }}
      xScale={{ type: 'point' }}
      yScale={{
        type: 'linear',
        min: 0,
        max: 'auto',
        reverse: false,
      }}
      ...

여기에 <Suspense> 를 이용하면 SSR에서도 로딩 UI를 구현할수도 있습니다!

이번 Next.js는 아주 잘 만들어 졌군요... 너무 좋습니다!

개발 완료. 근데 이게 끝은 아니지?

총 걸린시간은 다음과 같습니다.

  • 서버 + 크롤링 : 1주
  • 디자인 : 2일
  • 프론트엔드 개발 : 1주
  • 배포 : 2일

( 참고로, 워킹타임을 계산하는 하루 8시간 X 5일이 아닙니다! 하루 18시간 X 6~7일 입니다 )

저의 모든시간을 갈아 넣어 3주가 지나니 기획에 부합하는 사이트가 배포되었습니다!


( 처음 완성된 사이트, 아프리카만 수집하고 오늘 통계 탭만 존재하고 있습니다 )

와우! 👏
눈물이 찔끔 나는군요 ㅠ

만약 이 프로젝트가 개발용 프로젝트였다면 여기서 연재를 마쳐도 되겠습니다만, 저는 이 사이트를 오래 유지하고 홍보하고 싶기 때문에 아직 더 해야할일이 많습니다.

일단 추가로 진행해야되는 사항은 다음과 같습니다.

  • 트위치도 수집
  • 인포그래픽 제작
  • 방송 랭킹 제작
  • 블로그 추가
  • 유튜브도 수집
  • 애드센스 추가

이제 순서대로만 진행하면 될것 같습니다.

아주 순조롭습니다..
너무 순조로운데요?

( 다음화에 계속 )

profile
소프트콘 뷰어쉽 절찬리 운영중! https://viewership.softc.one

8개의 댓글

comment-user-thumbnail
2023년 10월 23일

와 진짜 고생 많이 하셧겠네요.. 저걸로 아프리카 지원하면 좋을듯요 ?

1개의 답글
comment-user-thumbnail
2023년 10월 23일

유익한 글 잘 읽었습니다.

1개의 답글
comment-user-thumbnail
2023년 10월 27일

혼자서 서비스를 만드시다니 정말 대단하신 것 같아요!
다음화가 기대됩니다 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 10월 28일

재밌는 글 감사합니다! 많이 배웠습니다~

답글 달기
comment-user-thumbnail
2023년 10월 30일

이런 서비스를 개발하실 생각을 어떻게 하게되시는건지 궁금하네요! ㅋㅋㅋ혹시 인사이트를 얻는 방법이 따로 있으신지 너무 궁금합니다!

답글 달기
comment-user-thumbnail
2023년 11월 29일

운영해도 되겠는데..?생각하는데 소개란에 이미 운 영 중!

답글 달기