이슈 발생
시형님 ! 예전 코드로 다시 원복해서 빌드했는데 예전 캐시가 적용이 안돼요.
평온히 개발하고 있던 어느날 다음과 같은 이슈가 발생했다. 사내 프로젝트에서 Turborepo를 활용해 모노레포를 구축하여 사용하고 있는데, 갑자기 예전에 빌드된 캐시가 코드에 적용되지 않는 현상이 발생한 것이다.
Turborepo는 강력한 캐시기능을 자랑한다. 로컬 캐시, 클라우드 캐시 등 다양한 캐시 전략을 통해 빠른 빌드 속도를 토대로 배포시간 단축에 도움을 준다. 우리 팀 또한 편리하게 개발하고 있었는데 이상하게 예전 코드로 돌아가면 빌드시에 현재 코드로 적용되는 현상이 발생한 것이다.
캐시기능을 off하고 사용할 수 도 있었지만 그러기엔 Turborepo가 자랑하는 캐시를 꺼버리기엔 아까운 상황. 다행히 몇번의 삽질 끝에 이슈를 재현할 수 있었다. Next.js를 static으로 배포하는 상황에서 환경설정을 제대로 하지 않아서 발생했는데 다음과 같이 타임라인으로 설명해보려 한다.
이슈 타임라인
1. 최초의 빌드 파일 생성
최초로 빌드 파일을 생성. 당연히 기존에 일치하는 내용의 빌드 파일이 없어 cache miss, 4ebce3a3c4a19f81 해시에 새로운 캐시가 생성된다.
2. 코드를 변경하여 새로운 빌드 파일 생성
1번과 마찬가지로 기존에 일치하는 내용의 빌드 파일이 없어 cache miss, bb42bf9ab064e613라는 새로운 해시에 캐시가 생성된다.
3. 1번 코드로 원복하여 캐시 사용하여 빌드
1번의 코드로 원복하여 4ebce3a3c4a19f81 캐시를 활용하여 빠르게 빌드. cache가 hit되며 빌드 과정을 생략한다.
타임라인대로 1->2->3의 순서를 통해 2번의 코드를 1번으로 원복했지만 캐시가 적용되지 않는 현상이 나타났다.
공식문서를 다시 살펴보고 몇 번의 삽질을 해보 결과 이슈 원인을 파악할 수 있었다. 서비스 사정에 의해 Next.js를 정적으로 빌드해 배포하고 있었는데 Turborepo에 추가적인 셋팅을 해주지 않아 발생한 이슈였다. 미리 공식문서를 꼼꼼히 읽지 않은 부끄러운 실수였다.
이슈 해결을 서술하기 전에 Turborepo의 캐시 과정에 대해 간략히 서술해보고자 한다.
Turborepo의 캐시 과정 살펴보기
Missing Or Hitting the Caching
Turborepo가 작업 진행을 캐싱해 이미 계산된 내용은 건너 뛰는 것을 의미 한다. 빌드는 딱 한번만 하는 것을 목표로 하는데 캐싱된 값이 있을경우 Missing되어 새로운 해시에 캐시를 생성, 이미 캐싱된 결과가 있을경우 Hitting하여 빌드를 생략하고 이전 결과를 가져온다.
다음과 같이 순서대로 살펴본다면, 최초로 빌드를 실행할 경우
- Turborepo가 코드 작업물의 결과를 미리 hash에 적용한다 (e.g.78awdk123)
- local 파일 시스템에서 동일한 해시가 있는지 체크한다 (e.g../node_modules/.cache/turbo/78awdk123.tar.zst)
- 동일한 해시를찾지못하면 바로 빌드작업을 수행한다.
- 작업이 성공적으로 완료되면 Turborepo는 파일과 log를 비롯해 지정된 모든 결과물들을 캐시에 저장한다. (hash 78awdk123)
다음으로, 코드 변화없이 다시 빌드를 실행할 경우 (빌드 캐시 적용)
- 코드의 변화가 없으므로 빌드의 hash는 동일하다 (e.g. 78awdk123).
- Turborepo는 일치하는 hash에 존재하는 캐시를 탐색한다
- task(빌드)를 수행하는 대신에 Turborepo는 저장된 로그를 출력하고 동일한 결과물들을 반환한다
이슈 원인 및 해결
이슈의 원인은 간단하게 Turborepo의 셋팅에서 찾을 수 있었다. Turborepo 환경설정을 담당하는 turbo.json에는 build, dev, storybook 등 각각의 스크립트에 따라 Pipeline이 존재한다. build pipeline의 경우 캐시 적용 및 인식되는 outputs 옵션이 있는데, 해당 배열에 결과물의 경로를 지정하지 않았다.
현재 사내 프로젝트를 정적 빌드형식으로 배포하고 있어 빌드 결과물이 out폴더에 생성되는데 이 폴더의 경로를 빼먹은 것.
// outputs에 static build 결과물인 out을 지정하지 않아 발생한 이슈
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
//"outputs": [".next/**", "!.next/cache/**"]
"outputs": [".next/**", "!.next/cache/**", "out"]
},
"dev": {
"cache": false,
"persistent": true
},
"storybook": {
"cache": false
}
}
}
Next.js를 static 형식으로 export할 경우 out 폴더에 정적 결과물들이 생성이 되는데, 이 경로를 build pipeline의 outputs에 추가하지 않아 캐시가 적용되지 않는 이슈 및 실수였던 것이다. 아무리 동일한 코드 결과물의 캐시가 존재해도 out 폴더를 지정하지 않으니 당연히 캐시가 적용되지 않는것.
부끄럽게도 공식문서를 제대로 읽지 않아 발생한 이슈이며, 다시 한번 공식문서 정독의 필요성을 느끼게 되었다. 모든 정답은 공식 document에 존재한다고 했는데 맞는 말임을 오늘도 뼈저리게 느낀다.
그래도 Turborepo의 캐시과정을 한번 훓어보고 초기 셋팅설정 및 공식문서의 중요성을 느꼈으니 득 또한 있었다 생각한다.
'React' 카테고리의 다른 글
Micro Frontend를 위한 Module Federation (0) | 2024.06.10 |
---|---|
직장인들의 IT 개발모임 직띵(Zicdding) FE 스터디 발표 후기 (0) | 2024.05.30 |
모듈 번들러의 탄생과 Rollup.js 파헤치기 (0) | 2024.05.27 |
AWSKRUG 프론트엔드 1월 Meepup 후기 (Cognito + Next-Auth) (1) | 2024.01.16 |
[Storybook] Storybook MDX 마크다운으로 템플릿 작성하기 (0) | 2023.12.29 |