1. 개발 환경 구성
터미널을 통해 프로젝트를 생성하기에 앞서 원하는 경로에 접근한다.
접근한 경로의 하위 디렉터리로 프로젝트가 만들어짐.
1. nextjs13 프로젝트 생성 전 조건 확인
조건 nodejs 버전 ^14.18.0 || ^16.14.0 || >=18.0.0
node -v
버전이 낮을 경우 nvm을 통해 필요 버전을 설치 및 적용한다.
2. nextjs13 프로젝트 생성
npx create-next-app@latest next_app
가장 최신버전의 nextjs를 요청하는 코드
프로젝트명은 next_app으로 생성한다.
3. 프로젝트 생성 옵션 선택
✔ Would you like to use TypeScript? … No / Yes
타입스크립트 사용
✔ Would you like to use ESLint? … No / Yes
문법 에러 검출 도구
✔ Would you like to use Tailwind CSS? … No / Yes
Tailwind CSS 라이브러리 사용
✔ Would you like to use `src/` directory? … No / Yes
src 구조 미사용
src
├ index.js
├ pages
├ styles
├ components
⎿ utils
✔ Would you like to use App Router? (recommended) … No / Yes
nextjs13에서 변경된 라우팅 기능 사용 (레거시는 pages)
✔ Would you like to customize the default import alias? … No / Yes
nextjs.config.js파일에 특정 경로를 매핑하여 절대경로로 사용하여 상대경로보다 명확하게 경로파악을 돕는 옵션
import { Button } from "~/components"
✔ What import alias would you like configured? …
~/* <- 이렇게 입력
4. Eslint formatting / VS code extension
EsLint 설치 후 프로젝트 루트에 있는 .eslintrc.json 을 열고 아래와 같이 린트 설정값을 붙여 넣고 저장
{
"parser": "@typescript-eslint/parser",
"extends": [
"next/core-web-vitals",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
"plugin:prettier/recommended",
"prettier/prettier",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
],
"plugins": ["prettier", "@typescript-eslint"],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020,
},
"rules": {
"@typescript-eslint/no-non-null-assertion": "off",
"no-unused-vars": [1, { "args": "after-used", "argsIgnorePattern": "^_" }],
"react-hooks/exhaustive-deps": [
"warn",
{
"additionalHooks": "useRecoilCallback",
},
],
"@typescript-eslint/no-empty-interface": [
"error",
{
"allowSingleExtends": false,
},
],
"react/prop-types": "off",
"react/display-name": "off",
},
}
기본 프로젝트 설정을 하면 package.json 에 devDependencies는 설정이 되어있지 않을 텐데, 아래와 같이 devDependencies를 입력해 위의 json에서 사용하는 플러그인들을 설치해 주겠습니다.
// package.json
{...,
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.59.2",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"prettier": "^2.8.7"
}
}
위 코드를 붙여 넣은 모습이 아래와 같습니다.
5. prettier
devDependencies 제일 마지막에 prettier를 설치했습니다.
prettier 사용을 위해 프로젝트 루트경로에 prettier.config.js를 생성하고 아래와 같이 작성합니다.
/** @type {import('prettier').Config} */
module.exports = {
endOfLine: "lf",
semi: false,
singleQuote: false,
tabWidth: 2,
trailingComma: "es5",
importOrder: [
"^(react/(.*)$)|^(react$)",
"^(next/(.*)$)|^(next$)",
"<THIRD_PARTY_MODULES>",
"",
"^types$",
"",
"^[./]",
],
importOrderSeparation: false,
importOrderSortSpecifiers: true,
importOrderBuiltinModulesToTop: true,
importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
importOrderMergeDuplicateImports: true,
importOrderCombineTypeAndValueImports: true,
}
프로젝트 루트에 .prettierignore 파일을 생성하고 아래와 같이 작성합니다.
dist
node_modules
.next
build
yarn install을 통해 package.json에 추가된 의존성 라이브러리들을 설치합니다.
이로써 개발 환경 설정이 완료되었습니다.
2. 개발 서버 실행 테스트
yarn dev를 통해 프로젝트가 잘 실행되는지 확인합니다.
localhost:3000 로컬서버주소이며 기본 포트는 3000입니다.
3. nextjs13에서 달라진 App Routing
Next.js 13에서 가장 눈에 띄는 개선점 중 하나는 바로 라우팅입니다.
개발자가 만드는 파일/폴더 구조를 이용해 routing을 만들 수 있는 file system 기반의 유연하고 강력한 라우팅, 지금 바로 알아보겠습니다.
1. 라우팅 생성
acme.com라는 주소의 웹사이트를 개발하고 있고
acme.com/dashboard/settings 경로로 들어갔을 때
보여야 할 페이지를 만들어본다고 가정해 보겠습니다.
acme.com / dashboard / settings 주소를 이루는 각 부분을 잘게 잘라서
next.js13의 app router에서 사용하는 용어로 변환해보려고 합니다.
이때 이 페이지는 app이라고 하는 디렉터리 하위에 생성되어야 하는데,
이 app 디렉터리와 주소 경로의 각 부분을 next.js에서는 다음과 같이 정의합니다.
url path(URL경로) - acme.com/dashboard/settings |
segment(폴더 구조) app-root segment ⎿dashboard - segment ⎿settings - Leaf segment |
app - root segment 하위의 디렉터리들이 url path에서 보시면 하위 경로로 생성되어 있음을 볼 수 있습니다.
✔︎root segment인 app은 url path에 포함되지 않습니다.
url path(URL경로)에서 dashboard 나 settings처럼 경로를 구현하고자 한다면
반드시 각 segment에 해당하는 디렉터리를app 디렉토리 하위에 생성해야 합니다.
이것이 nextjs13에서 적용된 App routing에 대한 구조입니다.
2. 페이지 생성
nextjs13에서는 특정 이름의 파일이 해당 디렉터리에서 정해진 역할을 수행합니다.
이 중 page.js(또는 page.tsx)는
url path로 사용자가 액세스 할 경우 해당 path(경로)의 보일 페이지로써 기능합니다.
app(root segment) 디렉터리의 하위에 디렉터리를 생성함으로
세그먼트와 이 세그먼트들이 url path를 구성하지만,
acme.com 이든
acme.com/dashboard 이든
acme.com/dashboard/settings 든
외부(페이지 방문자)에게 공개하기 위해서는
반드시 해당 세그먼트의 디렉터리에 page.js(또는 page.tsx)를 생성해야 합니다.
위 예제 그림에서 /dashboard url path를 통해 대시보드 페이지를 보여줄 수 있는 이유는
dashboard/ 디렉터리 하위에서 page.js(또는 page.tsx)를 생성했기 때문입니다.
page.js(page.tsx) 외에도 layout.js 등 각 세그먼트 디렉터리에서 고정된 역할을 수행하는 페이지명들을 추후 더 자세하게 알아보겠습니다.
이때 고정된 파일들은 .js 확장자뿐만이 아닌 .jsx, .js, .tsx로 사용이 가능합니다.
기본적인 페이지를 생성해 보겠습니다.
/dashboard url path로 접속하는 유저를 위해 /dashboard/page.tsx를 생성합니다.
export default function page({children}: {children: React.ReactNode}) {
return (
<div>
<div>page</div>
<div>{children}</div>
</div>
)
}
nextjs13이 해당 페이지 컴포넌트를 인식하기 위해서는
위 코드의 컴포넌트를 정의하고 export default 해주어야 합니다.
이때 children에는 어떤 내용이 들어갈지 알아보겠습니다.
아래 그림에서는 settings/ 디렉터리 하위에
password(leaf segment), profile(leaf segment) 디렉터리가 생성되어 있는 것을 볼 수 있으나
현재까지 우리가 진행한 단계는 dashboard 하위에 page.tsx를 만들고
settings 세그먼트를 담당할 settings/ 디렉터리까지 생성하였으나
settings의 디렉토리 내에는 아무것도 없습니다.
앞서서 app이 root segment라고 했죠?
이해를 돕기 위한 위 도식화를 보면
거대한 app이라는 tree는
blog 세그먼트로 시작되는 서브 트리와
dashboard 세그먼트로 시작되는 서브 트리로 이루어지고 있음을 알 수 있습니다.
dashboard 서브트리에서
root segment는 dashboard 세그먼트 자기 자신이고
도식화에서 보면 settings 디렉터리가
dashboard 세그먼트의 하위 세그먼트가 되는 것이지요.
dashboard 내부에 적힌 error, layout, loading, not-found, template은 잠시 잊어버리도록 하죠.
이 친구들이 고정된 기능을 하는 페이지들입니다.