NextJS 개발 환경 설정하기
January 23, 2024
react, react-dom, NextJS, typescript, eslint, prettier, styled-components 를 사용하는 개발 환경을 create-next-app 사용하지 않고 직접 설정해보자.
라이브러리 설치
npm i react react-dom next
npm i @types/node @types/react @types/react-dom eslint eslint-config-next typescript -D
tsconfig.json 작성
{
"$schema": "http://json.schemastore.org/tsconfig.json", // 해당 JSON 파일이 무엇을 의미하는지, 또 어떤 키와 어떤 값이 들어갈 수 있는지 알려주는 schemastore에서 제공하는 도구이다. 이를 통해 옵션 JSON 파일에서 IDE의 자동완성이 가능하다.
"compilerOptions": {
// 타입스크립트를 자바스크립트로 컴파일할 때 사용하는 옵션
"target": "es5", //타입스크립트가 변환을 목표로 하는 언어의 버전. 단, 폴리필까지는 지원하지 않는다.
"lib": ["DOM", "DOM.Iterable", "ESNext"], // 폴리필을 붙여서 지원할 환경이 준비됐다고 가정하고, 타입스크립트가 사용할 수 있는 라이브러리를 지정한다.
"allowJs": true, // 자바스크립트 파일을 허용할지 여부
"skipLibCheck": true, // 라이브러리에서 제공하는 d.ts에 대한 타입체크 여부. 이 옵션이 켜져 있으면 라이브러리의 d.ts까지 검사해서 전체적인 프로젝트의 컴파일 시간이 길어지므로 일반적으로 꺼놓는다.
"outDir": "dist",
"strict": true, // alwaysStrict, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables 옵션을 한꺼번에 켜는 옵션
"forceConsistentCasingInFileNames": true, // 파일 이름의 대소문자 구분
"noEmit": true, // 컴파일을 하지 않고, 타입 체크만 하는 옵션이다. 이 옵션을 켠 이유는 Next.js에서 swc가 타입스크립트 파일을 컴파일하므로 굳이 타입스크립트가 컴파일을 할 필요가 없기 때문이다.
"esModuleInterop": true, // CommonJS 방식으로 보낸 모듈을 ES 모듈 방식의 import로 가져올 수 있게 해주는 옵션
"module": "esnext", // 모듈 시스템 설정한다.commonjs는 require를 사용하고 esnext는 import를 사용한다.
"moduleResolution": "node", // 모듈을 해석하는 방식을 지정한다. node는 node_modules을 기준으로 모듈을 해석하고, classic은 tsconfig.json이 있는 디렉터리를 기준으로 모듈을 해석한다.
"resolveJsonModule": true, // JSON 파일을 import할 수 있게 한다.
"isolatedModules": true, // 파일에 import나 export가 없는 모듈을 허용하지 않는 옵션
"jsx": "preserve", // tsx 파일 내부의 JSX를 어떻게 처리할지 설정한다. preserve는 JSX를 변환하지 않고 JSX 코드를 그대로 두는 것인데, Next.js에서는 swc가 JSX 또한 변환해주므로 이 옵션을 사용한다.
"incremental": true, // 이전에 컴파일한 결과를 캐싱해서 다음번 컴파일 시간을 줄여주는 옵션
"baseUrl": "src", // 모듈을 해석할 때 기준이 되는 디렉터리를 지정한다. 아래 paths 옵션과 함께 사용한다.
"paths": {
"#pages/*": ["pages/*"],
"#hooks/*": ["hooks/*"], // 예를 들어, #hooks/useToggle는 src/hooks/useToggle 경로로 해석된다.
"#types/*": ["types/*"],
"#components/*": ["components/*"],
"#utils/*": ["utils/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "tsconfig.json"], // 타입스크립트 컴파일 대상에서 포함시킬 파일 목록을 의미한다. ts, tsx 확장자 파일 및 Next.js에서 자동 생성하는 next-env.d.ts 파일을 포함시킨다.
"exclude": ["node_modules"] // 타입스크립트 컴파일 대상에서 제외시킬 파일 목록을 의미한다.
}
next.config.js 작성
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true, // 리액트 엄겸 모드 활성화
poweredByHeader: false, // 보안 취약점인 X-Powered-By 헤더를 비활성화
eslint: {
ignoreDuringBuilds: true, // 빌드 시 eslint 검사를 하지 않도록 설정한다. 이후에 CI 과정에서 ESLint 검사를 진행할 예정이므로 빌드 시간 단축을 위함이다.
},
compiler: {
styledComponents: true, // styled-components를 사용하기 위한 설정
},
}
module.exports = nextConfig
// https://github.com/vercel/next.js/blob/v14.1.0/packages/next/src/server/config-shared.ts 에서 사용 가능 옵션 참고
ESLint와 Prettier 설정
npm i @titicaca/eslint-config-triple -D
// .eslintrc.js
module.exports = {
extends: [
"@titicaca/eslint-config-triple",
"@titicaca/eslint-config-triple/frontend",
"@titicaca/eslint-config-triple/prettier",
"next/core-web-vitals",
],
rules: {
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off",
},
}
스타일(styled-components) 설정
- styled-components 설치
npm i styled-components
_documents.tsx
에 ServerStyleSheet 추가
// _documents.tsx
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from "next/document"
import { ServerStyleSheet } from "styled-components"
export default function MyDocument() {
return (
<Html lang="ko">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
MyDocument.getInitialProps = async (ctx: DocumentContext) => {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
// useful for wrapping the whole react tree
enhanceApp: App => props =>
sheet.collectStyles(<App {...props} />),
// useful for wrapping in a per-page basis
enhanceComponent: Component => Component,
})
const initialProps: DocumentInitialProps = await Document.getInitialProps(
ctx
)
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
-
next.config.js 설정에 complier 옵션에서 styledComponents를 true로 켜기
- 이렇게 하면 swc가 styled-components를 사용하는 코드를 더 빨리 변환한다.
scripts
"scripts": {
"dev": "next dev",
"start": "next start",
"build": "next build",
"lint:es": "eslint '**/*.{js,ts,tsx}'",
"lint:fix": "npm run lint:es -- --fix",
"prettier": "prettier '**/*' --check",
"prettier:fix": "prettier '**/*' --write"
},
https://github.com/wonsss/next-app 에서 위와 같은 방법으로 개발환경 설정을 진행했다.
참고 자료 : 모던 리액트 딥다이브 - 김용찬 -