지금까지 모든 미션은 초기 환경이 이미 세팅된 레포를 받아 시작했다. 그래서 개발 환경을 직접 구축하거나, 어떤 도구를 사용할지 고민해볼 기회가 거의 없었다. 이에 몇 가지 불편함이 있었다. ESLint만 해도 버전이 올라갈수록 설정 방식이 달라지고, 기존 설정과 충돌이 생겼다. 세팅에 대한 기본 이해가 부족하다 보니 문제를 마주했을 때 제대로 대응하지 못했고, 결국 GPT에 의존하게 됐다.
게다가 미션은 Vite를 빌더 도구로 사용하고 있지만, 언젠가 Parcel을 써보고 싶어질 수도 있다는 생각이 들었다. 그럴 때 자유롭게 도구를 바꾸고, 원하는 구성 요소를 넣다 뺄 수 있으려면 환경에 대한 이해가 필요하다고 느꼈다.
그래서 이번엔 누군가 미리 깔아준 환경이 아니라, 바닥부터 직접 하나씩 쌓아올리는 방식을 택했다. create-react-app이나 create-vite처럼 손쉽게 초기 설정을 끝내주는 도구들도 일부러 사용하지 않았다.
노드 버전 확인 → 노드 설치 → 프로젝트 폴더 생성 및 이동
node -v
fnm install --lis
fnm list
mkdir my-app
cd my-app
code .
npm init -y
.gitignore 파일을 생성한다.
touch .gitignore
npm i -D typescript
npx tsc --init
JSX 파일을 쓰겠다고 선언하는 부분이다. 하지만 이 부분이 없어도 정상적으로 동작한다.
"jsx": "react-jsx"
npm i -D eslint
npx eslint --init
상황에 맞게 질문에 대답한다.
설치할까요? y
Eslint 어떤 거에 사용할까요? 모두
자바스크립트 모듈 어떤거 사용할까요? JavaScript (import/export)
프레임워크는 어떤 거 쓸까요? react
타입스크립트 사용하나요? y
Browser, Node? Browser
스타일 가이드를 따르세요? 아니면 매번 물어볼까요? 전자
스탠다드를 따르세요? xo를 따르세요? xo
설정파일 어떻게 잡으시겠어요? js
추가 설치해도 되나요? y
패키지 매니저 뭐 쓸까요? npm (기본)
plugin:react/jsx-runtime
을 extends에 추가하면 됐지만 현재는 안됨.export default defineConfig([
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"], },
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], languageOptions: { globals: globals.browser},
},
tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
{
// 🚨 react version 명시
settings: {
react: {
version: "detect",
},
},
},
{
// 🚨 'react/react-in-jsx-scope' 규칙을 'off'로 설정
rules: {
"react/react-in-jsx-scope": "off",
"react/jsx-uses-react": "off",
indent: ['error', 2],
},
// 🚨 ignore 설정
ignores: ['**/node_modules/**', '**/dist/**', '**/build/**'],
},
]);
mkdir .vscode
touch .vscode/settings.json
settings.json 파일에는 Lint가 잡을 것을 설정한다.
예를 들어, 80열에서 줄 긋기
, save하면 끝에 있는 줄 삭제
를 추가할 수 있다.
{
"editor.rulers": [80],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always" // S/TS 파일을 저장할 때마다 ESLint를 실행하고 문제점을 고치게 설정
},
"trailing-spaces.trimOnSave": true
}
npm i react react-dom
npm i -D @types/react @types/react-dom
// /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>Document</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="main.tsx"></script>
</body>
</html>
// /main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./src/App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// src/App.tsx
export default function App() {
return <>Hello</>;
}
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"check": "tsc --noEmit",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"test": "jest",
"coverage": "jest --coverage --coverage-reporters html",
"watch:test": "jest --watchAll",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
세팅을 하면서 Velog 같은 레거시 문서를 참고하지 않고, 공식 문서를 참고했다. 이유는 버전이 바뀌면서 설치되는 파일도 달라지고 설정 방식도 바뀌었기 때문에 레거시 문서를 믿을 수 없었다.
예를 들어, ESLint도 예전에는 JSX 파일에서 React를 직접 import하지 않아도 되게 하려면 plugin:react/jsx-runtime
을 extends에 추가하면 됐었다. 그런데 현재 사용하는 Flat config에서는 plugin:
접두사가 더 이상 지원되지 않기 때문에 이 설정을 쓸 수 없었다. 그래서 react/react-in-jsx-scope
규칙을 off
로 설정해서 React import를 강제하지 않도록 바꿨다.
공식 문서를 따라가며 하나하나 설정해보니, 생각보다 어렵지 않았다. 앞으로는 create-react-app 같은 도구의 도움을 받더라도 필요한 설정은 직접 커스텀할 수 있겠다는 자신감이 생겼다.