제 컴퓨터에서는 됐었는데 시연하려고 하니 안 되네요. 😭
"데모의 법칙"은 개발자들에게는 유명한 농담이자 현실이다. 운영 환경에서만 발생하는 버그, 또는 환경에 따라 달라져서 재현하기 어려운 버그는 참 우리를 환장하게 만들지만, 어느정도 규모 있는 프로덕을 운영하다 보면 또 의외로 자주 맞닥뜨리기도 한다.
최근 몇 개월간 캐시노트 프론트엔드 팀도 이런 문제를 3번이나 겪었다. 신기하게도 셋 모두 create-react-app 에서 CSS module을 사용하면서, 개발 환경에서는 경험하지 못했던 문제가 운영 환경에서 발견된 것이었다. 기존에는 이런 문제들도 원인을 파악해서 해결하고 나면 너무 자명하게 느껴저서 기록을 남기지 않는 경우가 많았다. 이제부터라도 '아 이거 겪어본 문젠데... 어떻게 풀었더라?' 를 피하기 위해, 문제 발견과 해결 과정을 의식적으로 기록하여 미래의 나에게 도움을 주고자 한다.
img
태그에 적용한 CSS 스타일이 문제의 원인임을 파악했다.merlin
저장소에서는 CSS module을 써서 React 컴포넌트를 스타일링한다. CSS module은 빌드 타임에 CSS 클래스명을 해시로 바꿔서, 해당 클래스명이 다른 클래스명과 충돌하지 않게 해준다. 예를 들어 뉴스Item.module.css
의 .thumbnailBox > img
는 이렇게 변환된다.img
태그 자체는 해싱이 될 수 없으므로(태그를 해싱해버리면 스타일링 대상을 어떻게 찾겠는가?) 스타일 정의가 그대로 남는다.merlin
은 모든 페이지 컴포넌트를 분할하여 지연 로드한다. module.css
파일도 페이지와 함께 번들링되어 있어서, 페이지가 로드될 때 CSS 스타일도 <head />
에 주입된다. 페이지 컴포넌트가 unmount되더라도 이미 주입된 스타일이 사라지는 건 아니므로, 다시 뉴스 페이지로 가보면 두 스타일이 다 적용되면서 height 40, width 400으로 일그러진 이미지가 보이게 된다.