Next.js로 jQuery 포트폴리오 업그레이드하기 - 초기설정, 퍼블리싱 편

2020년 취업 초반에 만들었던 jQuery 포트폴리오를 Next.js로 업그레이드하면서 적는 Next.js 고군분투기
처음 취업 준비 때 막무가내로 만들었던 포트폴리오.
어떤 한 사이트를 참고해가며 클론코딩을 만든 포트폴리오였 습니다.
나름 php도 붙여가며 회원가입, 로그인기능도 붙여놨지만 유지보수를 안하기도 했고 어찌저찌하여 내 손을 떠나게 되었는데, 그 때 막 퍼블리싱을 배우던 때라 jQuery로 성능도 생각하지 않고 냅다 코딩했던 기억만 있어요.
다시 코드를 까보니 넘나 더러워서.... 언젠가 업그레이드 해야겠다고 생각한 거 지금 react, next.js 배우고 있는 김에 업그레이드해봐야겠다고 결심했습니다.
- https://aainterior.com.ua/를 클론코딩한 사이트 입니다.
🍽️ next.js로 선택한 이유
구글 폰트 내장 지원
해당 파일을 보면, css를 파악하는데 좀 시간이 오래 걸렸습니다.
나름 reset.css도 적용하고 레이아웃은 레이아웃대로, 잘 분리했다고 생각했는데 폰트 설정도 다 모여있고 해서 파일 관리하기가 복잡해보였어요.
실제로 퍼블리싱 할 때 직접 구글 폰트 찾거나 아니면 폰트 파일을 다운로드 받아서 임포트 해주고... 그걸 font-face로 지정해주고 하는 과정이 번거롭게 느껴졌습니다.
구글 폰트가 내장으로 지원된다는 점은 이런 면에서 매력적이었어요!
빠른 로딩속도 개선
아무래도 인터랙티브한 UI들은 jQuery로 DOM을 직접 지정하여 인터랙션을 준 것들이라서 소스가 무겁다고 판단했습니다.
Next.js는 자동 코드 분할과 최적화된 빌드 시스템을 제공하여 성능을 최적화하기 때문에 이는 사용자 경험을 크게 개선할 수 있을 거라고 생각했어요.
React 생태계 활용
React를 실무에서 적용해본 적이 없고 경험을 많이 쌓고 싶다고 생각한 찰나에 마침 Next.js를 입문하고 있었습니다.
원페이지의 동적 데이터 교환이 없는 페이지여서 Next.js의 특장점을 살리는 프로젝트는 아니겠지만 그래도 React 생태계를 활용한다는 점에서 매력을 느껴 결정하게 되었어요.
SEO 최적화
굳이 React로 하지 왜 Next.js로? 라는 생각이 들 수 있다고 생각합니다.
그럼에도 불구하고 Next.js를 선택한 그 이유는 다음과 같습니다.
jQuery로 작성한 포트폴리오에서 meta태그로 검색엔진에 잘 걸릴 수 있게 설정을 해두었는데, 그런 면에서 Next.js가 SEO 측면에서 도움이 되지 않을까 생각했습니다.
CSS module 사용가능
처음 next앱을 셋팅할 때 css module로 사용할 수 있도록 지정해주었는데요, tailwind같은 프레임워크를 사용하지 않았던 이유는 css 디자인 비중이 높아서 였습니다. 이미지요소도 많았지만, 커스텀해서 스타일을 지정해주어야하는 부분이 많았고, css 모듈에 대해 좀 더 알아보고 싶어서 선택했습니다.
🍽️ 프로젝트 세팅
자 그럼 프로젝트를 세팅해봅시다. Next.js simple tutorial 보러가기
npx create-next-app@latest
🍽️ meta tag 세팅
meta tag를 설정해 봅시다.
export const metadata: Metadata = {
title: "rowanna porfolio 2020",
description: "next.js로 업데이트 한 jQuery 포트폴리오 입니다.",
keywords:
"나원지, 포트폴리오, portfolio, rowanna, 웹퍼블리셔, 웹퍼블리셔 포트폴리오",
icons: {
icon: "/favicon-128.jpg",
},
openGraph: {
title: "Wonji Na Portfolio",
description: "웹 퍼블리셔 나원지의 포트폴리오 사이트입니다.",
images: "/meta-img.jpg",
},
};
여기서 이미지 경로는 src/public이 아니라 public에 파일을 넣어둡니다. 기존의 favicon.ico는 삭제해 주었습니다.
🍽️ 폴더 구조 세팅
다음 구조는 src/app 디렉토리의 구조입니다.
/app
├── layout.tsx
├── page.tsx
├── components/ # ✅ 컴포넌트 모음 폴더
│ ├── ui/ # ✅ (1) UI 공통 컴포넌트
│ │ ├── Button/ # ✅ Button 컴포넌트 폴더
│ │ │ ├── Button.tsx
│ │ │ └── Button.module.css
│ │ └── index.ts # UI 컴포넌트들을 한 번에 export
│ │
│ ├── layout/ # ✅ (2) 레이아웃 관련 컴포넌트
│ │ ├── Header/ # ✅ Header 컴포넌트 폴더
│ │ │ ├── Header.tsx
│ │ │ └── Header.module.css
│ │ ├── Footer/ # ✅ Header 컴포넌트 폴더
│ │ │ ├── Footer.tsx
│ │ │ └── Footer.module.css
│ │ └── index.ts
│ │
│ ├── sections/ # ✅ (3) 특정 페이지에 포함되는 섹션 컴포넌트
│ │ ├── Main/ # ✅ Main 컴포넌트 폴더
│ │ │ ├── Main.tsx
│ │ │ └── Main.module.css
│ │ └── Info/ # ✅ Info 컴포넌트 폴더
│ │ ├── Info.tsx
│ │ └── Info.module.css
│ └── index.ts # 모든 컴포넌트들을 한 번에 export
│
├── styles/ # 전역 스타일
├── public/ # 정적 파일 (이미지, 폰트 등)
└── ...
import Layout from "@/app/components/layout";
import Main from "@/app/components/sections/Main/Main";
export default function Container() {
return (
<>
<Layout>
<Main />
</Layout>
</>
);
}
위처럼 모든 컴포넌트를 component폴더의 Container에 넣고 최종 page.tsx에서 아래와 같이 임포트 했습니다.
import Container from "@/app/components";
export default function Home() {
return <Container></Container>;
}
