
리액트 프로젝트 셋업
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
리액트를 사용하는 프로젝트를 생성할 때 마다 create-react-app(이하 CRA)를 사용하게 되었었는데요, scratch 부터 자주 사용하는 구성을 템플릿으로 남겨두고 싶은 마음이 생겼습니다. 기본적으로 사용되는 React, typescript, webpack, babel, eslint, prettier 설정입니다.
각각의 항목들에 대해서 자세하기 다루기 보다는 사용할 수 있는 형태의 코드를 제공하는게 목적입니다.
아래의 레포지토리에서 본 블로그의 코드 전체를 확인하실 수 있습니다.
https://github.com/Tolluset/react-pj-template
템플릿 개요
# 사용할 라이브러리 버전 react 17.0.2 typescript 4.5.5 webpack 5.68.0 babel 7.12.2 eslint 8.8.0 prettier 2.5.1
이번에 사용할 프로젝트 패키지입니다.
프로젝트 생성
mkdir react-pj-template cd react-pj-template yarn init -y // 초기 설정 스킵하여 디폴트 옵션으로 생성
프로젝트 생성할 디렉토리를 만들고 해당 디렉토리에서 yarn init 패키지 파일을 초기화해 줍니다.
디렉토리 및 index.html 생성
CRA에서 해주는 것처럼, public, src 디렉토리를 만들고 public에 index.html 을 추가 해줍시다.
mkdir public src touch public/index.html
// public/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
<div id="root"><div> 부분이 우리의 리액트가 들어갈 자리가 되겠습니다.
React
yarn add react react-dom yarn add -D @types/react @types/react-dom
@types 는 실제로 타입 모듈을 임포트해서 사용하면 dependencies 에 설치해야 하지만 이 템플릿에서는 사용하지 않기에 devDependencies에 설치합니다.
react-dom은 index.ts 에서 index.html 의 진입점에 렌더하기 위해 필요합니다.
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
// src/App.tsx
import React from 'react';
const App = () => {
return <div>App</div>;
};
export default App;
이 템플릿에서는 Function Component 기준으로 생성하겠습니다.
리턴타입에는React.FC 를 사용하지 않고 추론적으로 사용하겠습니다.
https://github.com/facebook/create-react-app/pull/8177
Typescript
yarn add -D typescript
타입스크립트를 추가했으니 tsconfig.json 도 추가해주겠습니다.
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "es6",
"strict": true,
"jsx": "react",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"lib": ["es6","dom"],
"outDir": "./dist",
},
"ts-node": {
"compilerOptions": {
"module": "CommonJs"
}
},
"include": ["src/**/*", "tests/**/*"],
}
target 을 es5 로 하면 라이브러리들이 es6 를 쓰는 경우 컴파일 단계에서 에러가 날 수 있는데요, 이를 위해 lib에 es6 를 추가 해 둡니다. (target을 es6로 써도 되고요, IE가 2022년 6월경 지원종료를 하는데 IE 이외의 대부분의 브라우저가 잘 지원하죠... https://caniuse.com/?search=es6 커버율 96.34% ?)
module은 import, export 로 사용하고 싶기 때문에 es6 로 설정합니다.
strict를 true 로 해두면 타입스크립트가 권장하는 여러 규칙들을 자동으로 추가해줍니다.
https://www.typescriptlang.org/tsconfig#strict
jsx는 react 를 사용하기 때문에 그대로 사용합니다.
esModuleInterop 는 import * as A from A 를 import A from A 같이 default import를 사용할 수 있게 해줍니다.
moduleResolution 는 모듈 import를 어떻게 할 것이냐 node 의 경우 nodejs 가 사용하는 방식을 사용합니다.
moduleResolution 에 대한 자세한 내용은 아래의 링크가 도움이 될 것 같습니다.
좀 더 tsconfig 를 세밀조정하고 싶다면, 레퍼런스를 참조해주세요.
https://www.typescriptlang.org/tsconfig
Webpack
# tl;dr yarn add -D webpack webpack-cli webpack-dev-server babel-loader html-webpack-plugin clean-webpack-plugin ts-node @types/node @types/webpack @types/clean-webpack-plugin # webpack yarn add -D webpack webpack-cli webpack-dev-server # loader yarn add -D babel-loader # plugins yarn add -D html-webpack-plugin clean-webpack-plugin # types yarn add -D ts-node @types/node @types/webpack @types/clean-webpack-plugin
# webpack : 웹팩을 사용하기 위한 cli와 개발환경에서 필요한 dev-server를 추가해줍니다.
# loader : 코드에 대한 해석을 babel에게 맡깁니다.
# plugins : html을 가져다 쓰기 위한 html-webpack-plugin 과 빌드 시 마다 빌드된 파일을 저장하는 폴더를 초기화 시켜주는 clean-webpack-plugin 을 사용합니다.
# types : webpack.config.ts 를 사용하는게 ?하다 생각하기 때문에 를 사용하기 위함입니다. (.js 로 해도되는데 github에 js를 사용하고 있다고 나오는게 묘하게 거슬려요, 저만 그런가요??? ?)
// webpack.config.ts
import path from "path";
import webpack from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import { CleanWebpackPlugin } from "clean-webpack-plugin";
import ESLintPlugin from 'eslint-webpack-plugin';
import "webpack-dev-server";
const config: webpack.Configuration = {
mode: "development",
entry: "./src/index.tsx",
module: {
rules: [
{
test: /\.(ts|tsx)$/,
include: path.resolve(__dirname, 'src'),
use: {
loader: "babel-loader",
},
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
plugins: [
new HtmlWebpackPlugin({
template: "public/index.html",
}),
new CleanWebpackPlugin(),
new ESLintPlugin({
extensions: ['ts', 'tsx']
})
],
};
export default config;
Babel
yarn add -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
사용할 preset들은 es6를 위해 사용하는 env , 리액트를 위한 react , 타입스크립트를 위한 typescript 를 추가해 줍니다.
// .babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
]
}
ESLint
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-import-resolver-typescript eslint-webpack-plugin
React, typescript와 관련된 ESlint를 추가해서 사용합니다.
plugins 에 사용할 플러그인들을 정의 해두고, extends 에서 플러그인들이 프리셋으로 제공하는 기능들을 지정하여 사용할 수 있습니다.
// .eslintrc.json
{
"root": true,
"env": { "browser": true, "es6": true },
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
"plugins": [
"@typescript-eslint",
"react",
"react-hooks",
"import",
"jsx-a11y"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:import/recommended",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended"
],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"]
},
"import/resolver": {
"typescript": {
"project": "./tsconfig.json"
}
}
},
"rules": {
"no-console": "warn",
"import/order": [
"error",
{
"groups": [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"object",
"type"
]
}
]
}
}
ESlint가 체크 할 필요 없는 파일은 .gitignore 처럼 아래와 같이 정의해주시면 됩니다.
// .eslintignore node_modules dist
위처럼 설정한 eslint를 webpack dev server에 연결하면
// webpack.cofing.ts
// ...omit
plugins: [
...
new ESLintPlugin({
extensions: ['ts', 'tsx']
})

터미널에서 바로 확인 하실 수 있게 됩니다.
Prettier
yarn add -D prettier eslint-config-prettier
eslint-plugin-prettier가 아닌 eslint-config-prettier 를 사용해줍니다.
ESlint 설정 파일의 extends 에 prettier 플러그인을 추가해줍니다.
// .eslintrc.json
// ...omit
{
"extends": [
...
"prettier"
]
}
extends 에 prettier 를 추가함으로써 eslint와 prettier가 충돌하지 않게 적절하게 이미 설정된 rule들을 꺼줍니다. 그러므로 extends 의 마지막에 추가해주세요!
https://github.com/prettier/eslint-config-prettier
// .prettierc
{
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"parser": "typescript",
"arrowParens": "always"
}
singleQuote, tarilingComma, parser 이외의 설정은 기본값이지만 변경하지 않도록 주의하기 위해 의도적으로 표시해둡니다.
추가적인 옵션들은 아래의 링크를 참조해주세요.
// .prettierignore dist node_modules
포맷팅이 필요없는 파일은 적절하게 걸러줍니다.
에필로그
Webpack의 프로덕션 빌드, 환경 별 파일 분리 및 머지 같은 설정이나, https://webpack.kr/guides/production/
Husky, lint-staged를 이용해서 좀 더 영리하게 린팅, 포매팅,
환경변수 등등...
추가적인 설정을 더 해둬야 하긴 합니다 ?
본 블로그 게시글을 보시고 문의 사항이 있으신 분들은 클래스메소드코리아 (info@classmethod.kr)로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !







