월간 사이드 프로젝트의 시작
1월 초, 올해 이루고 싶은 목표가 담긴 만다라트를 작성했다. 8개의 주제 중 하나가 사이드 프로젝트였다. 그동안 사이드 프로젝트를 거의 하지 못했다. 기획, 디자인, 개발까지 크게 만들어야 한다는 부담감에 시작조차 어려웠다.
그러던 중, 인프콘 2024에서 조현우 님의 발표 ‘사이드 프로젝트로 커리어 레벨업!’ 영상을 보게 되었다. 해당 발표에서 가장 마음에 와닿던 메시지가 있었다.
프로젝트의 핵심은 완성하는 것이다.
몰입을 유지할 수 있도록 2~3일 내에 끝낼 수 있는 작은 사이즈로 진행하는 게 좋다.
발표 덕분에 ‘작은 프로젝트라도 완성하면 충분히 의미가 있구나!’라는 인사이트를 얻을 수 있었고 그렇게 월간 사이드 프로젝트를 시작하게 되었다.
목표는 단순하다.
거창해지지 않기
기존 서비스 개선해보면서 새로운 기술 배우기
현재 가장 관심있는 주제로 작은 서비스 만들어보기
이렇게 정리하니 만들고 싶은 아이디어가 꽤 떠올랐다.
1월 : 기존 프로젝트 마이그레이션!
4년 전 만든 반려견 입양 체크리스트 프로젝트를 최신 환경에 맞춰 마이그레이션 하기로 했다. 기존 레포지토리에 변경 이력을 남기기 위해서 브랜치를 생성해서 작업했다.
진행한 작업
TypeScript 도입
먼저, 프로젝트가 오래된 만큼 패키지 호환성을 확인하는 작업이 필요했다.
npm outdated
이 결과를 바탕으로 react-scripts
를 최신 버전으로 업데이트했다.
npm install react-scripts@latest
타입을 최신 버전으로 설치했더니 React보다 높은 19 버전이 설치되면서 호환성 문제가 발생했다. 현재 사용 중인 React 메이저 버전에 맞춰 타입을 다운그레이드해서 문제를 해결했다.
npm install --save-dev @types/react@17 @types/react-dom@17
Typescript 설정 파일 생성
npx tsc --init
global.d.ts 파일에서 전역 인터페이스 확장
카카오톡 공유 기능있어서 카카오 SDK를 사용하고 있었다. Window 객체에 Kakao 객체의 타입이 없어서 전역 인터페이스에 명시적으로 선언해 주었다.
declare global {
interface Window {
Kakao: any;
}
}
React 버전 업데이트 : 17 → 18
React와 라이브러리 간의 버전 호환성 확인한 뒤 버전 업데이트를 진행했다.
npm list react react-dom
React Scripts에서 Vite로 전환
CRA(Create React App)에서 Vite로 마이그레이션을 진행했다.
Vite 도입 이유
개발 환경에서 ES 모듈을 사용하여, 필요한 모듈만 로드하기 때문에 빠른 HMR(Hot Module Replacement)가 가능하다.
프로덕션 빌드시 Rollup(여러개의 모듈을 하나의 파일로 병합해주는 도구)을 사용하여 최적화된 번들링을 제공한다.
vite.config.ts
파일을 통해 설정 커스터마이징이 쉽다. 다양한 플러그인도 사용 가능하다.
번들 크기 및 성능 비교
CRA는 webpack-bundle-analyzer
를 사용하고 Vite는 rollup-plugin-visualizer
를 사용해서 번들 크기나 속도 차이를 비교해 보았으나 프로젝트 규모가 작아서 큰 차이를 발견하긴 어려웠다.
적용 순서
CRA 종속성 제거 :
npm uninstall react-scripts
Vite 설치 :
npm install --save-dev vite @vitejs/plugin-react
Vite 설정 파일 생성 및 설정
// vite.config.ts import { defineConfig, PluginOption } from "vite"; import react from "@vitejs/plugin-react"; import vitetsConfigPaths from "vite-tsconfig-paths"; import { visualizer } from "rollup-plugin-visualizer"; export default defineConfig(({ mode }) => { const isLocal = mode === "development"; return { base: "/", plugins: [ react(), vitetsConfigPaths(), isLocal ? [ visualizer({ filename: "./dist/stats.html", // 결과 파일 경로 template: "treemap", // 그래프 유형: 'treemap', 'sunburst', 'network' open: true, gzipSize: true, brotliSize: true, }) as PluginOption, ] : [], ], resolve: { alias: { "@/*": ["src/*"], }, }, server: { open: true, port: 3000, }, build: { outDir: "build", }, }; });
Vite 스크립트 추가
// package.json "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "visualize": "vite build --mode development" }
Vite 환경에 맞게 코드 변경
CRA의
process.env.REACT_APP_*
환경 변수를import.meta.env.VITE_*
형태로 변경index.html
위치 조정 및 script 태그 추가
index.html 위치 변경하고 script 태그 추가 하는 이유
Vite는 CRA와 달리 index.html
이 애플리케이션 엔트리 포인트로 사용되기 때문에 public/index.html
위치를 프로젝트 루트로 이동해야 한다. 또한 Vite 개발 서버는 번들링 없이 파일을 브라우저에 직접 전달하므로 ES 모듈을 사용하도록 script태그를 추가해야 한다.
<script type="module" src="/src/index.tsx"></script>
React Query 도입
서버 데이터를 가져와서 클라이언트 상태에 저장하고, 에러를 처리하던 기존 로직을 서버와 클라이언트 상태의 역할을 명확히 분리하도록 개선했다.
Feature-Sliced Design(FSD) 적용
프로젝트 구조를 개선하기 위해서 Feature-Sliced Design(FSD) 을 적용하고 있다. FSD는 기능(feature)별로 레이어를 나누고, 의존성을 단방향으로 흐르게 하는 구조 패턴이다. FSD를 적용하면서 각 요소가 어느 레이어에 속해야 하는지 고민이 많이 되었다. 다음과 같은 질문을 기준으로 적용했다.
이 로직이 특정 페이지 전용인가? =>
pages/
에 위치여러 곳에서 공유될 가능성이 있는가? =>
shared/
에 위치비즈니스 로직을 어느 레이어에 두는 게 적절한가? =>
model/
,api/
에 위치
실제로 적용해보니 100% 완전히 맞춰서 구조를 적용하는게 불가능하다는 걸 깨달았다. 결국 중요한 건 FSD를 엄격하게 적용하는 것이 아니라 의존성 관리 관점에서 가장 적절한 구조를 고민하는 게 더 중요하다는 생각이 들었다. 그래서 스스로 ‘이 구조가 유지보수를 더 쉽게 만들까?’ 라는 질문을 스스로 던지는 시간을 많이 가졌다. 사용하는 도구에 종속되지 않으면서 유지보수를 더 쉽게 하는 방법을 고민할 수 있어서 뜻깊은 작업이었다.
마무리 : 이번 프로젝트에서 무엇을 배웠는가
마이그레이션을 진행하면서, 기술 도입을 결정하는 과정에서 스스로 이유에 대해서 질문하는 개 중요하다는 걸 배웠다. 작은 프로젝트임에도 불구하고, 예상보다 작업할 부분이 많았고, 특히 기술적 선택을 내리는 과정에서 진행할 작업과 우선순위를 정할 때 많이 고민했다.
기술 도입이 반드시 필요한가
작업 초반에는 Next.js app router를 도입할 생각이었다. 그러나 진행하면서 ’Next.js 를 지금 도입해야 하는 이유가 있는가?’라는 질문을 던졌고, 결국 도입하기 않기로 결정했다. 나중에 추가 기능 도입할 예정이면 그때 도입하면 되고, 해당 서비스는 체크리스트 페이지이므로, 메인 페이지만 노출되면 되기에 SEO 관련된 문제도 없었기 때문이다. 기술적 도입을 검토하는 과정이 중요하다는 걸 깨달았다.
기술 도입시 해야 하는 질문
이 기술을 지금 도입해야 하는가 ?
도입한다면 어떤 문제를 해결하기 위해서 도입해야 하는가?
우선순위는 어떻게 가져갈 것인가?
나만의 사이드 프로젝트를 진행하는 즐거움
사이드 프로젝트는 모든 기술적 결정을 내가 원하는 방향으로 자유롭게 진행할 수 있어서 즐거웠다. 실무에서 하던 고민을 그대로 하면서 기술적인 실험을 할 수 있어서 좋았다. 2월 프로젝트는 역도 관련된 서비스를 만들어볼 계획이다. 내가 실제 사용자가 되는 프로젝트라서. 사용자 관점에서 기능을 고민할 수 있을 것 같아서 기대된다!