전체 글 49

Next.js 모노레포 디자인 시스템 구축

💣 pnpm + Turborepo 기반 Tailwind 중심 Design System 구축이번 작업의 핵심은 단순히 모노레포를 구성하는 것이 아니라, Tailwind 기반 디자인 시스템을 공용 패키지로 분리하고, 각 앱이 이를 import만 해서 동일한 스타일을 사용하도록 만드는 구조 설계였습니다. 1. 전체 설계 의도1. Tailwind를 중심으로 한 설계 -> 단순히 Tailwind를 사용하는 것이 아니라, 디자인 시스템 자체를 Tailwind 유틸리티 구조 위에서 일관되게 관리할 수 있도록 만드는 것이 목적.2. 디자인 토큰과 앱 공통 스타일의 역할의 명확한 분리 -> color, typography, shadow처럼 디자인 규칙에 해당하는 영역과 실제 앱에서 사용하는 레이아웃이나 공통 래퍼 같은..

카테고리 없음 2026.02.16

Next CI/CD (with Vercel)

🌐CI/CD 배포 정리배포 방식: GitHub Actions + VercelFramework: Next.js목적: develop → Preview 배포 / main → Production 배포 자동화 배포 개요af-fe는 프론트엔드 Next.js 프로젝트로 Vercel + GitHub Actions를 이용한 자동 배포 파이프라인(CI/CD)을 구축함.develop 브랜치 → Preview 환경 자동 배포main 브랜치 → Production(실제 서비스) 자동 배포pnpm 패키지 매니저 + Node.js 20 버전 사용별도의 로컬 설치 없이 GitHub Actions에서 자동 빌드·배포 ⚙️ Vercel 세팅 절차▷ 프로젝트 생성https://vercel.com 접속Import Project → Git..

카테고리 없음 2025.10.27

🌐 리액트 프로젝트 초기세팅

⚛️ 초기세팅리액트 프로젝트를 위해서 react + vite + pnpm을 사용하여 초기세팅을 해줬다.일단, 사이즈를 반응형으로 적용되도록 px 말고 rem으로 사용하고, user, 사장님 페이지를 나눠서 관리를 해야 하는데, user는 앱화면, 사장님은 웹 화면으로 구성해야 했기에 react-router-dom의 oulet을 사용하여 layout으로 관리하기로 했다. PX to REM converter (instantly and bidirectional) PX to REM converter (instantly and bidirectional)PX ↔︎ REM conversion tables PixelsREM1px0.06rem2px0.13rem3px0.19rem4px0.3rem5px0.3rem6px0.4..

LOOPy's Project Hub 2025.07.11

🧠프로젝트를 위한 Github Flow 이해

🐈‍⬛ Git 브랜치 전략 여러 개발자가 하나의 저장소를 사용하는 환경에서 저장소를 효과적으로 활용하기 위한 work-flow다. 브랜치 생성에 규칙을 만들어서 협업을 유연하게 함. 🐈‍⬛ 2가지 브랜치 전략협업에서 효율성을 높이기에 아주 좋은 방식인데 그 중 가장 많이 쓰이는 게 git-flow, github-flow 전략이다. - Git-flow기본적인 가지의 이름은 아래의 5가지로 구분하곤 한다.feature > develop > release > hotfix > master위 순서들은 왼쪽으로 갈수록 포괄적인 가지이며 master branch를 병합할 경우 그 왼쪽에 있는 hotfix 등 모든 가지들에 있는 커밋들도 병합하도록 구성하게 된다.5가지 중, 항시 유지되는 메인 브랜치 maste..

LOOPy's Project Hub 2025.07.11

📱코틀린 플로

📱플로플로는 코틀린 프로그래밍 언어의 일부로, 코루틴 기반의 비동기 태스크들로부터 순차적으로 여러 값을 반환할 수 있도록 설계되었다. 플로는 생산자, 중재자, 소비자로 구성되고,생산자는 데이터를 제공하며, 이 데이터가 플로를 구성한다.소비자는 플로 스트림의 반대편 끝에 위치하며 생산자가 방출한 데이터를 수집한다. 중재자는 생산자와 소비자 사이에 위치하며, 데이터가 소비자에게 도착하기 전에 스트림을 필터링 하거나 다른 방식으로 변환하는 등 데이터에 추가적인 처리를 수행한다. -> FlowDemo 프로젝트 구현하기하나 이상의 중재자 플로 연산자를 사용해 생산자와 소비자 사이에서 데이터를 변경할 수 있다. map() 연산자는 값을 다른 값으로 변환하고, 수집된 값마다 변환을 수행한다.filter() 연산자를..

카테고리 없음 2025.06.04

🍎 useCallback, useMemo, memo를 이용한 최적화

🌐 최적화를 어떻게 하나일단, TMDB를 이용해서 간단한 영화 사이트를 만들 것이다. 검색 필터링영화 무비tmdb 내에 search에서 무비 들어가면 include_adult (성인), language(언어), 개봉일, 페이지원래 검색어 같은 경우는 쿼리를 활용해보는 것도 좋다. 이런 tmdb에서 api를 불러오기 위해서 api 파일을 만들어준다. (axios 활용을 위해서 다운로드 해준다.)$ pnpm add axios import axios from "axios";export const axiosClient = axios.create({ baseURL: "https://api.themoviedb.org/3", headers: { Authorization: `Bearer ${..

🐻zustand로 장바구니 만들기🛒

리덕스 툴킷을 활용해서 만든 장바구니를 zustand로 만들 것이다. 리덕스 툴킷을 타입 세이프티하게 Cart Slice를 만들어서 장바구니 즉, 음반 바구니를 만들어 봤었다. 리덕스 툴킷 같은 경우는 리덕스만 활용했을 때보다는 개념 자체가 훨씬 간단하고 자체적으로 immer라는 내장 라이브러리가 들어가 있어서 불변성을 굳이 매핑 한다거나 따로 처리를 해줘야 할 필요가 없었다. (스프레드 연산자를 활요해서 이전 상태를 항상 유지해주는 불변성을 유지하는 작업 불필요.) 그래도 보일러 플레이트가 있다. 보일러 플레이트 예를 들어 중앙 저장소, 액션에 대한 타입들도 훅으로 따로 추출, slice 등을 만들었는데 더욱 큰 프로젝트를 하면 더욱 복잡해질 것이다. 그렇기 때문에 zustand로 처리를 해볼 것이다..

🐻 Zustand 배우기

Zustand 라이브러리에 대해서 활용을 해볼 것이다. 리덕스 툴킷을 활용해서 쇼핑카트를 UI부터 끝까지 만들어 봤다. 보일러 플레이트나 라이브러리가 좀 가벼운 zustand를 많이 활용해보는 것이 좋다.zustand는 전역 상태관리에서 많이 사용하는 라이브러리이다. 프로젝트 생성pnpm create vite zustand 다운로드 pnpm i zustand zustand로 관리import './App.css';import Counter from './components/Counter';import RandomNumberGenerator from './components/RandomNumberGenerator';function App() { return ( )}e..

🔧Redux-Toolkit을 활용해서 쇼핑 카트 만들기

기존에 context API를 활용하면서 코드가 복잡해지고 비교적 간단한 데이터를 공유해야 하고, 빈번하게 렌더링이 발생한다거나 자체적으로 지원해주는 미들웨어 기능 같은 것이 없다. 리듀서를 활용했을 때 어떤 것이 문제이고 이 문제를 해결하기 위해서 리덕스 툴킷이 왜 도입되었는지 집중해서 활용해보는 것이 좋다. 기존에 만든 영화 서비스와는 다르게 장바구니 서비스를 만들 것이다. 서버 api는 존재 x.리덕스 툴킷을 활용하면 비동기 처리 미들 웨어 등을 활용해서 처리할 수 있다. 리덕스 툴깃으로 장바구니 서비스 만들기$ pnpm create vite$ pnpm i 장바구니 서비스 관련 프로젝트를 생성한다. (+ 의존성 설치) tailwindcss도 설치$ pnpm install tailwindcss @..

🍎 useReducer를 왜 쓸까

useState와 다른 게 무엇이 있는지 확인하기 위해서 useReducerPage를 만들어 볼 것이다.import { useState } from "react";export default function UseReducerPage() { const [count, setCount] = useState(0); const handleIncrease = () => { setCount(count + 1); }; return ( {count} Increase );} 이 코드를 비교하면서 차이점을 보려고 한다. 일단, useState와 useReducer 둘 다 상태를 관리하고 업데이트를 시키는 훅이기는 하다..