swc_core 업데이트 작업 후기

뭐 이런 걸 적냐고 생각할수도 있는데, 2주 이상의 시간을 잡아먹은 작업이라 적는다.

터보팩 PR: github.com/vercel/turbo/pull/4470 next.js PR: github.com/vercel/next.js/pull/48098

PR들의 히스토리를 보면 리베이스 + --force 푸시의 흔적이 가득하다.

시작은 vercel/turboswc_core 업데이트 PR을 날린 것이었다. 이때는 v0.74.0 버전의 swc_core를 사용했다. 컴파일 오류 고치고, 테스트 업데이트 한 다음에 PR을 보냈다. 그런데 터보팩에 PR을 보내려면 next.js 에도 PR을 보내야하는데 이를 잊어서 매니저가 대신 PR을 만들어주셨다.

next.js PR이 고생의 시작이었다. 노드 패키지인 @swc/helpers, @swc/core와 러스트 패키지인 swc_core을 모두 업데이트해야하는 상황이었기 때문이다. 사실 업데이트야 그냥 하면 되는데 CI가 깨지더라. 로컬에서 재현이 된다는 게 그나마 위안거리였고, 로컬 디버깅하면서 대부분의 이슈는 고쳤다. 근데 app dir + 동적 임포트 관련 테스트 하나가 실패하는데 원인을 알 수가 없었다.

export const NextDynamicNoSSRServerComponent = dynamic(
  () => import("../text-dynamic-no-ssr-server"),
  {
    ssr: false,
  }
);

문제가 되는 코드는 위의 코드였다. 이 테스트 디버깅을 저저번주 토요일, 즉 4월 9일에 시작했다. ssr: false,를 제거하면 잘 작동했다. 디버거 붙이고 ssr 프로퍼티랑 관련 있는 모든 코드에 하나씩 로그 추가해보면서 테스트 돌리는 작업을 미친듯이 반복했다.

Exception이 리액트쪽에서 나는 것이라서 리랙트 소스코드까지 뜯어봤다. 삽질을 하다보니 __next_f 라는 함수에 잘못된 값이 들어가있어서 리액트 서버 패키지에서 이상한 값을 뱉는 것이었다.

그런데 로그 찍다보니 생성된 파일이 좀 이상한 것 같아서 생성된 파일도 diff 해봤다.

#Diff

그러다가 발견한 점이, 생성된 client-reference-manifest.json 파일에서 저 테스트에 관련 있어보이는 몇가지 모듈이 사라졌다는 점이었다. 관련 스크린샷은 github.com/vercel/next.js/pull/48098#issuec.. 에 올려놨다. 이건 팀원들이 알 것 같아서 슬랙에 물어봤고, 알고보니 @swc/core 업데이트가 문제였다. 번들 크기를 줄이기 위해서 ESM 임포트가 common js 모듈로 컴파일되는 방법을 바꿨는데, next.js 소스코드 중에 컴파일된 common js 모듈을 분석하는 로직이 있었던 것이다. 이 이슈는 @shuding님이 분석 로직을 바꾸는 식으로 해결해주셨다.

저 이슈를 고친 뒤엔 pnpm이 속을 썩였다. 전역으로 설치된 pnpm이 8.x 버전대라서 npx pnpm@7 i를 썼다. 근데 자꾸 reactreact-dom 패키지가 2번씩 포함돼서 CI가 실패했다. pnpm 이슈 트래커에서 검색을 엄청 여러번 해봤는데 도움되는 댓글은 하나도 못 찾았다. 근데 엄청 오래 삽질하다가 혹시나해서 npx pnpm@7.24.3 i를 해보니까 되더라.

그런 뒤엔 리뷰 기다리면서 충돌 나면 리베이스했다. 그리고 오늘 승인을 받아서 vercel/turbo에 올린 PR을 머지했다. next.js CI 기다리면서 적은 글이라, 현재 시점에서 next.js에 보낸 PR은 아직 머지되지 않았다. 이 패치가 머지되고 새 버전이 배포되면 next.js의 Wasm 이슈가 해결될 것이다.