> For the complete documentation index, see [llms.txt](https://pm1100tm.gitbook.io/devnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pm1100tm.gitbook.io/devnote/week01/1..md).

# 1. 개발환경

## 🚀 React + TypeScript + Lint + Parcel

## 1. FNM

### fnm 설치

```terminal
brew install fnm
```

### 환경 변수 추가

```shell
# ~/.zshrc
eval "$(fnm env --use-on-cd)"
```

### FNM 기본 명령어

#### 버전 확인

```shell
fnm --version
```

#### 설치 가능 버전 리스트 확인

```shell
fnm list-remote
```

#### 버전 설치

```shell
fnm install --lts (Long Term Support)
fnm install <version>
```

#### 설치한 버전 사용

```shell
fnm use lts-latest
fnm use <version>
```

#### 특정 버전 기본으로 사용

```shell
fnm default $(fnm current)
fnm default <version>
```

> 이후 Parcel 설치 과정의 이슈로 인해 v18.15.0 사용 (원인 불명)

#### 프로젝트 안으로 진입했을 때 node version 변경하기

프로젝트 폴더의 루트로 들어가 .node-version 파일 생성

```shell
node --version > .node-version
```

### 2. npm 패키지 준비

```shell
# npm 전역 설치 및 업그레이드
npm install -g npm
npm install -g npm@latest
```

```shell
# 프로젝트 내부에서 npm 초기화
npm init -y
```

## 2. 타입스크립트 설정

여기서 -D 옵션을 사용하여, 타입스트립트를 프로덕션 환경에는 설치되지 않도록 한다. 타입스크립트는 코딩을 위한 도구로 설정한다.

```shell
npm i -D typescript
npx tsc --init
```

## 3. ESLint 설정

```shell
npm i -D eslint
npx eslint --init
```

```shell
npx eslint --init

@eslint/create-config@0.4.6
- Ok to proceed? (y) y

How would you like to use ESLint? …
- To check syntax, find problems, and enforce code style

What type of modules does your project use? …
- JavaScript modules (import/export)

Which framework does your project use? …
- React

Does your project use TypeScript?
- Yes

Where does your code run?
- Browser

How would you like to define a style for your project? …
- Use a popular style guide

Which style guide do you want to follow? …
- XO: https://github.com/xojs/eslint-config-xo-typescript

What format do you want your config file to be in? …
- JavaScript

eslint-plugin-react@latest eslint-config-xo@latest ...
? Would you like to install them now? › No / Yes
- Yes

Which package manager do you want to use? …
- npm
```

## 4. React 설치

```shell
npm i react react-dom
npm i -D @types/react @types/react-dom
```

## 5. 테스팅 도구 설치(Jest)

```shell
npm i -D jest @types/jest @swc/core @swc/jest \
    jest-environment-jsdom \
    @testing-library/react @testing-library/jest-dom@5.16.4
```

## 6. Parcel 설치

```shell
npm i -D parcel
```

> Parcel 이란?
>
> 모듈 번들러. Webpack 과 함께 bundler 시장의 점유율을 나눠갖고 있다. 번들러란 dependency가 있는 자바스크립트 파일을 최적화/압축하여 하나 혹은 여러개의 static 파일로 빌드해주는 컴파일러이다. Webpack 을 사용하는 것보다 장점이 있다고 한다.

## 7. parcel-reporter-static-files-copy 설치

```shell
npm install -D parcel-reporter-static-files-copy
```

```shell
# Root path 에 static 폴더를 만든다. 정적 이미지 등을 해당 폴더에 넣는다.
mkdir static
```

## ETC

### .gitignore 파일 생성

```terminal
...
/dist/
/.parcel-cache/
```

[gitignore.io 바로가기](https://www.toptal.com/developers/gitignore)

### tsconfig.json 수정

```javascript
...
"jsx": "react-jsx",
```

### .eslintrc.js 수정

```javascript
env: {
  browser: true,
  es2021: true,
  jest: true,  # 추가. Jest를 설치한 경우
},
extends: [
  'xo',
  'plugin:react/recommended',
  'plugin:react/jsx-runtime',  # 추가
],
```

#### prettier 와 충돌 방지

```shell
npm install --save-dev eslint-config-prettier
```

```javascript
// .eslintrc.js 파일 수정 - prettier 추가
extends: ['xo-typescript', 'prettier'],
```

> vscode 껐다 켜기

### .eslintignore 파일 생성

```shell
/node_modules/
/dist/
/.parcel-cache/
```

### .parcelrc 생성

```javascript
{
  "extends": ["@parcel/config-default"],
  "reporters":  ["...", "parcel-reporter-static-files-copy"]
}
```

### .vscode 폴더 생성 -> settings.json 파일 생성

```javascript
{
  "editor.rulers": [80],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "trailing-spaces.trimOnSave": true
}
```

### index.html 생성

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React Demo App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="./src/main.tsx"></script>
  </body>
</html>
```

### App.tsx 생성 (src 폴더 생성 후)

```javascript
export default function App() {
  return <p>Hello, world!</p>;
}
```

### main.ts 파일 (src 폴더 생성 후)

```javascript
import ReactDOM from 'react-dom/client';

import App from './App';

function main() {
  const element = document.getElementById('root');

  if (!element) {
    return;
  }

  const root = ReactDOM.createRoot(element);

  root.render(<App />);
}

main();
```

### package.json 파일 수정

```javascript
"source": "./index.html",
...
"scripts": {
    "start": "parcel --port 8080",
    "build": "parcel build",
    "check": "tsc --noEmit",
    "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx .",
    "test": "jest",
    "coverage": "jest --coverage --coverage-reporters html",
    "watch:test": "jest --watchAll"
  },
```

## 빌드 + 정적 서버 실행

### 빌드

```shell
npx parcel build
```

### 정적 서버 실행

```shell
npx servor ./dist
```
