React + TypeScript 프로젝트 초기 세팅 하는 방법과 에러들을 기록해보았다.
(추가 내용이 발생할 때 마다 업데이트 해 볼 예정...아마도..?)
npx create-react-app "폴더이름" --template typescript
npm i --save typescript @types/node @types/react @types/react-dom @types/jest
프로젝트에 따라 필요한 라이브러리를 설치하여 사용하면 되는데, npm 사이트 검색창에서 @types/
+ 라이브러리
키워드 조합으로 쉽게 찾을 수 있다.
npm install --save @types/styled-components
프로젝트 규모가 커지고 폴더구조가 복잡해지게 되면서 "../../../../src/components/Navbar.tsx"
처럼 파일경로를 찾기 위해 땅굴을 파 본 적이 있을 것이다.
해당 문제를 최소화 하기 위해 tsconfig.json
파일 내부에 "baseUrl": "./src"
을 추가했다.
{
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": "./src",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"]
}
d.ts
는 TypeScript
코드의 타입 추론을 돕는 파일이다. TypeScript
에서 이미지 파일 import
할 때 에러가 발생하기 때문에 src
폴더 내부에 types
폴더를 생성하고 image.d.ts
파일을 생성하여 허용할 확장자를 작성해주면 된다.
declare module '*.jpg';
declare module '*.png';
declare module '*.jpeg';
declare module '*.gif';
declare module '*.svg';
(이 외에 다른 파일 추가할 일이 생기면 이어서 작성해 볼 예정...!)
기존의 index.tsx
파일을 보면 as HTMLElemet
로 타입 단언을 한 것을 볼 수 있다. 이펙티브 타입스크립트 책에 의하면, 타입 단언(as Type)
보다는 타입 선언(: Type)
을 사용하라고 명시되어 있다. (타입 단언은 강제로 타입을 지정했으니 타입 체커에게 오류를 무시하라고 하는 것이기 때문)
아직 Typescript
를 잘 모르지만, 코드를 작성할 때 최대한 as
없이 작성하려고 하는 편이다. 때문에 사서 에러를 얻은 모습을 볼 수 있다. (document.getElementById('root')
에서 에러가 빵빵 터진다.)
getElementById(elementId: string): HTMLElement | null;
getElementById
는 null
이 존재 할 수 있다.createRoot
메소드에는 null
이 존재할 수 없기 때문에 에러 발생const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('Failed to find the root element');
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
null
반환 시 에러를 발생 하도록 로직 추가)npm i -D eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier
.eslintrc
파일 생성 후 해당 내용 작성
{
"extends": [
"prettier",
"airbnb",
"airbnb/hooks",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"]
}
.eslintignore
파일 생성 후 해당 내용 작성
/node_modules
.prettierrc
파일 생성 후 해당 내용 작성
{
"singleQuote": true,
"parser": "typescript",
"semi": true,
"useTabs": false,
"printWidth": 120
}
기존 .package.json
파일 "scripts"
부분에 해당 내용 작성
"scripts": {
"prettier": "prettier --write --config ./.prettierrc \"**/*.{ts,tsx}\"",
"lint": "eslint './src/**/*.{ts,tsx}'",
"lint:fix": "eslint --fix './src/**/*.{ts,tsx}'"
}
이제 터미널에 npm run lint
를 입력해보자. 에러가 빵빵 터질 것이다.
eslintrc
파일 "rules"
부분에 해당내용 추가
"rules":{
"react/jsx-filename-extension": ["warn", { "extensions": [".tsx"] }]
}
eslintrc
파일 "rules"
부분에 해당내용 추가
"rules":{
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
]
}
npm install eslint-import-resolver-typescript --save-dev
eslintrc
파일 "settings"
부분에 해당내용 추가
"settings":{
"import/resolver":{
"typescript":{}
}
}
매 번 새 프로젝트 세팅 할 때 마다 검색을 통해 부분부분 참고하며 해결했는데, 이렇게 초기 세팅 과정들을 한 번에 정리해놓고 나니까 흐름이 잘 보여서 더 좋은거 같다. 앞으로도 헷갈리는 과정이 있을 때 마다 블로그 글을 보면서 참고하면 될 것 같다.
https://velog.io/@junghyeonsu/React-create-react-app-Typescript-초기-세팅-완벽-정리
https://velog.io/@sweetpumpkin/기존-리액트-프로젝트에-TS-적용시-발생하는-에러
https://codingapple.com/unit/how-to-install-typescript-in-local-vue-react/
https://baek.dev/til/typescript/effective-typescript/ch02/item9
https://flamingotiger.github.io/javascript/eslint-setup/
https://velog.io/@suyeon-hong/eslint와-prettier-충돌로-인한-오류-해결-방법
https://velog.io/@he0_077/React-Typescript-eslint-prettier-설정