지난주에는 내가 좋아하는 커비를 테마로 한 귀여운 쇼핑몰을 만들었다. 이번에 쇼핑몰 만들기를 하면서 느꼈던 점에 대하여 정리하기 위하여 이렇게 커비샵 만들기 프로젝트에 관련된 글은 총 5개를 작성할 예정이다.
1. 프로젝트 세팅 이야기
2. emotion과 Global ui 세팅, 효율적인 컴포넌트 세팅
3. 상품목록 만들기 리액트 쿼리와 캐싱
4. 장바구니에 담기, 장바구니 체크. Recoil로 관리하기
5.Graphql을 쓰는 이유
프로젝트를 시작함에 있어서 세팅을 하는 것은 매우 중요하다. 그래서 어떻게 프로젝트를 시작해야 하는지에 대하여 고민을 많이 하였던 것 같다.
1. CRA를 사용하지 않기, 대신 Vite를 이용하여 React 앱 생성하기
2. Yarn Berry를 사용하여 패키지 관리를 효율적으로 진행하자
3. Webpack을 사용하지 않고 Vite를 사용하는 이유는 무엇일까?
이 세가지에 대한 왜??
라는 의문을 프로젝트를 직접 세팅해보면서 해결하고자 하여 프로젝트를 세팅하고자 하였고 이 글은 이것을 시도하면서 마주쳤던 이모저모 일을 정리하였다.
GDSC 커뮤니티에서 멤버 분이 올려준 아래 영상을 지하철에서 본 적이 있다.
Create React App is Finally Dead
처음에 이 링크 올라온 것 보고 굉장히 깜짝 놀랐다.나는 리액트 앱을 만들 때 항상
npx create-react-app
명령어를 사용하기 때문이다. 그런데 이게 왠 걸.. 사용하지 말라니! 청천벽력이었다. 영상에서 이야기하는 내용은 아래와 같다.
- CRA는 Webpack으로 애플리케이션을 번들링한다. -> 빌드 시 앱이 굉장히 무거워지고, 변경사항을 반영하는 데 있어서 오랜 시간이 걸림
- 서버사이드 랜더링을 처리하는 데 있어 세팅을 하는 것이 어렵다. 게다가 타입스크립트를 지원하지 않음.
- 용량이 너무 크다! 그리고 의존성 설치에 있어서 굉장히 오랜 시간이 걸린다
나는 특히 3번 단점에 너무너무 공감했는데, 컴퓨터를 바꾸기 전에 CRA를 하면 기본적으로 500MB가 넘어가서 파일을 옮기거나 삭제하는 데 정말 오랜 시간이 걸렸고, 의존성 설치를 할 때마다 수많은 Warning
이 발생하면서 하나하나 의존성 관계를 살펴줘야 했기 때문이다.
이런 단점들에 있어서 정말 많은 공감을 하고 있었기 때문에 새로운 대안이 나오게 되었다는 것이 내심 반가웠다.
사람들이 최근 정말 많이 사용하고 유행처럼 되고 있는 Vite
이다. Vite는 타입스크립트로 바로 앱을 생성할 수 있게 해줄 뿐 아니라, 서버를 실행하는 속도도 매우 빠르다.
이번에 프로젝트를 하면서 느꼈던 것인데 코드를 수정하고 삭제함에 있어서 App.tsx
에서부터 HMR되는 속도가 정말 빨랐기 때문에 어떤 원리로 진행되는지에 대하여 나중에 꼭 공부해보아야겠다고 생각했다.
Vite를 사용함으로써 코드에 대한 피드백을 매우 빠른 속도로 받을 수 있고, 이는 개발 생산성을 높인다는 데 있어 매우 중요하기 때문에 많은 사람들이 Vite에 주목하고 있다는 것을 알 수 있다. 더욱 자세한 내용은 아래 글을 참고하자
왜 Vite를 사용해야 하는가?(공식문서)
Vite가 빠른 이유에 대해서 간단히 정리해보고자 한다.
기존 개발은 Javascript 위주로 이루어지고, 이러한 Javascript를 쉽게 사용하게 해주는 패키지들을 npm에서 관리하고 있었다. 이는 개발을 할 때 사용하는 라이브러리들을 가져와 합쳐 빌드하는 과정인 '번들링'을 진행하는데, 가장 유명하고 많이 쓰이는 것이 바로 Webpack이다.
Webpack은 CRA 앱을 만드는 데에도 사용되고, 가장 널리 사용되고 있던 번들링 도구인데, 개발 볼륨이 커지거나 많은 라이브러리가 깔려서 용량이 커지게 되면 Webpack bundling이 매우 오래 걸린다는 단점이 존재한다.
그러나 Vite은 Go로 만든 Esbuild
를 사용하여 번들링을 진행하기 때문에 번들링을 매우 빠르게 진행할 수 있고, 개발과 관련된 라이브러리를 설치하자마자 미리 bundle을 만들어 두기 때문에(사전 번들링) 소스코드는 필요한 부분만 다시 번들링을 진행하는 것이다.
그리고 코드가 갱신될때마다 HMR(Hot Module Replacement)을 이용하여 변경된 부분들만 빠르게 번들링할 수 있도록 한다.
이러한 면에서 Vite는 매우 좋은 개발자 경험을 제공할 수 있기 때문에 최근 매우 유명해진 것이다.
Next.js는 React를 기반으로 구축된 프런트엔드 프레임워크이고, 특히 SSR
을 위한 프레임워크이다. 또한 정적인 웹 사이트를 개발할 때에는 웹 애플리케이션의 성능을 개선시킬 수 있으며 기존 React에서 사용하는 도구들과 호환되기 때문에 어렵지 않게 개발에 집중할 수 있다는 장점이 있다. 자세한 내용은 아래 공식문서를 참고하자.
왜 NextJS인가?(공식문서)
이번 프로젝트에서는
위의 내용을 더욱 공부해보고 싶었기 때문에 Vite + React + Typescript
를 사용하게 되었다.
지난 글에서 node_modules의 의존성 설치 때문에 정말 많은 시간을 에러 해결에 보냈던 고통스러운(?) 일을 겪고 나서 Yarn에 대한 장점을 찾아보다 아래 글을 발견하게 되었다.
node_modules로부터 우리를 구원해 줄 Yarn berry
이 글을 읽고 나서 Yarn berry를 이용해보고 싶다는 생각을 많이 했었고
이 있어서 이번 프로젝트에서는 꼭 사용해보자! 하여 적용해보게 되었다.
Yarn berry의 장점을 알기 위해서는 기존에 사용하던 Npm의 문제점에 대하여 먼저 짚고 넘어가야 한다.
Npm의 node_modules를 표현한 아래 그림을 보자.
그렇다.. node_modules는 정말 무겁다. 그래서 내 옛날 컴퓨터도 이 엄청난 용량과 복잡함을 견디지 못하고 개발할 때 너무 느려서 힘들었었다. 그럼 Yarn berry를 적용하고 나서는 어떤 장점들을 느낄 수 있을까 ?
더이상 복잡한 node_modules의 폴더들을 탐색하고 다닐 필요가 없다. .pnp.cjs
파일만이 있다면 이 친구가 제공해주는 자료구조를 이용하여 바로 의존성 위치를 찾을 수 있기 때문이다. 그리고 패키지의 관리는 해당 파일을 이용하기 때문에 다른 환경에 의하여 의존성 설치 및 관리를 다시 세팅할 필요가 없어졌다.
이제 무겁고 용량도 큰 node_modules 파일을 생성하지 않아도 된다. 그리고 의존성 관계가 잘못되어 강제로 버전이 맞지 않는 의존성을 설치한다던가 node_modules 파일을 다시 지우고 처음부터 install 해야 하는 번거로움이 생기지도 않는다.
협업할 때 힘들었던 점 중에 하나였는데 백엔드 개발자분께서 clinet 관련된 개발환경을 보고 싶다고 하셔서 깃허브 링크를 드린 다음에 Node modules 세팅 및 의존성 설치부터 .. 정말 복잡한 과정이 많았는데 의존성 관리도 github를 통하여 할 수 있어서 의존성 설치와 관리에 있어서 매우 편리해졌다. 이 말은 같은 프론트엔드 개발자들도 마찬가지였다!!
plug'n Play
는 node_modules의 파일 시스템을 이용하여 의존성을 관리하는 것이 아니라, package.json 기반으로 의존성 트리를 생성하고 node_modules를 구성하여 패키지의 의존성 구조를 이미 다 알도록 만드는 것이다.
npm에서 최신 버전의 yarn을 받고, 버전을 berry 버전으로 세팅하여 Yarn berry를 사용할 수 있다.
$ npm install -g yarn
$ cd ../path/to/some-package
$ yarn set version berry
이렇게 세팅하고 나면 node_modules 폴더가 아닌 .yarn
폴더가 생성되어 의존성 정보가 .yarn/cache
폴더에 저장된다. 그리고 .pnp.cjs
파일에 의존성을 찾을 수 있는 정보가 기록된다.
그리고 아래는 .pnp.cjs
파일이다.
#!/usr/bin/env node
/* eslint-disable */
"use strict";
function $$SETUP_STATE(hydrateRuntimeState, basePath) {
return hydrateRuntimeState(JSON.parse('{\
"dependencyTreeRoots": [\
{\
"name": "shopping-mall",\
"reference": "workspace:."\
}\
],\
"enableTopLevelFallback": true,\
"ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\
"fallbackExclusionList": [\
["shopping-mall", ["workspace:."]]\
],\
"fallbackPool": [\
],\
"packageRegistryData": [\
[null, [\
[null, {\
"packageLocation": "./",\
"packageDependencies": [\
["@emotion/css", "npm:11.10.6"],\
["@emotion/react", "virtual:56e2f830d7b2e0ed21a5b97c3f05cd0367f2ed1006e685a21e839e324bc395ace017167b32015c18f71a0aac4dd85772e359562d5eabf0663b57804a7b675079#npm:11.10.6"],\
..
이제 앱을 실행할 때 package.json
의 script에 실행 스크립트를 따로 작성하지 않아도 된다.
$ yarn dev
라고 입력하기만 해도 pnp로 의존성을 불러오기 때문에 자동으로 실행된다. 만약 zero-install을 사용하고 싶다면, gitignore
파일에 아래 내용을 설정하면 된다.
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
yarn berry 세팅과 Vite 설정을 마쳤는데 이게 왠걸.. 자꾸 모듈을 인식하지 못하는 현상이 발생하였다. 이것저것 구글링을 하다가 GDSC Hongik 커뮤니티에 질문을 남겼다.
친절하신 우리의 천재 프론트 개발자 폼프님이 답변을 남겨주셨고, 이대로 수행해보니까 해결할 수 있었다.
도대체 yarn dlx @yarnpkg/sdks vscode
가 뭐길래 , 그리고 타입스크립트 버전이 어떻길래!!! 모듈을 인식하지 못하는 오류가 발생하였던 걸까?🥲
구글링으로 찾아보았을 때 많은 분들의 해결책은 아래와 같았다.
1. yarn add @types/react @types/react-dom
을 이용하여 설치하여라
2. .d.ts
파일을 생성해서 모듈을 정의하고 선언해라
혹시 몰라 이 두가지 방법을 모두 시도해 보았으나 돌아온 것은 씁쓸한 에러였다..
위의 두가지를 실행해도 잘 되지 않던 것이 왜 typescript 버전을 맞추니까 잘 돌아가게 되었던 것일까?
결론적으로 이 부분은 내가 yarn berry를 세팅함으로써 만나게 되는 문제였던 것이다.
node_modules를 사용할 때에는 node_modules의 폴더 내부 구조를 기반으로 하여 의존성을 찾고, import를 하는 구조로 이루어졌다. 하지만 yarn berry에서는 이 폴더를 하나하나 탐색하는 것이 아니고, pnp 방식을 이용하기 때문에 import를 하기 위한 설정을 별도로 해 주어야 한다.
PnP를 이용해야 할 때 typescript가 작용할 수 있도록 위와 같은 코드를 작동하여 작업하고 있는 편집기에 대한 설정을 적용해주어야 한다.
$ yarn dlx @yarnpkg/sdks vscode
라는 명령어는 현재 SDK의 설정을 생성하겠다는 의미이다. Sdk는 소프트웨어 개발 키드 (Software Development Kit, SDK)를 의미하며 현재 내가 코드를 작성하고 있는 vscode의 개발 환경을 세팅하는 것이다. 더욱 자세한 내용은 아래 글을 읽어보자.
https://www.npmjs.com/package/@yarnpkg/sdks
이제 typescript를 현재 작업 영역 버전으로 설정해주면 타입스크립트를 yarn berry 환경에서도 문제 없이 이용할 수 있다. eslint와 같은 것도 같은 방법으로 설정해야 한다.
이제 프로젝트 세팅이 끝났으니 자주 쓰게 될 ui 세팅을 emotion으로 진행해보자!