yarn

2 개의 포스트

toss5분 읽기큐레이션 요약

모노리포 희망편, 절망의 리포가 희망의 리포로 부활하기까지 걸린 1년

토스는 100명 이상의 프론트엔드 엔지니어가 여러 제품을 개발하면서도 React 19, Next.js 15 등 동일한 개발환경을 유지하기 위해 모노리포와 의존성 카탈로그를 활용하고 있습니다. 단순히 모노리포를 사용하는 것만으로는 서비스별 의존성 버전 파편화와 느린 설치 속도 문제를 해결할 수 없었기 때문에, 핵심 라이브러리 버전을 표준화하는 카탈로그 전략을 도입했습니다. 그 결과 의존성 규모와 설치 시간이 크게 줄었고, 플랫폼 변경과 최신 기술 도입도 더 안전하고 빠르게 진행할 수 있게 되었습니다. ## 모노리포가 제공한 개발 일관성 - 토스의 모바일 제품 코드는 하나의 모노리포로 통합되어 있습니다. - 모든 서비스가 React, Next.js, TypeScript, 번들러, Linter 등 유사한 버전을 사용하도록 관리되었습니다. - 이를 통해: - React Concurrent Mode, React Server Components 같은 최신 기능을 여러 서비스에서 활용할 수 있습니다. - 서비스 간 공통 코드와 플랫폼 라이브러리를 쉽게 공유할 수 있습니다. - 플랫폼 변경사항을 전체 서비스에 일관되게 전파할 수 있습니다. - 제품이 많아도 동일한 개발환경을 유지해 사용자 경험과 개발자 경험을 함께 개선하는 것이 목표였습니다. ## 모노리포만으로 해결되지 않은 문제 - 서비스마다 React와 각종 라이브러리의 버전이 달라 의존성 트리가 복잡했습니다. - 오래된 서비스는 낡은 개발환경을 계속 사용하게 되어 개발 서버 속도와 API 사용성에서 큰 차이가 났습니다. - 의존성 종류와 버전이 많아 설치에 캐시가 있어도 1분 이상 걸리는 경우가 있었습니다. - 플랫폼 팀은 다양한 React 및 라이브러리 조합을 모두 테스트해야 했기 때문에 공통 라이브러리 변경이 어려웠습니다. - 서비스 개발자도 업데이트 후 문제가 발생할 가능성을 우려해 플랫폼 라이브러리 업데이트를 기피했습니다. - 결과적으로 오래된 의존성이 고착되고, 서비스와 플랫폼 양쪽의 유지보수 비용이 커졌습니다. ## 폴리리포의 한계 - 모노리포를 여러 개의 독립적인 리포지토리로 나누면 각 저장소의 의존성과 설치 부담은 줄어듭니다. - 그러나 다음 문제는 오히려 남거나 심해질 수 있습니다. - 서비스별 개발환경 파편화 - 공통 코드 공유와 업데이트 비용 증가 - 서비스마다 다른 개발 경험 - 플랫폼 변경사항의 일관된 전파 어려움 - 토스는 지속적으로 플랫폼을 유지보수하고 최신화해야 하므로, 폴리리포보다는 기존 모노리포의 의존성 문제를 해결하는 방향을 선택했습니다. ## 핵심 해결책: 의존성 버전 표준화 - 가장 근본적인 문제를 “서비스마다 핵심 의존성 버전이 모두 다르다”는 점으로 정의했습니다. - React, 컴포넌트 라이브러리(TDS), 상태 관리 라이브러리(Jotai), TypeScript, ESLint 등 약 10~20개의 주요 라이브러리를 표준화 대상으로 삼았습니다. - 핵심 의존성 버전을 통일하면: - 설치해야 할 의존성의 종류와 개수가 줄어듭니다. - 모든 서비스에서 비슷한 개발 경험을 제공합니다. - 플랫폼 라이브러리의 테스트 환경이 단순해집니다. - Breaking change에 대응하는 코드 변환 스크립트나 호환성 레이어를 만들기 쉬워집니다. - 서비스 개발자가 검증된 최신 라이브러리로 업데이트할 유인이 커집니다. - 대부분의 개발자는 “React가 필요하다”고 결정할 뿐 특정 버전을 직접 선택할 필요는 없다는 점도 표준화의 근거가 되었습니다. ## 카탈로그를 통한 버전 관리 - 토스는 서비스에서 권장하는 표준 라이브러리 버전 집합을 **카탈로그(Catalog)**라고 정의했습니다. - pnpm이나 Yarn의 카탈로그 기능을 사용해 모노리포의 공통 버전을 선언합니다. ```yaml catalog: react: ^18.2.0 jotai: ^2.18.1 ``` - 각 서비스는 `catalog:` 프로토콜로 버전을 참조합니다. ```json { "dependencies": { "react": "catalog:", "jotai": "catalog:" } } ``` - 안정 버전과 실험 버전을 별도 카탈로그로 관리할 수도 있습니다. ```yaml catalogs: stable: react: ^18.2.0 jotai: ^2.18.1 beta: react: ^19.1.0 jotai: ^2.20.1 ``` - 이후 서비스는 `catalog:stable`처럼 특정 카탈로그를 선택할 수 있습니다. - React, Next.js, TypeScript, TDS, 토스 앱 SDK 등 핵심 개발 라이브러리부터 카탈로그에 편입했습니다. ## 카탈로그 도입과 운영 방식 - 카탈로그 패키지는 릴리즈 전에 주요 사용 사례를 테스트 페이지로 검증했습니다. - 신규 서비스는 최신 카탈로그를 자동으로 참조하도록 스캐폴딩했습니다. - 개발자가 `yarn add`로 직접 패키지를 추가해도 카탈로그 버전을 사용하도록 했습니다. - 실수로 카탈로그를 사용하지 않는 경우를 CI에서 자동 검출했습니다. - 기존 서비스는 코드 오너와 함께 의존성을 카탈로그 참조 방식으로 일괄 마이그레이션했습니다. - 카탈로그 버전을 변경할 때는 기존 카탈로그를 직접 수정하지 않고 새 버전을 발행했습니다. - 일부 서비스에서 먼저 검증 - 안정성 확인 - 전체 서비스가 새 카탈로그로 수동 마이그레이션 - 업그레이드 비용을 낮추기 위해 코드 수정 스크립트와 AI Skill도 제공했습니다. ## 카탈로그 적용 후의 성과 - 서비스별 의존성 버전이 통일되면서 전체 의존성 규모가 크게 감소했습니다. - Yarn PnP의 `.pnp.cjs` 파일 크기: - 96MB → 15MB - 약 84% 감소 - 개발 서버 실행 시간: - 26.7초 → 20.3초 - 약 23% 개선 - 전체 의존성 설치 시간: - 528.4초 → 249.9초 - 약 52% 감소 ## 검증된 의존성과 구조적 개선 - 카탈로그에 포함된 패키지는 최소 한 개 이상의 서비스에서 동작을 검증해야 하므로 사용 신뢰도가 높아졌습니다. - 패키지 간 의존성도 엄격하게 관리할 수 있게 되었습니다. - 예를 들어 A 패키지가 B의 v1에 의존하는데 서비스가 B의 v2를 사용하는 식의 불일치를 예방할 수 있습니다. - 어떤 서비스가 어떤 버전을 사용하는지 파악하기 쉬워져 패키지 개발자가 대규모 구조 개선을 추진하기 수월해졌습니다. - 그 결과 RSC, TypeScript 7, Rspack, E2E 테스트 같은 급진적인 기술 개선도 비교적 빠르고 안정적으로 도입할 수 있었습니다. - 플랫폼 패키지의 개선사항이 서비스에 전달되는 경로가 표준화되어, 서비스가 최신 플랫폼의 혜택을 더 빠르게 받을 수 있는 기반도 마련되었습니다. ## 실용적인 결론 모노리포의 효과를 극대화하려면 저장소를 하나로 합치는 것만으로는 부족합니다. 핵심 의존성의 버전을 카탈로그로 표준화하고, CI 검증·자동 마이그레이션·단계적 릴리즈를 함께 운영해야 서비스 간 일관성, 설치 성능, 플랫폼 업데이트 속도를 동시에 개선할 수 있습니다.

원문 읽기(새 탭에서 열림)
datadog원문

엔지니어링 스포트라이트: 마엘 니송 (새 탭에서 열림)

인도양의 작은 섬 레위니옹에서 시작해 자바스크립트 생태계의 핵심 도구인 Yarn의 메인 유지보수자가 되기까지, Maël Nison의 여정은 끊임없는 호기심과 오픈소스에 대한 열정으로 가득 차 있습니다. 그는 페이스북 부트캠프를 통해 Yarn 프로젝트에 합류한 뒤, 단순한 기여자를 넘어 프로젝트를 TypeScript 기반의 모듈형 구조로 재설계하고 커뮤니티 주도형 프로젝트로 탈바꿈시키는 데 결정적인 역할을 했습니다. 현재 Datadog의 프론트엔드 플랫폼 팀에서 근무하면서도 Yarn의 비전과 로드맵을 이끄는 그는, 기술적 해결책을 모두와 공유하는 오픈소스 정신이 개인과 공동체를 어떻게 성장시키는지 잘 보여줍니다. **Yarn의 진화와 다각적인 리더십** * 페이스북 입사 초기, 신규 입사자 교육 프로그램인 '부트캠프'를 통해 Yarn 프로젝트를 접하고 업무 시간의 상당 부분을 오픈소스 기여에 투입하기 시작했습니다. * 초기 내부 도구 성격이 강했던 Yarn을 TypeScript로 완전히 재작성하고 아키텍처를 모듈화하여, 특정 기업에 종속되지 않는 진정한 커뮤니티 오픈소스 프로젝트로 발전시켰습니다. * 프로젝트를 관리하며 개발자 역할을 넘어 제품 매니저, 팀 리드, 고객 지원, 인프라 설계, 웹 디자인 등 다방면의 역할을 수행하며 '1인 CEO'와 같은 경험을 쌓았습니다. **DarkBASIC에서 시작된 프로그래밍의 기초** * 프랑스 툴루즈의 중학교 시절, 점심시간마다 모이던 프로그래밍 클럽에서 DarkBASIC이라는 게임 제작 언어를 배우며 개발의 세계에 입문했습니다. * 화면 위에서 물고기가 움직이고 거품을 쏘는 간단한 2D 게임을 만들며, 코드를 수정하면 즉시 결과가 바뀌는 논리적인 과정에 매료되어 평생의 직업으로 삼기로 결심했습니다. * 2000년대 초반 3G 네트워크와 펜티엄 III 프로세서가 표준이던 시절부터 PHP 웹사이트를 구축하고 SQL 취약점을 직접 경험하며 실전 기술을 익혔습니다. **워크플로우 최적화와 실용적 교육** * 깃허브(GitHub)가 없던 시절, 포럼을 통해 소스 코드를 공유하며 누구나 필요한 해결책을 사용할 수 있게 하는 오픈소스의 본질을 체득했습니다. * 기존 CMS(콘텐츠 관리 시스템)들의 복잡한 관리 페이지 구조에 의문을 품고, 게시물을 클릭해 즉시 수정하는 직관적인 워크플로우를 고민하며 '사용자 경험 최적화'에 대한 철학을 세웠습니다. * 이론보다 실무 중심의 프로젝트와 동료 평가를 중시하는 프랑스의 교육 기관 EPITECH에서 수학하며, 자기 주도적 학습 역량과 실용적인 엔지니어링 기술을 연마했습니다. Maël Nison의 사례는 단순히 기술적인 숙련도를 높이는 것을 넘어, 자신이 마주한 불편함을 해결하고 그 결과물을 커뮤니티와 공유하는 습관이 어떻게 세계적인 오픈소스 리더로 성장하는 밑거름이 되는지 보여줍니다. 새로운 기술을 익힐 때 단순히 사용법을 익히는 데 그치지 않고, 오픈소스 프로젝트에 작은 기여부터 시작해 보는 것은 커리어 개발과 기술적 통찰력을 동시에 얻을 수 있는 가장 확실한 방법입니다.