2021.05.13 - [Frontend/React] - CRA에 Next.js 적용하기 1
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의 역할을 수행하면 될 테다!
그런데 js는 그렇다 쳐도... 기존 html속 head태그 속 부분은 어떻게 처리하지?
쨘. 이렇게 next의 Head 컴포넌트를 이용하면 html속 meta나 title태그들을 사용할 수 있다.
그런데 여기서 문제, 우리는 CSS-in-JS가 익숙하므로... styled-component를 이용해 CSS를 입혀줬을 테다.
뭐 대충 이런 식으로!
당연히 Next.js에서도 똑같이 styled-component를 사용할 수 있다!
그런데 (진짜) 문제는...
저 양옆의 알 수 없는 margin은? → 브라우저 기본값!
따라서 이를 없애줘야 하는데... 기존 CRA에서처럼 index.css를 만들어 둘을 연결시켜줘야 할까?
pages 폴더 내에 _app.js(이름이 희한하다)란 파일을 만들자!
요렇게 코드를 작성해준 뒤...
styles 폴더 내에 globals.css 파일을 만들어주자!
프로젝트 전체에 적용하고 싶은 CSS 스타일(marign, padding, box-sizing, font 등)을 이곳에 작성!.
그런데 두 번째 문제. styled-component가 제대로 적용되지 않는다! 어떤 때는 되고, 어떤 때는 안되고...
왜? SSR은 JS 파일 로딩이 끝나기 전에 HTML을 미리 만들어 사용자한테 제공한다.
때문에 CSS-in-JS를 사용하는 styled-component 역시 HTML 렌더링 후에야 적용되고 만다!
github.com/vercel/next.js/tree/canary/examples/with-styled-components
쨔잔. 친절한 example 코드에 들어가 보면...
Next.js는 렌더링 시 pages 디렉터리 안에 기본적으로 같이 렌더링 되는 컴포넌트가 존재한다.
대표적으로 방금 만든 _app.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이 있기 때문에 이를 적용시키는 모습!
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-decoration: none; 을 적용했는데도 먹히지 않는다!
왜? → 원래 그렇단다! 띠용.
따라서...
이런 식으로 Link 컴포넌트 내에 a 태그를 넣어 활용해야 한다!
4) HTML Head 태그를 전역으로 설정
여태까지 index.js에 Head 태그를 추가했었는데...
이는 당연히 처음으로 렌더링 되는 index.js에만 적용된다.
우리가 원하는 건? 해당 앱 내 모든 페이지에 적용되는 것..!
친절한 공식문서(의 번역본).
아까 만든 _app.js를 이용하라는데... 얘네는 대체 뭘까?
Next.js 에는 일반 페이지가 아닌, 특수한 역할을 수행하는 페이지들이 존재한다.
- pages/_document.js : HTML, head, body를 담당.
- pages/_app.js : 전체 페이지를 감싸고 있는 root 페이지.
아하! 따라서 _app.js에 Head를 적용시키면 모든 페이지에 먹힐 테다.
사실 공식 문서상에는 Head 같은 경우 _document에서 설정하라는데...
아까 styled-component를 적용할 때 _document에 코드를 왕창 작성해버렸고
다른 예제들도 _app.js에 작성한 사례가 많아 그냥 이곳에 적기로..!
이렇게! 추가적으로 props로 전달받은 Component와 pageProps는 Next.js에서 전달한 것!
아항..! 즉 Next.js 속 페이지들은 요 _app.js에서 Compenent란 형태로 렌더링 되고,
이들의 props는 pageProps란 형태로 각 컴포넌트에 전달되는 거고만!
4. SSR 확인하기
이렇게 끙끙거리며 고쳤는데... 진짜 SSR이 작동되는지 의심된다!
두 눈으로 확인하기 위해 개발자 도구 - Network 탭에 들어가자.
캐싱된 내용을 지우고 새로고침을 누르면...
쭈르르륵 뭔가가 뜨는데, 그중 Type이 document인 파일을 클릭해보자.
와우! 우리가 만든 페이지가 잘 뜨는 모습.
만약 CSR으로 작동되는 페이지라면?
따란... JS가 작동되야만 페이지를 읽을 수 있다!
'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 |