
Next.js 공식 홈페이지 ( https://nextjs.org/ ) 에서 말하는 Next.js 입니다. 약 몇년간 React.js, Vue.js 등의 라이브러리를 사용하여 SPA ( Single Page Application ) 를 구축하는게 개발업계의 유행이었습니다. Client Side 렌더링의 가장 큰 단점 2가지는 최초 로딩 지연, SEO의 취약성으로 이 둘을 극복하기 위해 최근 개발업계는 서버사이드 렌더링을 지향하고 있다고 합니다.
Next.js 는 서버사이드 렌더링을 지원하고, 또 React.js 를 기반으로 클라이언트 사이드 렌더링도 지원하는 풀 스택 프레임워크입니다.
HTML 파일을 서버에서 제작하고, 클라이언트 (브라우저) 에게 전송합니다. 브라우저는 전달받은 HTML파일을 해석하고 렌더링합니다.
핵심
서버에서 렌더링을해서 보내주지 않습니다. HTML 문서를 문자열 형태로 브라우저에게 전송할 뿐입니다.
자연스럽게 위와 같은 생각이 들 수 있습니다. 하지만 어떤 방법이 더 좋다라고 단언할 수 없습니다. 웹 애플리케이션은 여러 구획으로 나누어져있고, 필요한 곳에서 저 둘을 효율에의해 사용하는것이 관건입니다.
서버측에서 과도한 렌더링을 한다면, 서버를 사용하는 비용이 증가할 수 있고, 클라이언트에서 과도한 렌더링을 한다면, 로딩에 지연이 발생할것입니다.
Next.js 로 앱을 생성하면 아래와 같은 디렉토리를 가지게 됩니다.
npx create-next-app@latest appname
// @latest 최신버전 다운로드
Root

public : 정적 데이터를 저장하는 공간, 파일서버를 구축하여 데이터를 관리하지 않는 이상 public 폴더에 데이터를 보관합니다.src/app : layout.js, page.js 를 열어서 구조를 확인해보십시오. Next.js 의 근간이 되는 파일구조이며, 디렉토리 1개는 1개의 layout.js 와 page.js를 가질 수 있습니다.<img src="/item.jpg">이미지의 '/' 루트 경로는 /public 입니다. 다른 정적자원은 확인하지 못했지만 어떤 page.js 에서도 / 하나로 pulic 폴더에 접근 가능합니다.
Tip. Next.js 의 이미지
이미지 최적화: 최신 형식의 이미지 크기 변경 기능( WebP 등 )을 사용 할 수 있습니다. ( 브라우저에서 지원하는 경우 ) ,이렇게 하면 작은 화면을 가진 장치로, 큰 이미지를 전달하지 않아도 됩니다.
Next.js 이미지의 특징 :Next.js는 빌드 시 이미지를 최적화하는 대신, 사용자가 요청할 때 만 이미지를 최적화합니다.정적 사이트와는 달리, 10개의 이미지를 전송하든 1천만 개의 이미지를 전송하든 빌드 시간이 증가하지 않습니다.
이미지는 기본적으로 지연 로드됩니다. ( 화면에 표시될 이미지만 로드 ) 즉, 뷰포트 외부의 이미지에 대해서는 페이지 속도에 영향을 미치지 않습니다.
이미지는 레이아웃 오류를 방지하여 렌더링됩니다. 사용자 예상치 못하게, 레이아웃이 움직여 잘못된 행동을 하게 되는 것을 방지합니다.
( 개발자 환경과, 사용자 환경의 차이로 인해, 오류나 성능 저하가 눈에 띄지 않을 수도 있다. )

package.json : 프로젝트의 메타데이터와 함께 다양한 설정과 정보를 담고 있으며, 주요 용도는 다음과 같습니다프로젝트 정보 : 프로젝트의 이름, 버전, 설명, 저자, 라이선스 등과 같은 기본적인 정보를 제공합니다.의존성 관리 : 프로젝트에서 사용하는 의존성(라이브러리 및 모듈)을 명시합니다. dependencies와 devDependencies 섹션을 통해 프로덕션환경과 개발환경에서 필요한 패키지를 구분하여 관리할 수 있습니다.스크립트 : 개발, 빌드, 테스트, 배포 등의 작업을 위한 스크립트를 정의합니다. npm이나 yarn과 같은 패키지 관리자를 사용하여 이러한 스크립트를 실행할 수 있습니다.환경 설정 : 프로젝트에 특정한 환경 설정을 정의할 수 있습니다. 예를 들어, 린터(linter) 설정, 배포 설정, 특정 환경에서 사용할 변수 등을 설정할 수 있습니다.버전 관리 : 프로젝트의 현재 버전을 기록합니다. 버전 관리는 소프트웨어의 업데이트와 호환성을 관리하는 데 중요합니다.프로젝트의 식별자 : Node.js 에코시스템에서 프로젝트를 식별하는 데 사용됩니다. 예를 들어, npm publish 명령을 사용하여 프로젝트를 npm 레지스트리에 게시할 때, 이 파일의 정보가 중요하게 사용됩니다.리포지토리 링크 : 프로젝트의 소스 코드가 있는 리포지토리에 대한 링크를 제공할 수 있으며, 이는 다른 개발자들이 프로젝트의 소스 코드를 찾고 기여하기 쉽게 합니다.script : 현재 프로젝트를 유지보수 할 때 필요한 명령어"dev" : "next dev" : Next.js 프로젝트의 개발서버를 실행합니다. 개발모드는 핫리로딩을 지원하여 실시간으로 변화를 적용합니다."build" : "next build" : Next.js의 프로덕션을 위해 코드를 최적화 (코드 압축, 불필요한 부분 제거) 하고, 필요한 리소스를 컴파일하며, 애플리케이션을 배포할 준비를합니다. 실제 서비스를 위한 배포버전을 생성합니다. "start" : "next start" : Next.js 프로젝트를 프로덕션 모드로 실행합니다. next build 로 생성된 배포버전을 기반으로 서버를 실행합니다. 이 서버는 최적화된 상태로 애플리케이션을 서비스하며, 실제 운영 환경에서 사용됩니다.dependencies: 애플리케이션 실행에 필수적인 패키지를 나타냅니다. 애플리케이션을 배포할 때 ( 서비스 할 때 ) 패키지도 포함됩니다.devDependencies: 개발 과정에서만 필요한 패키지를 나타냅니다. 일반적으로 프로덕션 환경에서 필요하지 않으므로 배포시에는 포함되지 않습니다.Next.js 프로젝트를 생성하면 부가적인 패키지들을 권장하고, 필요한 패키지만 설치 할 수 있게 지원해줍니다.

Next.js 개발을 하기 앞서 굉장히 중요한 개념이기에 따로 섹션을 두고 짚고 넘어가려고 합니다.
https://helloinyong.tistory.com/315 해당 블로그의 내용을 인용한 것입니다.
Server Side에서 렌더링 된 정적 페이지와 번들링된 JS파일을 클라이언트에게 보낸 뒤, Client Side에서 HTML 코드와 React-In-JS코드를 서로 매칭 시키는 과정을 말합니다.
React.js는 JavaScript 파일, 코드만을 이용하여 웹 화면을 구성하는 원리를 가지고 있습니다. 실제 HTML 코드는 하나도 작성되어있지 않습니다. ( SEO에 적합하지 않은 이유 )
React.js는 JavaScript 기술이기 때문에 JavaScript가 작동하지 않는 환경에서는 화면을 렌더링하지 못합니다. 개발자 도구에서disable Javascript 를 사용하여 JavaScript를 제거하면 아무것도 렌더링되지 않는 이유가 바로 여기있죠.

React 프로젝트의 index.html 파일의 모습입니다. 단순 뼈대만 있는 HTML 문서와 JS 파일들을 클라이언트로 모두 보내고, 클라이언트에서 JS 코드를 통해 화면을 렌더링 합니다.

클라이언트가 해석하고 렌더링한 화면은 index.js 파일에 의해 root 라는 DOM 을 찾아서 주입하게 됩니다.
Next.js는 클라이언트에게 웹 페이지를 보내기 전에 Server Side 단에서 미리 웹 페이지를 Pre-Rendering하고, 생성된 HTML 을 클라이언트에게 전송합니다.
중요
클라이언트가 전송 받은 웹 페이지는 단순히 웹 화면만 보여주는 정적인 HTML일 뿐이고, 자바스크립트 요소들이 하나도 없는 상태입니다.
이는 웹 화면을 보여주고 있지만, 특정 JS 모듈 뿐 아니라 단순 클릭과 같은 이벤트 리스너들이 각 웹 페이지의 DOM 요소에 하나도 적용되어 있지 않은 상태임을 말합니다.
그렇다면 페이지만 보여주고 동작조차 하지 못하는 마치 빈 껍데기 같은 웹 페이지가 나중에는 어떻게 정상적으로 동작하게 되는 것일까.
Next.js Server에서는 Pre-Rendering된 웹 페이지를 클라이언트에게 보내고 나서, 바로 리액트가 번들링 된 자바스크립트 코드들을 클라이언트에게 전송합니다.

개발자 도구의 네트워크 탭을 보면, 가장 처음 document 를 전송받고, 이후에 React 코드들이 렌더링 된 JS 파일들을 Chunk 단위로 다운로드하는 것을 확인할 수 있습니다.
그리고 이 자바스크립트 코드들이 이전에 보내진 HTML DOM 요소 위에서 한번 더 렌더링을 하면서, 각자 자기 자리를 찾아가며 매칭이 됩니다.
이 과정을 Hydrate라고 부른다.
이것은 마치 자바스크립트 코드들이 DOM 요소 위에 물을 뿌리듯 필요로 하던 요소들을 채운다 하여 Hydrate(수화)라는 용어를 쓴다고 합니다.

실제로 Next.js 로 만든 애플리케이션을 새로 로딩할 때마다 뒤늦게 스타일이 적용되는 듯한 느낌이 Hydration 과정이며, 자바스크립트가 HTML 렌더링 후에 뿌려지기 때문입니다.
(정확하게는, 자바스크립트로 외부 서버에 웹폰트를 요청해서 받아오는데, Hydrate 이전에는 웹 폰트를 아직 요청하지 못해 적용되지 않아서이다.)
두 번 렌더링은 비효율적인게 맞습니다. 다만, 서버 단에서 빠르게 Pre-Rendering하고 유저에게 빠른 웹 페이지로 응답할 수 있다는 것에 더욱 큰 이점을 가져갈 수 있습니다.
심지어 이 Pre-Rendering 한 Document는 모든 자바스크립트 요소들이 빠진 굉장히 가벼운 상태이므로 클라이언트에게 빠른 로딩이 가능합니다.
따라서 같은 화면에 대해 두 번 렌더링이 일어난다는 단점을 보완하고도 남습니다.
더 나아가서 클라이언트 단에서 자바스크립트가 렌더링을 할 때, 단지 각 DOM 요소에 자바스크립트 속성을 매칭 시키기 위한 목적이므로 실제 웹 페이지를 다시 그리는 과정까지는 하지 않습니다. (Paint 함수 호출 X)
요점 정리
Next.js는 pre-rendering하여 정적인 html을 먼저보내고, chunk 단위의 js 코드를 아이언맨 수트처럼 차차착 붙혀줍니다.
Next.js의 라우팅은 React.js의 라우팅과는 조금 다릅니다.

이미지의 create, read, update 폴더 또한 경로로 취급합니다.
Next.js의 url 파라미터는 React.js 보다 훨씬 강력합니다.
<Link href="/read/1">1번 게시글</Link>
/read/1 위 링크의 1 이라는 숫자를 url 파라미터로 사용하겠습니다.

Next.js의 page에서 url 파라미터를 사용하려면 [파라미터명] 으로 된 폴더를 생성하고, 그 하위에 page.js를 생성합니다.
위 이미지의 경로는 아래와 같습니다.
nextapp/src/app/read/[id]/page.js
url파라미터를 전달 받은 페이지는 정말 간단하게 props.params를통해 {파라미터명:파라미터값} 처럼 객체 형태로 정의된 값에 접근할 수 있습니다.
export default async function Read(props) {
return (
<>
{props.params}
</>
);
}
간단하게 Next.js와 React.js의 라우팅에 차이점을 알아보겠습니다.
라우팅 설정:
Next.js는 파일 시스템 기반으로 자동 라우팅을 설정합니다.
React.js는 react-router-dom과 같은 라이브러리를 사용하여 수동으로 라우트를 설정합니다.
설정의 용이성:
Next.js는 새 페이지를 생성하기 위해 파일을 추가하기만 하면 됩니다. 라우팅 설정이 자동으로 이루어집니다.
React.js에서는 새 페이지를 추가할 때마다 라우터 설정을 업데이트해야 합니다.
동적 라우팅:
Next.js는 파일명에 대괄호를 사용하는 방식으로 동적 라우팅을 처리합니다.
React.js에서는 Route 정의에 :param 같은 매개변수를 사용합니다.
특수 페이지:
Next.js는 _app.js, _document.js 등 특수한 기능을 가진 파일을 제공합니다.
React.js에서는 이러한 특수 페이지를 수동으로 설정해야 합니다.
지금까지 Next.js 의 특징과 React.js 와 어떤 차이를 보이는지 포스팅 해봤습니다. 다음 포스팅에서는 실제로 Next.js 를 사용해서 간단한 앱을 만드는 포스팅을 진행하면서 Next.js 를 알아보겠습니다.