탕스로그
5주차 미션 : nextJS로 netflix 클론코딩 본문
5주차 미션은 무려 팀 미션!!! 후에 한달동안 프로젝트를 같이 하게 될 나의 프론트메이트.. 채연이와 개발을 하게 되었다.
그리고 이번 미션은 nextJS를 이용해서 SSR을 적용한 netflix 페이지를 만드는 것이었는데..!
난 nextJS를 말만 들어봤지 전.혀 써본 적이 없기 때문에 ㅎㅎ 엄청난 시련을 겪게 되었다...
우리의 야무진 개발 타임라인은 다음과 같았다.
개발 타임라인
11/7 ( 월 ) : 첫 회의.. 파트 나누기
11/8 ( 화 ) : 페이지, 컴포넌트 레이아웃 잡기 완료
11/9 ( 수 ) : nextJS 공부 -> 서버 연결 완료 (?)
이렇게만 보면 우리의 일이 수월했겠지만..
난 nextJS만 쓰면 얘가 알아서 SSR을 해주는 줄 알고 그냥 fetch를 박아서 서버 연결을 해버렸던 것이었다..ㅎ
왠지 너무 쉽더라... 오늘의 교훈 인생을 날로 먹지 말자 ⭐️
완성한 줄 알고 신나서 운영진이 주최한 게더타운 스터디에 들어갔는데..
fetch를 냅다 박으면 안된다는 말을 듣고.. 수요일 밤 11시부터 나의 고군분투가 시작되었다.
어려웠던 점
1. getData
nextJS 버전이 12->13으로 올라가면서 getServerSideProps가 아니라 getData를 쓰도록 권장(?) 하는 듯 했다.
https://programming119.tistory.com/273
이 글에 정리가 잘 되어있더라!! 위 글에서 Data Fetching 부분만 보면 된다.
근데 getData()를 썼을 때의 문제점은..
// app/page.js
async function getData() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
return res.json();
}
// This is an async Server Component
export default async function Page() {
const data = await getData();
return <main>{/* ... */}</main>;
}
이런 식으로 Page를 async 컴포넌트로 써야하는데, 이렇게 되면 서버 오류가 뜬다는 것이었다.
아니 예제에선 async를 썼는데 내 파일에선 왜 안돼..?
그렇다고 async await을 빼버리면 json 형식이 아니라 promise가 반환되어 버리기 때문에
빼면 안되고.. 그렇다고 넣으면 또 오류나고.. 총체적 난국이었다.
이에 대한 해결방안은 아직도 찾지 못했다..
그래서!! getServerSideProps를 써서 SSR을 적용하기로 했다..ㅎㅎ
2. getServerSideProps
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props
위 공식문서의 말로는,
function Page({ data }) {
// Render data...
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
export default Page
와 같이 내가 api 연결을 원하는 페이지에서 getServerSideProps()를 쓰면 되는 듯 한데,
여기서 나의 궁금증은 다음과 같았다.
getServerSideProps()에서 리턴해준 data를 Page에서 어떻게 받아오는거지...?
-> nextJS가 알아서 해준다고 한다 ㅎ
pages 폴더 아래에 home.tsx 같이 선언하면 알아서 "/home" 으로 주소 설정해서 라우팅 해줄때부터 알아봤어야하는건데...
nextJS가 상당히 친절한 도구라는 것을 깨닫게 되는 하루였다 ㅎ
/pages/home.tsx
export default function Home( { latest, now_playing, popular, top_rated, upcoming } : any) {
console.log(latest);
// ...
}
export async function getServerSideProps() {
let res = await fetch(`${api}/movie/latest?api_key=${apiKey}`)
const latest = await res.json()
res = await fetch(`${api}/movie/now_playing?api_key=${apiKey}`)
const now_playing = await res.json()
res = await fetch(`${api}/movie/popular?api_key=${apiKey}`)
const popular = await res.json()
res = await fetch(`${api}/movie/top_rated?api_key=${apiKey}`)
const top_rated = await res.json()
res = await fetch(`${api}/movie/upcoming?api_key=${apiKey}`)
const upcoming = await res.json()
return { props: { latest, now_playing, popular, top_rated, upcoming } }
}
위는 내가 짠 코드인데... 여기서도 문제가 발생했다.
바로 콘솔로그를 찍으면 undefined가 뜬다는 것...
아니 자동으로 해준다며!!! 왜 선언되지 않았다는건데!!!! 하면서
아무리 코드를 뜯어봐도 잘못된 것을 발견하지 못했다...
그러던 도중 ⭐️세오스 프짱이⭐️의 빛과 같은 손길이 내려왔다.
_app.tsx에.. PageProps가 안 되어있어!!
아니 글쎄.. 원래는 nextJS 초기 세팅을 하면 _app.tsx에
const App = ({ Component, pageProps }: any) => {
return (
<>
<Component {...pageProps}/>
</>
);
};
export default App;
와 같이 저 pageProps가 들어있어야 하는데...
내 파일은
const App = ({ Component }: any) => {
return (
<>
<Component/>
</>
);
};
export default App;
이렇게 pageProps가 빠져있던 것이었다...
내가 초기세팅 후에 뭔 생각으로 저 코드를 뺐는지 아직도 모르겠다.
나의 프론트메이트에게 무한 사죄를..
저 pageProps를 넣고 나니 콘솔로그가 너무나도 잘 찍히더라...ㅎ
이렇게 나의 우여곡절 SSR 적용기가 끝이 났다.
Key Questions
1. Server Side Rendering과 Client Side Rendering의 차이
Server Side Rendering
SSR은 클라이언트가 웹 페이지를 렌더링하는 것이 아니라 서버에서 웹 페이지를 생성해서 클라이언트는 이를 가져와서 띄우는 방법이다.
서버에서 웹 페이지 정보를 모두 가지고 있기 떄문에 서버가 무거워지고 서버 비용이 증가한다는 단점이 있으나
서버가 가지고 있는 웹 페이지 정보를 검색엔진이 인식할 수 있기 때문에 SEO를 통해 네이버, 구글 등에 웹 페이지가 쉽게 노출될 수 있다는 장점이 있다.
Client Side Rendering
서버는 클라이언트에게 HTML, JS 정보만 보내주고 클라이언트가 이를 받아 브라우저에서 직접 페이지를 렌더링하는 방법이다.
서버가 가벼워지고 서버의 성능에 신경쓰지 않고 페이지를 개발할 수 있다는 장점이 있으나
클라이언트가 직접 페이지를 렌더링하기 때문에 페이지의 초기 로딩 시간이 길고 SEO가 잘 되지 않는다는 단점이 있다.
2. SEO란
SEO란 검색 엔진 최적화를
이 SEO를 위해 개발자는 구글, 네이버 등에 자신의 페이지가 상위에 노출되기 위해
태그, 링크 구조를 개선하여 검색 엔진이 자신의 페이지를 잘 검색할 수 있도록 해야한다.
SEO를 위한 작업들
- <title> 태그 안에 너무 긴 텍스트를 넣지 않고 모든 웹페이지의 title에 단일한 제목을 사용하지 않아야 한다.
- 태그 안의 요소는 자신의 웹페이지가 노출되었을 때 제목 바로 밑에 뜨는 한 두줄 정도의 요약 문장을 의미한다.
가독성을 고려해서 작성하자. - Open Graph 태그 안의 요소는 웹 페이지가 공유될 때 어떻게 노출될지를 알려준다.
이 요소를 잘 정의해놓아야 트래픽이 증가하고 이런 트래픽 증가는 검색 상위 노출을 위한 평가에 영향을 준다.
3. 전반적인 협업 과정
- 이번 협업에서는 깃허브에서 organization을 생성한 후 레포 안에서 각자 브랜치를 생성해 각자 맡은 부분을 개발한 후 주기적으로 머지하는 방식으로 진행하였다.
- 주기적으로 온라인 회의를 통해 진행 방향 및 상황을 공유했으며, data fetching 같이 혼자서 해결하기 어렵거나 이해하기 힘든 부분은 함께 자료를 찾아보고 해결하였다.
배포 링크
우리가 만든 netflix의 배포 링크는 다음과 같다.
https://next-netflix-16th-k7yg.vercel.app/
'회고 > CEOS' 카테고리의 다른 글
7주차 미션 : CEOS 파트장 & 데모데이 투표 서비스 제작 (0) | 2023.02.05 |
---|---|
6주차 미션 : nextJS로 netflix 클론코딩 - 2 (0) | 2022.11.18 |
4주차 미션 : react-messanger - 2 (0) | 2022.10.30 |
3주차 미션: react-messanger (1) | 2022.09.30 |
2주차 미션 : React-todo (1) | 2022.09.23 |