구글이 리액트 네이티브 커뮤니티를 흔들기로 한 날

Mars Kim
Cross-Platform Korea
11 min readOct 27, 2019

원작자: Yamil García Hernández
원글 작성일: 2019/06/27
번역일: 2019/10/26

원글의 배너

이 글은 Yamil García HernándezThe day Google decided to shake the React Native Community를 번역한 글입니다.

구글은 안드로이드 버전을 올릴때마다 급진적이고도 갑작스러운 변화를 주는 것으로 잘 알려져 있는데요, 이것 때문에 여러분의 앱은 아무 변화도 주지 않았음에도 갑자기 어느날부터 동작하지 않을수도 있습니다.

이는 안드로이드 레포에서 maven 라이브러리의 deprecated되어서 삭제되어버린 버전 때문이거나 간접적으로 의존하고 있는 라이브러리들 중 (안드로이드) X 버전을 요구하는 라이브러리가 여러분의 앱에 import되어있는 다른 라이브러리와의 충돌에 의해서일수도 있습니다. 어찌되었든간에 이런 종류의 상황에 대처하는 것은 무척이나 성가신 일입니다. 예를 들어봅시다:

만약 여러분의 팀이 몇일동안 해온 버그 픽스와 새로운 기능을 포함한 릴리즈를 이번주에 기획했다고 가정해봅시다. 그런데 갑자기 프로젝트 빌드가 되지 않아서 그 원인 분석을 하는 시간과 함께, 이미 빌드가 됐었으면 진행할 수 있었던 앱을 테스트해볼 시간이 더 소비되는 상황이 옵니다.

어찌되었든, 이런 상황은 안드로이드 개발자라면 어쩔 수 없이 맞닥뜨리게 되는데, 결국 아무도 간접 의존 라이브러리들이나 외부 레포지토리의 변경사항을 완벽하게 컨트롤할 수는 없기 때문입니다.

이런 종류의 상황이 생기는 것을 해결하기 위해서는 보통 충돌이 난 라이브러리에 ([포크를 떠서 해결하든지 해서] 충돌현상을 해결해놓은 — 역주) 해당 라이브러리 레포를 주입시켜 놓던지 안드로이드 의존 라이브러리의 특정한 버전을 강제하여 직간접적인 라이브러리 충돌을 방지합니다.

이런 종류의 현상에 대한 조치는 그렇게 오래 걸리지는 않는 편인데, 이유인즉슨 보통 한개나 운이 없다면, 두개의 라이브러리에서 일어나는 문제기 때문입니다. 그러나 어느 날, 좀 다른 경우의 일이 터졌습니다.

2019년 6월 17일, 안드로이드가 그들의 새 패키지 이름들을 이미 DEPRECATED된 지원 라이브러리들과 다른 툴들을 AndroidX안으로 넣어서 릴리즈 해버린 것입니다. 그리고….

이 릴리즈의 결과로, 만약 여러분이 import android.support.annotation.*; 과 같은 형태로 라이브러리를 import 했다면, 이제부터는 import androidx.annotation.*와 같이 import 해야 한다는 뜻입니다. 패키지의 클래스가 이동되어져서 없어져 버렸으니까요.

여기에 새 패키지들의 모든 맵핑 정보가 있습니다:

아래는 영향받은 라이브러리들 리스트입니다:

이번 일로 구글이 안드로이드와 리액트 네이티브 커뮤니티에 제공했던 모든 기초 라이브러리들의 최신 버전이나 그에 근접한 버전들이 전부 영향을 받았습니다. 어떤 경우들은 리액트 네이티브 라이브러리 관리자들이 라이브러리 import시에 + 같은 심볼을 사용함으로써 릴리즈 되어 있는 라이브러리들 중 최신버전을 자동으로 사용하게끔 해 놓았기 때문이지만, 보통은 개발자들이 최신 릴리즈 버전의 새 기능들을 쓰고 있었기 때문입니다.

처음에 구글은 이런 현상이 일어날 것을 예측하고 Jetifier라는 툴을 릴리즈하기로 결정했습니다:

독립적인 툴인 Jetifier는 지원 라이브러리 의존적인 라이브러리들을 동 AndroidX 패키지를 대신 의존하도록 해 줍니다. 이 툴은 Android Studio 안에 있는 Android Gradle 플러그인을 사용하지 않고, 독립적인 라이브러리를 직접 바꿔줍니다.

이 툴은 여러분의 프로젝트와 모든 의존 라이브러리들이 네이티브인 경우에는 완벽하게 동작하겠지만, 리액트 네이티브 커뮤니티에서는 상황이 달랐습니다. 빌드 프로세스에 이 툴을 추가시켰을때 몇개의 직접 import된 네이티브 라이브러리에게만 정상적으로 작동했으며, 많은 양의 간접적인 의존 라이브러리들이나 직접 짠 코드들에도 적용되지 않았습니다.

이런 이유들로 결국에 리액트 네이티브 안드로이드 개발자로써 여러분은 몇 개의 옵션밖에 남지 않게 됩니다:

여러분의 의존 라이브러리들 중 많은 수가 아래의 결정에 따라 직접적인 영향을 받기 위해, 완전히 AndroidX를 쓰느냐 쓰지 않느냐의 경우만 가정하고, 그 사이의 경우는 없다고 가정합시다.

  • 여러분의 영향받은 리액트 네이티브 + 의존 라이브러리들의 버전이 포함된 프로젝트의 Gradle, 빌드 툴들, target SDK의 버전을 예전의 이 문제에 영향받지 않던 버전으로 다운그레이드 시킵니다.
  • 여러분의 모든 의존 라이브러리들이, 만약 프로젝트 내에 다른 의존 라이브러리가 AndroidX를 이미 지원하고 있는 경우, AndroidX를 중복해서 지원하지 않도록 하는 새 버전을 릴리즈할때까지 기다린다. 허나 이 옵션은, 만약 여러분의 프로젝트가 AndroidX로부터 무엇인가를 요구할 경우엔 무용지물이 되어 버립니다.
  • 여러분의 모든 의존 라이브러리들이 AndroidX를 지원하는 새 버전을 릴리즈할때까지 기다린다. 이것은 커뮤니티 내에서 관리하는 라이브러리들일 경우 오래 걸릴텐데, 어떤 프로젝트들은 실질적인 관리자가 없기 때문에 업데이트가 끊긴지 이미 오래일지도 모릅니다.
  • DIY: 여러분 스스로 가내수공업을 하는 방법. 여러분의 프로젝트에 최신 버전의 Gradle, 빌드 툴들, target SDK와 적절한 버전의 Jetifier를 여러분 프로젝트의 node_modules 디렉토리에 쓰는 것입니다. 아름답지 않은 부분이라면, 이것이 정공법이 아니기 때문에 여러분이 스크립트를 직접 짜는 시간이 드는 것과, 앱의 빌드를 돌릴 때마다 추가시간이 든다는 것입니다.

다운그레이드를 할 수 없고 여러분이 많은 의존 라이브러리들을 가지고 있는 경우에는 최선의 옵션은 결국 DIY가 될텐데, 이 경우 여러분의 Gradle 설정을 Google이 권장하는 버전으로 업데이트해야 합니다.

  • com.android.tools.build:gradle 을 v3.2.1이상으로 올리세요.
  • compileSdkVersion을 28이상으로 올리세요.
  • missingDimensionStrategy “RNN.reactNativeVersion”"reactNative57_5" 로 올리세요.

또한, 아래의 두가지 옵션을 여러분의 AndroidManifest.xmlapplication 태그에 넣어주세요.

  • android:appComponentFactory="androidx"
  • tools:replace="android:appComponentFactory"

그리고, 여러분의 gradle.properties 를 아래와 같이 고쳐주세요:

또한, 여러분의 gradle-wrapper.properties를 다음과 같이 고쳐주세요:

그리고 이제 아름답지 못한 부분, 스크립트 입니다:

Jetifier 툴을 쓰시는 걸 진심으로 권장드리구요, 이를 쓰시려면 다음과 같습니다:

  • npm install -g npx
  • npm install jetifier --saveyarn add jetifier

보통 여러분이 node_modules에 있는 의존 라이브러리들의 경로를 AndroidX로 마이그레이션 하실 때의 명령어는 npx jetify가 될 것입니다.

이제, scripts/fix-androidx.sh에 스크립트를 만들어 봅시다.

위 스크립트는 Jetifier툴을 실행시키고, Jetifier가 잡아내지 못한 라이브러리들의 경로를 정규식으로 바꿔줍니다. 제 경우에는 (react-native-navigation — 역주)이었는데요, 여러분의 경우에는 좀 다를지도 모릅니다. 그래도 몇개의 라이브러리에서 마이그레이션이 일어나지 않은 경우, 이 스크립트에 그 라이브러리들을 추가하시고, 여기 Google AndroidX에서 제공하는 것들로 바꿔주세요.

그리고 이 스크립트를 실행할 명령어를 package.json에 아래와 같이 추가해주세요.

"fix-androidx": ".scripts/fix-androidx"

이 명령어를 언제 실행시킬지는 여러분들의 자유지만, 저는 install이나 clean 명령이 실행된 직후를 추천합니다.

결론

이로써 여러분의 문제가 해결되서 앱의 빌드가 다시 돌아갈테지만, 알아두셔야 할 점은, 만일 여러분이 AndroidX를 쓰지 않기로 결정하셨다면, 여러분의 프로젝트 안의 의존 라이브러리들 중 하나나 네이티브 코드가 언젠가는 AndroidX를 요구할 것이고 그렇게 된다면 여러분은 AndroidX를 쓰게끔 앱을 강제로 업데이트할 수밖에 없어질 것입니다.

여러분이 위의 DIY옵션을 선택하신 경우에는, 언젠가는 여러분의 의존 라이브러리들을 AndroidX를 지원하는 버전으로 업데이트 해야 할 것 입니다. 이는 손이 많이 가는 작업일 수도 있으나, 빌드 타임을 많이 잡아먹는 Jetifier에 대한 의존도를 낮추기 위해서는 필요한 작업입니다.

어느 옵션을 선택하든, 이는 아직 완전히 해결된 문제가 아니며 리액트 네이티브 안드로이드 개발자로써 직면해야할 도전이 아직 많이 남아 있습니다. 이 문제를 해결하기 위해 몇날몇일동안 고생했지만, 많은 것을 배웠고, 희망을 갖고 밝은 미래를 보고 있습니다.

여러분은 어땠습니까? 이 AndroidX사태에 어떤 일이 여러분께 일어났으며 여러분은 어떻게 대처하셨습니까? 제가 위에 설명한 방법이 여러분의 문제를 해결해 주었습니까? 혹시 더 나은 방법을 알고 계신가요? 여러분의 코멘트를 기다립니다.

추천할만한 팀(원 저자의 팀 — 역주)

추천할 만한 리액트 네이티브 커뮤니티의 이슈 쓰레드 멘션들

--

--

Mars Kim
Cross-Platform Korea

react/react-native dev. chronic violin practice procrastinator.