React
[01] 리액트로 웹앱 만들기 with TypeScript
BGK97
2024. 4. 9. 16:37
리액트 프레임워크 이해하기
리액트란?
- 2013년 페이스북에서 발표한 오픈소스 자바스크립트 프레임워크
- 가상 DOM(Document object model), JSX(JavaScript XML)라는 새로운 방식으로 동작
- 프론트, 백 중 프론트에 해당하는 프레임워크로 분류
웹 서버의 작동 방식
- 웹 서버의 경우, 웹 브라우저가 요청하는 다양한 유형의 자원을 제공하는 역할을 수행
- 이 때, URL 문자열을 HTTP 프로토콜로 사용하여 웹 서버에 요청해야 함
- 이를 HTTP 요청이라 한다.
- 요청을 받은 웹 서버는 해당 자원을 웹 브라우저로 전달
- 이를 HTTP 응답이라 한다.
- 이후 이 응답을 사용자가 볼 수 있도록 웹 페이지 화면에 보여준다.
- 이를 렌더링 이라고 한다.
- 그 이후 다른 자원을 다시 요청하면, 전에 있던 렌더링 내용들은 모두 삭제 된다.
- 이 때, 화면 깜빡임이 발생 (ex 새로고침)
SPA (Single Page Application)
- 주소창으로 요청하는 자원이 하나뿐인 웹 애플리케이션
- index.html 파일 하나로만 작동하여 자원을 한 번만 요청, 화면 깜빡임이 없음
- 리액트의 경우, 백엔드에서 받은 JSON 데이터를 해석하여 현재 사용자가 새로 요청한 부분만 동적으로 생성한다.
이런 방식의 웹 애플리케이션을 싱글페이지 애플리케이션이라고 한다.
- 반대로, 사용자 요청이 있을 때 마다 완전히 새로운 HTTP 요청, 응답으로 새로운 HTML을 전달받는 기존 방식을 MPA, 멀티페이지 애플리케이션 이라고 한다.
템플릿 엔진
- 웹 서버는 대부분 HTML 템플릿 엔진을 제공
- 템플릿 엔진은 HTML 문서를 DB에서 추출한 데이터와 결합해 쉽게 생성시켜줌
- 프론트엔드의 경우, 백엔드에서 제공한 JSON 데이터를 해석 후 JS 객체를 얻은 후, 객체들을 다시 웹 브라우저가 이해 가능한 DOM 객체로 변환 해주어야 함
- 리액트가 JS를 DOM 객체로 전환해주는 역할을 수행
- 클라이언트(웹 브라우저)에서 작동하는 템플릿 엔진
01-2 윈도우에서 리액트 개발 환경 만들기
- 사용하는 프로그램
프로그램명 | 용도 | 운영체제 | 기타 |
---|---|---|---|
Node.js | 웹 서버 개발 플랫폼 | 윈도우/mac | 필수 |
VSCode | 소스코드 편집기 | 윈도우/mac | 권장 |
scoop | 윈도우용 설치 프로그램 | 윈도우 | 권장 |
Homebrew | macOS용 설치 프로그램 | mac | 권장 |
touch | 파일 관리 유틸리티 | 윈도우 | 선택 |
Chrome | 웹 브라우저 | 윈도우/mac | 권장 |
- 이 때 , 개발용 도구는 윈도우 업데이트에 민감하여 항상 최신 버전으로 유지해야 함
- 항상 최신버전으로 유지해야, 버그 픽스를 수월히 할 수 있음
VSCode 설치하기
- https://code.visualstudio.com/ 접속 후 메인 화면 가운데에 있는 설치 진행
Node.js 설치하기
- https://nodejs.org/en 에 접속하여, LTS 버전을 다운 받는다.
- 도중에 나오는 Automatically install the necessary tools.은 체크해야 한다.
01-3 VSCode 개발환경 설정하기
- 필요한 확장 프로그램들
프로그램 명 | 용도 | 운영체제 | 기타 |
---|---|---|---|
프리티어 | 코드 정렬 | 윈도우 / mac | 권장 |
테일윈드CSS | CSS스타일링 | 윈도우 / mac | 필수 |
헤드윈드 | 테일윈드CSS 클래스 분류기 | 윈도우 / mac | 선택 |
포스트CSS | CSS구문 강조 표시 | 윈도우 / mac | 선택 |
기본 설정
- File -> preference -> color T**heme** 메뉴를 실행 후 원하는 색 선택한국어 언어 팩 설치하기
- View -> Extension 메뉴에서 마켓플레이스를 열고, Korean 검색 후 마이크로소프트의 Korean 언어팩을 찾아 install
- Ctrl + Shift + P 를 누른 후 User Settings 입력, 이후 설정 파일에서 아래와 같이 변경
{ "workbench.colorTheme": "Default Light+", "editor.tabSize": 2, }
- 마켓 플레이스에서, prettier 검색 후 Prettier-Code formatter 설치
- 동일한 곳에서 TailWindCss, HeadWind, PostCss 설치
타입스크립트 컴파일러 설치하기
- 좌측 상단 터미널 - > new 터미널 선택 후, npm i -g typescript ts-node 입력
- 이후 tsc -v, ts-node -v를 통해 버전 확인
타입스크립트 프로그램 만들고 컴파일 하기
- 터미널에서
- mkdir ch01/ch01_4/src
- touch ch01/ch01_4/src.index.ts
- cd ch01/ch01_4 차례로 수행
- 이후 console.log로 아무거나 찍어보고,
- ts-node src/index.ts를 수행하면 해당 문자가 찍힘
프리티어로 소스 정리
- 먼저 디렉터리에 prettierrc.js파일을 생성해야함
- touch 명령어를 통해 만들면 된다.
- 생성 이후 다음과 같은 코드를 추가
module.exports = { singleQuote: true, semi: false, }
- 의미 : 세미콜론을 모두 지우고, 큰 따옴표는 작은 따옴표로 교체
- 이후 index.ts에서 코드를 작성하면, 저 위의 양식대로 자동 변경 됨
- prettier가 작동하지 않게하려면 //prettier-ignore를 사용하면 됨
01_5 리액트 프로젝트 생성
- 터미널에 npx create-react-app (프로젝트명) --template typescript
어플리케이션 실행
- npm run start : 개발 모드 (코드 반영 o)
- npm run build : 빌드 모드 (개발 모드가 아닙니다.)
- 최적화된 코드로 빌드, 필요없는 코드나 용량들을 압축, 삭제
웹팩과 번들
- 웹팩
- 프론트엔드 프레임워크에서 사용하는 대표적인 모듈 번들러
- 모듈
- 애플리케이션이 동작하는데 필요한 파일 (HTML, CSS, JS...)
- 번들
- 웹팩은 다양한 입력모듈을 결합해 단순한 형태의 모듈로 변환하는데, 이 때 나오는 결과물
웹 서버 가동
- 웹 서버 역할을 하는 serve 프로그램 설치
- npm install -g serve
- serve -s build
개발 모드로 실행
- npm start
- 해당 터미널 실행 후, 코드를 바꾸게 되면, 동적으로 바로 화면이 바뀌게 된다.
- 이를 핫 모듈교체 혹은 핫 리로딩 이라고 함
프리티어 적용하기
- 아까와 똑같이 터미널에 touch prettierrc.js 추가
- 원하는 설정을 넣고, 이제 정렬할 때마다 해당 속성이 적용
module.exports = { bracketSpacing: false, jsxBracketSameLine: true, singleQuote: true, trailingComma: 'none', arrowParens: 'avoid', semi: false, printWidth: 90 }
가짜 데이터 만들기
- Node.js용 외부 패키지 설치법
- npm i 이용시 옵션을 줄 수 있는데...
- --save : 실행에 필요한 패키지로, package.json 파일의 dependencies 항목에 등록 -S
- --save-dev : 개발에 필요한 패키지로, package.json 파일의 devDependencies 항목에 등록 -D
- chance, luxon 패키지 설치
- 가짜데이터 제공 및 날짜를 '20분 전' 등의 형태로 만들어주는 패키지들
- npm i chance luxon 을 통해 설치
- npm i -D @types/chance @types/luxon(파일에 추가된 패키지 명세를 보여줌) -> package.json 파일에 있을거다
- 이후에 src에 data폴더를 생성하여 가짜 데이터를 생성한다.
프로젝트를 공유할 때는 node_modules 디렉터리를 지워야 용량을 줄일 수 있다!!!
어짜피 나중에 npm i 하면 설치 된다.
각 가짜파일 작성하기
- util.ts
export const makeArray = (length : number) => new Array(length).fill(null)
export const range = (min: number, max: number): number[] => makeArray(max - min).map((notUsed, index) => index + min)
export const random = (min: number, max: number): number => Math.floor(Math.random() * (max - min)) + min
- range에서, 원래 빈 배열에 map을 하면 오류가 뜬다. 그러나, 선언 과정에서 fill을 사용하게 되면 오류가 뜨지 않는다.
- image.ts
import { deflate } from "zlib";
import * as U from "./util";
// prettier-ignore
export const picsumUrl = (width: number, height: number): string => `https://picsum.photos/${width}/${height}`
export const randomImage = (
w: number = 1000,
h: number = 800,
delta: number = 200
): string => picsumUrl(U.random(w, w + delta), U.random(h, h + delta));
export const randomAvatar = () => {
const size = U.random(200, 400);
return picsumUrl(size, size);
};
- 공유 이미지 사이트에서 이미지 가져오기
- chance.ts
import Chance from "chance";
const chance = new Chance();
export const randomUUID = () => chance.guid()
export const randomName = () => chance.name()
export const randomEmail = () => chance.email()
export const randomId = () => chance.fbid()
export const randomJobTitle = () => chance.profession();
export const randomCompanyName = () => chance.company();
export const randomSentence = (words = 5) => chance.sentence({words})
export const randomTitleText = (words = 3) => chance.sentence({words})
export const randomParagraphs = (sentences = 3) => chance.paragraph({sentences})
- date.ts
import { DateTime } from "luxon";
export const makeRandomPastDate = () => {
const value = new Date().valueOf();
const n = 100000;
return new Date(value - Math.floor(Math.random() * n * n));
};
export const makeRelativeDate = (date: Date) =>
DateTime.fromJSDate(date).startOf("day").toRelative();
export const randomRelativeDate = () => makeRelativeDate(makeRandomPastDate());
export const makeDayMonthYear = (date: Date) =>
DateTime.fromJSDate(date).toLocaleString(DateTime.DATETIME_FULL);
//이 코드를 통해, '19시간 전' 과 같은 문자를 만든다
export const randomDayMonthYear = () => makeDayMonthYear(makeRandomPastDate());
- index.ts
export * from './util'
export * from './chance'
export * from './date'
export * from './image'
이때 까지 만들어 놨던 파일들을 전부 export
가짜 데이터 사용하기
- App.tsx
import * as D from './data' export default function App(){ return ( <div> <p> {D.randomName()}, {D.randomJobTitle()}, {D.randomDayMonthYear()} </p> <img src={D.randomAvatar()} height="50"/> <img src={D.randomImage()} height="300"/> </div> ); }
- 해당 코드로 가짜데이터들을 불러왔음