Frontend · React Native · Platform

설계와 운영 사이

사용자에게 보이는 기능부터 빌드·배포 환경까지. 제품을 만들며 경험한 기술적 의사결정과 문제 해결 과정을 기록합니다.

195 POSTS

전체 글

사용자에게 보이는 기능부터 빌드·배포 환경까지. 제품을 만들며 경험한 기술적 의사결정과 문제 해결 과정을 기록합니다.

[배포 파이프라인 보안] AWS 정적 키를 GitHub OIDC로 걷어내기 Architecture/CI-CD

[배포 파이프라인 보안] AWS 정적 키를 GitHub OIDC로 걷어내기

레포 네 곳이 복사해 쓰던 IAM 액세스 키 한 쌍을 GitHub Actions OIDC로 바꾼 과정을 공유합니다. 설정 방법보다는 trust policy 범위를 어떻게 정했는지, 전환하면서 무엇이 깨졌는지를 중심으로 다룹니다.들어가며이번 작업의 출발점은 보안이 아니었습니다. 처음 질문은 "환경변수를 Doppler 대신 AWS Secrets Manager로 옮기는 게 낫지 않을까?"였습니다. 레포를 하나씩 열어보니 옮길 이유가 없었습니다. 대신 다른 문제가 보였습니다. 바꿔야 할 것은 시크릿 저장소가 아니라 AWS에 인증하는 방식이었습니다.무엇이 문제였나저희 팀의 배포 대상은 대부분 S3와 CloudFront입니다. 웹 앱은 S3에 정적 파일을 올리고 CloudFront 캐시를 비우고, 모바일 앱은 Co..

2026.10.01 댓글
Architecture/CI-CD

AI 테스트 코드 자동 생성, GitHub Actions로 누락까지 잡기

AI 코딩 도구에 "테스트도 같이 짜줘"를 매번 말하는 대신, 테스트 코드 자동 생성 기준을 .test-policy.json 한 파일로 빼고 누락은 GitHub Actions가 잡도록 만들었습니다. React Native 모노레포에서 5개월 굴린 결과와, 그 과정에서 내린 설계 결정들을 공유합니다.들어가며테스트를 안 짜는 이유는 대부분 "귀찮아서"가 아니라 "지금 당장 급해서"입니다. 기능 하나 붙이는 데 30분, 테스트 짜는 데 30분이면 후자가 먼저 잘려 나갑니다. 그렇게 몇 달이 지나면 테스트 없는 코드가 기본값이 되고 이제 와서 다시 쌓기엔 너무 늦었다는 기분이 듭니다.AI 코딩 도구를 쓰면 이 계산이 달라집니다. 테스트 작성 비용이 30분에서 0분에 가까워지니까요. 그런데 비용만 낮아진다고 테스..

2026.09.11 댓글
Engineering/Mobile

앱 에셋 140MB를 13MB로 — png 1,313장 webp·svg 전환기

세 개의 React Native 앱에 png가 1,313장, 140.84MB 쌓여 있었다. webp 변환과 svg 아이콘화, 미사용 파일 정리로 13.48MB(-90.4%) 까지 줄였다. 메인 앱의 AAB는 240MB에서 177.5MB로 62.5MB(-26%) 가벼워졌다. 작업 자체는 단순하다. 정리할 만한 건 그 과정에서 알게 된 쪽이다. 이미지가 앱 용량의 어디에 들어가는지, AAB의 나머지를 무엇이 차지하는지, lossy 변환을 어디에 적용해야 하는지.들어가며앱이 무겁다는 이야기가 나왔다. 스토어 등록본이 240MB였으니 그럴 만했다.가장 먼저 눈에 띈 건 이미지였다. 세 앱의 assets/images를 세어보니 png가 1,313장, 합쳐서 140.84MB였다. 몇 년치 화면이 쌓이는 동안 아무도..

2026.09.08 댓글
Engineering/Mobile

React Navigation 심화 — 컴포넌트 트리 밖에서 안전하게 화면 전환하기

React Navigation을 쓰다 보면 useNavigation()이 닿지 않는 곳에서 화면을 옮겨야 할 때가 온다. 딥링크 핸들러, 푸시 알림 콜백, 외부 SDK 콜백, 전역 인터셉터 같은 "컴포넌트 트리 바깥"이다. navigationRef를 쓰면 되지만, 막상 해보면 빈 화면·흰 화면 같은 타이밍 버그가 줄줄이 튀어나온다. 이 글은 트리 밖 화면 전환을 실제로 안정적으로 만들기까지 밟은 과정과, 그 사이에 만난 버그들의 정리다.문제 — useNavigation이 닿지 않는 곳화면 전환은 보통 컴포넌트 안에서 useNavigation() 훅으로 한다. 그런데 React 컴포넌트가 아닌 곳에서 전환을 트리거해야 하는 경우가 의외로 많다.딥링크 핸들러 — linking.getInitialURL / s..

2026.06.08 댓글
Engineering/FrontEnd

useEvent 패턴 — 부모 리렌더링이 자식 effect를 폭주시키는 문제 해결하기

리액트로 외부 라이브러리나 SDK를 붙이다 보면 한 번쯤 마주치는 함정이 있다. 부모에서 콜백을 prop으로 넘겼을 뿐인데, 부모가 리렌더링될 때마다 자식의 useEffect가 통째로 다시 실행되는 현상이다. 이 글에서는 그 원인을 짚고, useEvent라는 한 줄짜리 훅으로 깔끔하게 해결하는 방법을 정리한다.어떤 문제인가리액트에서 자식 컴포넌트(특히 외부 라이브러리)에 콜백을 prop으로 넘길 때, 자식이 그 콜백을 useEffect의 deps 배열에 잡고 있으면 문제가 생긴다. 부모가 리렌더링될 때마다 새 콜백 reference가 만들어지고, 그 reference 변화가 자식의 effect를 매번 재실행시킨다.// 자식 (외부 라이브러리라고 가정)function ThirdPartyWidget({ on..

2026.06.08 댓글
iOS 빌드 인프라, 어디서 돌릴까 — 6가지 옵션 비교와 self-hosted runner 구축기 Architecture/CI-CD

iOS 빌드 인프라, 어디서 돌릴까 — 6가지 옵션 비교와 self-hosted runner 구축기

React Native 모노레포의 iOS 빌드를 어디서 돌릴지 고민하며 6가지 인프라 옵션을 비교했고, 최종적으로 사내 Mac에 GitHub Actions self-hosted runner를 붙였습니다. 옵션별 비교, 우리가 self-hosted를 고른 이유, 그리고 self-hosted 특유의 함정(코드 서명·키체인)을 어떻게 넘었는지 공유합니다.들어가며저희 팀은 여러 개의 React Native 앱을 하나의 Nx 모노레포에서 운영하고 있습니다. 빌드/배포 파이프라인은 GitHub Actions 위에 올라가 있고, Git 태그를 푸시하면 해당 앱이 Stage/Prod로 빌드되는 구조입니다. Android는 Linux runner에서 잘 돌아갑니다. 문제는 항상 iOS였습니다.iOS 빌드는 macOS에서..

2026.06.05 댓글
Architecture/Monorepo

Yarn Berry PnP 마이그레이션 — node_modules를 없앤 이유와 과정

Nx 웹 모노레포에서 Yarn v1(Classic)을 Yarn v4(Berry) + PnP로 전환한 과정을 공유합니다. 왜 전환했는지, PnP가 뭔지, 마이그레이션 중 어떤 문제를 만났는지를 다룹니다.들어가며저희 팀은 Nx 기반 웹 모노레포를 Yarn v1(Classic)으로 운영하고 있었습니다. 큰 문제 없이 잘 돌아가고 있었는데, 마이그레이션 과정에서 axios, lodash, qs, uuid, react-router 같은 패키지가 package.json에 선언되지 않았는데도 사용되고 있었다는 사실을 발견했습니다.이런 현상이 왜 발생하는지, 그리고 이를 해결하기 위해 Yarn Berry의 PnP(Plug'n'Play)로 전환한 과정을 정리합니다.Yarn v1의 node_modules, 뭐가 문제인가호..

2026.04.17 댓글
웹 모노레포 CI/CD 개편기 — 라벨 배포에서 태그 배포로 Architecture/CI-CD

웹 모노레포 CI/CD 개편기 — 라벨 배포에서 태그 배포로

Nx 웹 모노레포에서 PR 라벨 기반 배포를 걷어내고, Git 태그 + Doppler로 배포 파이프라인을 재설계한 과정을 공유합니다.들어가며저희 팀은 Nx 기반 웹 모노레포에서 여러 앱을 운영하고 있습니다. 관리자 페이지, 백오피스, 로그인 페이지, 웹뷰 등 성격이 다른 앱들이 하나의 레포에 들어 있고, 각각 독립적으로 빌드/배포됩니다.초기에는 PR 라벨로 배포를 트리거하고, 환경변수는 GitHub Secrets에 앱별로 등록하는 방식이었습니다. 앱이 2~3개일 때는 문제가 없었지만, 앱과 환경이 늘어나면서 관리가 어려워졌습니다.이 글에서는 기존 방식의 문제점, 태그 기반 배포로의 전환, Doppler를 활용한 환경변수 관리, 그리고 최종 CI/CD 파이프라인 구조를 다룹니다.기존 방식의 문제점PR 라벨..

2026.04.17 댓글
React Native 모노레포에서 앱 빌드 및 배포 전략 설계하기 Architecture/CI-CD

React Native 모노레포에서 앱 빌드 및 배포 전략 설계하기

들어가며저희 팀은 4개의 React Native 앱을 운영하고 있습니다. 처음에는 각각 독립된 레포지토리로 관리했지만, 앱이 늘어나면서 공통 코드 중복, 의존성 파편화, CI/CD 파이프라인 중복 등의 문제가 반복되었습니다. 이를 해결하기 위해 Nx + pnpm 기반 모노레포로 통합했고, 이 글에서는 통합 이후 빌드 타입 분리, 브랜치 전략, 태그 기반 배포, CodePush 운영 방식을 어떻게 설계했는지 다룹니다.모노레포 자체의 마이그레이션 과정은 이 글의 범위를 벗어나므로, 빌드와 배포 전략에 집중합니다.서버 환경 구성제약 조건설계에 앞서 몇 가지 제약 조건이 있었습니다.서버팀 요구사항: 테스트 데이터가 Prod DB에 올라가면 안 됨 → Stage 서버 사용 필수내부 테스트(QA)와 심사 제출이 별..

2026.04.17 댓글
Notes/JavaScript

실행 컨텍스트(Execution Context) 완벽 이해

자바스크립트를 조금 깊게 공부하다 보면“실행 컨텍스트(Execution Context)” 라는 용어가 꼭 등장합니다.이 개념은 스코프(Scope), 클로저(Closure), this 바인딩 같은자바스크립트의 핵심 원리를 이해하기 위한 기초 중의 기초예요.💡 실행 컨텍스트란?“자바스크립트 코드가 실행되는 환경”조금 더 구체적으로 말하자면,자바스크립트 엔진이 코드를 실행할 때변수, 함수, this, 스코프 정보 등을 관리하기 위한 객체입니다.즉, 어떤 코드가 “어디서, 어떤 환경에서, 어떤 변수들을 가지고 실행되는가”를 결정하는 일종의 실행 박스라고 보면 됩니다.⚙️ 실행 컨텍스트의 종류종류설명전역 컨텍스트 (Global Context)코드가 처음 실행될 때 단 한 번 생성. 전역 변수, 함수 선언이 등록..

2025.10.18 댓글