저번 달 작성한 토스ㅣSLASH 23 - 달리는 토스 앱에 React Native 엔진 더하기 글이 SEO의 선택을 받은 것일까 조회수가 꽤 잘 오르고 있다.
하지만 최근 인터뷰에서 해당 글과 관련한 질문에 대답이 미흡해서 아쉬웠다.
질문은 esbuild
와 관련된 내용이었고, 기존 metro
번들러와 차이점, 속도가 더 빠른 이유에 대해 물어봤었다.
esbuild
로 react-native 프로젝트를 빌드하는 것이 막연히 복잡하고 어려운 사항이라 생각해 디테일하게 공부하지 않은 점이 화근이었다.
간단히 esbuild
로 react-native 프로젝트를 빌드해주는 라이브러리가 존재한다.
사용법 또한 굉장히 간단해서 조금 당황하긴 했다.
물론 커스텀 옵션을 다루기 위해 어느정도 esbuild
사용법도 알아야한다.
그러던중 유일하게 열려있는 이슈 하나를 발견하고, 글을 쓰기 시작했다.
react-native 개발팀은 작년 7월에 Hermes
를 기본 엔진으로 사용할 것이라 공지했다.
Hermes
는 기존 JSC(JavacriptCore)
에 비해 월등히 나은 성능을 보여주고 있다.
하지만 해당 이슈에서 설명하듯이 react-native-esbuild
라이브러리와 Hermes
를 같이 사용해도 되지만 빌드 타임 성능에 문제가 생긴다.
Hermes
는 ES6 스펙인 let/const
를 차용하고 있으나, 실제 let/const
의 기능을 충실히 따르지 않는다.
마치 기존의 var
처럼 전역 혹은 함수 스코프를 지닌채 컴파일 되어 미묘한? 버그를 발생시키고 있다.
더욱 자세히는 TDZ(Temporal Dead Zone)
이라 불리는 선언 단계와 초기화 사이에 ReferenceError
가 발생하지 않고, 호이스팅 되는 불상사가 생긴다.
이렇게만 얘기하면 복잡한 JS 수업 같으니 예시를 살펴보자
Lacking support for ES6 block scoping #575
2021년에 열린 ES6 블록 스코핑의 지원이 안된다는 이슈다.
댓글의 내용처럼 Hermes
는 let/const
를 받아들이지만, 의미적으로 그들의 기능을 완전히 충족하진 못하고 있다.
https://hermesengine.dev/playground
function myFunction(arg){
switch(arg) {
case "1":{
function onClick(){
print("onClick 1")
}
onClick()
print("1")
break;
}
case "2":{
function onClick(){
print("onClick 2")
}
onClick()
print("2")
break;
}
}
}
myFunction("1");
예시처럼 해당 코드를 작성하고
직접 실행해보면 onClick 2
처럼 블록 스코핑이 제대로 구현되지 않아 오류가 발생하는 것을 확인할 수 있다.
I also talked to members of the metro team, but my impression is they are not really aware of the performance issues they are having as their primary reference is webpack, not esbuild/swc, and that some issues stem from watchman which is not in their scope/expertise. I think the fundamental issue is that the main author of hermes is no longer at meta, and that they don't see how it directly benefits their use case (to which I might object to as it should reduce bundle sizes and build times).
Metro
팀은 webpack
을 주로 참조하지 esbuild/swc
등을 참조하지 않는다.
그리고 watchman
에 의해서 생기는 이슈를 다루며 scope/expertise
등은 관심이 저조하다.
Hermes
를 만든 메인 개발자는 더이상 메타에서 일하지 않으며,
(번들 크기와, 빌드 타임을 줄이기 위해 그럴지도 모르지만) 이 사항이 직접적으로 사용 사례에 도움이 되는지 깨닫지 못하고 있다.
react-native-esbuild
메인테이너의 (울분과 절망이 담긴) 댓글을 보며 사태의 심각성을 알 수 있다.
그의 걱정처럼 Hermes
는 아직도 ES6 블록 스코프가 적용된 메이저 버전을 내놓지 못하고 있다.
metro-react-native-babel-preset
라이브러리를 사용하면 @babel/plugin-transform-block-scoping
플러그인을 사용할 수 있다.
하지만 esbuild
를 사용하는 이점이 사라지는 설정이긴 하다.