본문 바로가기
source-code/React

CRA에 Next.js 적용하기 2

by mattew4483 2021. 5. 13.
728x90
반응형

2021.05.13 - [Frontend/React] - CRA에 Next.js 적용하기 1

 

CRA에 Next.js 적용하기 1

첫 단추는 언제나 중요하다. 개발 전 CTO님이 말씀하신 "SSR이 어쩌고... 검색 엔진이 어쩌고..." 그때는 별생각 없이 흘려 들었더랬다. 이제야 문제를 깨닫고 SSR을 적용시키려하는데... 여기서 문제

23life.tistory.com

Next.js가 어찌 돌아가는지 대...충이나마 감을 잡았으니!

CRA으로 만든 기존 앱에 이를 적용시켜보자.


1. 기본 환경 설정

이전에 썼던 글을 참고! → 설치 및 package.json 수정, pages폴더 생성까지 진행하면 된다.

 

2. 구조 변경하기

한번 더 짚고 넘어가자면...

Next.js는 기본적으로 최상위 루트의 pages폴더의 index.js를 띄워준다!

요 pages폴더 안에 다른 폴더를 만들 경우 → /새로운폴더명 으로 그 속의 index.js를 Route!

 

따라서 우리가 해야 할 건..?

기존 index.html에 있던 녀석을 몽땅 pages/index.js 속에 옮기고(이때 index.js에는 첫 화면 구성 요소가 들어갈 테다),

다른 페이지 이동할 URL에 맞는 폴더들을 그 속에 만들어주면 될 테다!

이런 식으로!

이러면 '/' → 최상위 index.js로

'/company', '/team' → 해당 이름의 폴더 속 index.js로 Route 될 테다!

 

1) index.js 작성하기

index.js는 제일 처음 보이는 페이지! 

따라서 기존 CRA의 index.html, index.js, App.js의 역할을 수행하면 될 테다!

index.html

그런데 js는 그렇다 쳐도... 기존 html속 head태그 속 부분은 어떻게 처리하지?

 

index.js

쨘. 이렇게 next의 Head 컴포넌트를 이용하면 html속 meta나 title태그들을 사용할 수 있다.

 

그런데 여기서 문제, 우리는 CSS-in-JS가 익숙하므로... styled-component를 이용해 CSS를 입혀줬을 테다.

index.js

뭐 대충 이런 식으로!

당연히 Next.js에서도 똑같이 styled-component를 사용할 수 있다!

그런데 (진짜) 문제는...

http://localhost:3000/

저 양옆의 알 수 없는 margin은? → 브라우저 기본값!

따라서 이를 없애줘야 하는데... 기존 CRA에서처럼 index.css를 만들어 둘을 연결시켜줘야 할까?

pages 폴더 내에 _app.js(이름이 희한하다)란 파일을 만들자!

 

_app.js

요렇게 코드를 작성해준 뒤...

styles 폴더 내에 globals.css 파일을 만들어주자!

프로젝트 전체에 적용하고 싶은 CSS 스타일(marign, padding, box-sizing, font 등)을 이곳에 작성!.

 

http://localhost:3000/

그런데 두 번째 문제. styled-component가 제대로 적용되지 않는다! 어떤 때는 되고, 어떤 때는 안되고...

 

왜? SSR은 JS 파일 로딩이 끝나기 전에 HTML을 미리 만들어 사용자한테 제공한다.

때문에 CSS-in-JS를 사용하는 styled-component 역시 HTML 렌더링 후에야 적용되고 만다!

 

github.com/vercel/next.js/tree/canary/examples/with-styled-components

 

vercel/next.js

The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.

github.com

쨔잔. 친절한 example 코드에 들어가 보면...

Next.js는 렌더링 시 pages 디렉터리 안에 기본적으로 같이 렌더링 되는 컴포넌트가 존재한다.

대표적으로 방금 만든 _app.js! 이와 유사하게 이번에는 같은 위치에 _document.js 파일을 만들어보자.

 

_document,js

으윽. 그리고 아까 전 exemple 코드에 적힌 걸 가져왔는데...

요점은 이를 통해 HTML 렌더링 시 styled-component도 함께 가져오는 것!

 

2) Link 바꾸기

Next.js에서는 next/Link의 L:ink를 import 해 Route 기능을 사용한다.

따라서... 기존 CRA에서의 Route 컴포넌트와 Link 컴포넌트를 몽땅 삭제!!!

대신 <Link href=""> 형태로 바꿔줘야 한다.

 

3. 에러 해결하기

1) Img 업로드

해당 프로젝트 내에 위치한 이미지를 import 할 때 발생한 에러!

Next.js의 모듈을 import 할 때 이미지 파일은 할 수 없는 설정...이라고 하는데,

이는 next-images라는 라이브러리를 통해 해결할 수 있다!

라이브러리를 설치해주시고

 

프로젝트의 최상위 루트에 Next.js에서 webpack 설정을 하는 next.config.js 파일을 생성!

 

next.config.js 

요렇게 작성한 후 서버를 재시작해주면 된다.

 

next.config.js이 있기 때문에 이를 적용시키는 모습!

 

2) Global CSS cannot be imported from files other than your Custom <App>

요 녀석은... index.js 속 컴포넌트 내에서 다른 CSS 파일을 import 했을 때 발생!

나의 경우는 Swiper 라이브러리에 적용되는 SCSS 파일로 인해 에러가 떴다.

 

해결책은? 해당 CSS 파일을 _app.js 파일에서 import 해주면 그만!

요런 식으로!

 

3) Link 컴포넌트 CSS 적용 안됨.

Link 컴포넌트에 className을 지정하고, styled-compent를 통해 text-decorationnone; 을 적용했는데도 먹히지 않는다!

왜? → 원래 그렇단다! 띠용.

 

따라서...

이런 식으로 Link 컴포넌트 내에 a 태그를 넣어 활용해야 한다!

 

4) HTML Head 태그를 전역으로 설정

여태까지 index.js에 Head 태그를 추가했었는데...

이는 당연히 처음으로 렌더링 되는 index.js에만 적용된다.

우리가 원하는 건? 해당 앱 내 모든 페이지에 적용되는 것..!

 

https://nextjs.org/docs/advanced-features/custom-app

친절한 공식문서(의 번역본).

아까 만든 _app.js를 이용하라는데... 얘네는 대체 뭘까?

 

Next.js 에는 일반 페이지가 아닌, 특수한 역할을 수행하는 페이지들이 존재한다.

  • pages/_document.js : HTML, head, body를 담당. 
  • pages/_app.js : 전체 페이지를 감싸고 있는 root 페이지.

아하! 따라서 _app.js에 Head를 적용시키면 모든 페이지에 먹힐 테다.

사실 공식 문서상에는 Head 같은 경우 _document에서 설정하라는데...

아까 styled-component를 적용할 때 _document에 코드를 왕창 작성해버렸고

다른 예제들도 _app.js에 작성한 사례가 많아 그냥 이곳에 적기로..!

_app.js

 

이렇게! 추가적으로 props로 전달받은 Component와 pageProps는 Next.js에서 전달한 것!

아항..! 즉 Next.js 속 페이지들은 요 _app.js에서 Compenent란 형태로 렌더링 되고,

이들의 props는 pageProps란 형태로 각 컴포넌트에 전달되는 거고만!

 

4. SSR 확인하기

이렇게 끙끙거리며 고쳤는데... 진짜 SSR이 작동되는지 의심된다!

 

두 눈으로 확인하기 위해 개발자 도구 - Network 탭에 들어가자.

캐싱된 내용을 지우고 새로고침을 누르면...

쭈르르륵 뭔가가 뜨는데, 그중 Type이 document인 파일을 클릭해보자.

 

와우! 우리가 만든 페이지가 잘 뜨는 모습.

 

만약 CSR으로 작동되는 페이지라면?

따란... JS가 작동되야만 페이지를 읽을 수 있다!

 

728x90
반응형

'source-code > React' 카테고리의 다른 글

patch-package 사용하기  (0) 2021.05.24
CRA에 Next.js 적용하기 3  (0) 2021.05.14
CRA에 Next.js 적용하기 1  (0) 2021.05.13
Props 전달 에러 해결  (0) 2021.04.06
.map() is not a function 에러 해결  (1) 2021.04.05