Next.js
를 사용해 프로젝트 구축 과정을 설명합니다.Typescript
와 함께 ESLint
, Prettier
를 설정합니다.
Next.js
Next.js는 명령어로 한 번에 프로젝트 구성이 가능합니다.
설치되는 버전은 15.1.2
입니다.
설치
# next 프로젝트 생성
$ npx create-next-app
✔ What is your project named? … test-next-app
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … No
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … No
✔ Would you like to customize the import alias (`@/*` by default)? … No
이제 사용하는 IDE로 프로젝트를 열어주면, 설치 완료입니다.
ESLint
ESLint는 ES + Lint 의 합성어로, Javascript의 에러를 표시해주는 도구입니다.
이미 설치를 했기 때문에 eslint.config.mjs
에서 바로 확인할 수 있습니다.
설치 및 설정
저는 xo
라는 Style Guide를 따르려고 합니다.
❓ Airbnb를 사용하지 않는 이유
현재 ESLint 9 버전까지 나왔는데, airbnb의 경우 유지보수가 되고 있지 않아 호환 이슈가 있어요.
그래서 다른 스타일 가이드를 사용해요.
플러그인 지원 현황
# xo 설치
$ npm i -D xo eslint-config-xo-react
그 후 ESLint 설정 파일에서 extends를 추가합니다.
// eslint.config.mjs
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
...compat.extends("xo"), // 👈 추가
...compat.extends("xo-react"), // 👈 추가
];
테스트
예시로 page.tsx
를 검사하겠습니다.
$ ./node_modules/.bin/eslint ./app/page.tsx
에러가 엄청 많습니다.. 하나하나 수정해보겠습니다.
react/react-in-jsx-scope
JSX를 사용한다면 'React'를 import 하라는 룰인데, React 17 이상부터는 내장으로 지원합니다.
따라서 관련 plugin인 react/jsx-runtime
을 추가하면 해결됩니다. 참고 링크
// eslint.config.mjs
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
...compat.extends("xo"),
...compat.extends("xo-react"),
...compat.extends("plugin:react/jsx-runtime"), // 👈 추가
];
react/jsx-sort-props
JSX에서 props 전달 시에 정렬 여부를 검사하는 룰입니다.
이 단계에서는 굳이 필요없다고 생각되어 끄겠습니다.
// eslint.config.mjs
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
...compat.extends("xo"),
...compat.extends("xo-react"),
...compat.extends("plugin:react/jsx-runtime"),
{
rules: {
"react/jsx-sort-props": "error", // 👈 추가
},
},
];
quotes
작은 따옴표(''
)를 사용하라고 권장합니다.
현재 전부 큰 따옴표(""
)로 되어있으니, 큰 따옴표를 사용하도록 설정하겠습니다.
// eslint.config.mjs
const eslintConfig = [
// 생략..
{
rules: {
"react/jsx-sort-props": "error",
"quotes": ["error", "double"], // 👈 추가
"jsx-quotes": ["error", "double"], // 👈 추가
},
},
];
indent
들여쓰기 규칙인데, 기본 설정이 4
입니다.2
로 변경하겠습니다.
// eslint.config.mjs
const eslintConfig = [
// 생략..
{
rules: {
"react/jsx-sort-props": "error",
"quotes": ["error", "double"],
"jsx-quotes": ["error", "double"],
indent: ["error", 2], // 👈 추가
"react/jsx-indent": ["error", 2], // 👈 추가
"react/jsx-indent-props": ["error", 2], // 👈 추가
},
},
];
다시 검사해보면 에러는 전부 사라졌습니다.
그런데 ESLint는 Javascript 문법 관리 도구인데 코드 스타일까지 신경씁니다. (quotes, indent 등)
역할이 너무 과한 것 같은데..? 😂
💡 코드 오류는 ESLint! 코드 포맷팅에는 Prettier!
Prettier
Prettier는 일관적인 코딩 스타일을 유지시켜주는 code fomatter입니다.
설치
# prettier 설치
$ npm i -D prettier eslint-config-prettier
ESLint 설명에서 코드 포맷팅도 관여하고 있었습니다.eslint-config-prettier
는 ESLint에서 Prettier와 충돌하는 부분을 비활성화하는 모듈입니다.
❓ 함께 언급되는 eslint-plugin-prettier를 설치하지 않는 이유
eslint-plugin-prettier
는 prettier를 eslint의 rules로 동작하게 하는 모듈이예요.
하지만 포맷팅 문제를 오류로 인식하면 lint 오류와 구별이 어렵고, 오류 메시지가 지나치게 많아지고 prettier보다 느린 문제가 있어 비추천해요. :(
ESLint와 연동
ESLint 설정 파일에서 extends를 추가합니다.
그리고 기존 코드 포맷팅 관련은 Prettier에서 할테니, ESLint 설정에서는 제거하겠습니다.
// eslint.config.mjs
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
...compat.extends("xo"),
...compat.extends("xo-react"),
...compat.extends("plugin:react/jsx-runtime"),
...compat.extends("prettier"), // 👈 추가
{
rules: {
"react/jsx-sort-props": "error",
"quotes": ["error", "double"], // ❌ 제거
"jsx-quotes": ["error", "double"], // ❌ 제거
indent: ["error", 2], // ❌ 제거
"react/jsx-indent": ["error", 2], // ❌ 제거
"react/jsx-indent-props": ["error", 2], ❌ 제거
},
}
];
이렇게 해도 이제 에러가 없습니다. 잘 분리가 됐습니다. :)
설정
이 부분은 필수가 아니지만, 알고는 있어야 합니다.
Prettier도 원하는대로 설정을 할 수 있습니다..prettierrc
파일을 만들고, 내용을 작성합니다.
// .prettierrc
// 작은 따옴표 사용을 허용해서 테스트 해볼게요!
{
"singleQuote": true // 👈 추가
}
💡 그 외 설정은 여기서 참고하시면 돼요. :)
이제 prettier로 코드 포맷팅을 실행합니다.
# prettier 자동 수정
$ ./node_modules/.bin/prettier --write ./app/page.tsx
자동으로 작은 따옴표로 변경되었습니다!
의견은 언제든 댓글로 남겨주세요. 🙂