Upgrade to Pro — share decks privately, control downloads, hide ads and more …

baseline으로 마이그레이션, 리팩토링 안전하게 맡기기

Avatar for Sungyong An Sungyong An
November 02, 2026

baseline으로 마이그레이션, 리팩토링 안전하게 맡기기

2026년 11월 2일 (월) 드로이드나이츠 2026 발표자료입니다.
"baseline으로 마이그레이션, 리팩토링 안전하게 맡기기"
https://www.droidknights.dev/

Avatar for Sungyong An

Sungyong An

November 02, 2026

More Decks by Sungyong An

Other Decks in Programming

Transcript

  1. 앱을 개발할 때 비즈니스 요구사항 플랫폼 요구사항 요구사항에 맞춰 내가

    직접 구현하는 코드 변경된 코드가 PR diff에 보여서 리뷰할 수 있다 매년 targetSdk에 맞춰 라이브러리를 올린다 비즈니스와 방향이 일치하지 않을 수 있다 기획, 디자인, 운영, 사업 같은 요구 리소스를 확보해 제때 Android, Google Play, Firebase 등 요구 에 대응해야 한다 3
  2. Target SDK 대응할 때 공식 문서 확인 동작 변경 확인

    targetSdk 올리기 새로운 Android 버전에 맞춰 androidx 올리기 appcompat 등 QA 동작 확인 보통 이런 흐름으로 확인하고 배포한다 4
  3. appcompat만 올렸을 뿐인데 gradle/libs.versions.toml - appcompat = "1.3.1" + appcompat

    = "1.4.0" ./gradlew :app:dependencies +--- androidx.appcompat:appcompat:1.4.0 | +--- androidx.core:core:1.7.0 | +--- androidx.emoji2:emoji2:1.0.0 | | +--- androidx.lifecycle:lifecycle-process:2.4.0 | | | \--- androidx.startup:startup-runtime:1.0.0 | | \--- androidx.core:core:1.3.0 -> 1.7.0 (*) | +--- androidx.emoji2:emoji2-views-helper:1.0.0 | \--- androidx.lifecycle:lifecycle-runtime:2.3.1 -> 2.4.0 (*) +--- androidx.core:core-ktx:1.6.0 | \--- androidx.core:core:1.6.0 -> 1.7.0 (*) 개발자가 인지하기 어려운 이 추가된다 5
  4. 검토해야 할 것들 appcompat 1.3.1 → 1.4.0 릴리스 노트를 읽었다.

    컴파일 통과. 화면도 확인했다 여기까지 보인다 emoji2 1.0.0 텍스트뷰가 EmojiCompat으로 이모지를 그린다 폰트를 받기 전엔 새로운 이모지가 ☐로 표시 startup-runtime 1.0.0 manifest에 InitializationProvider가 생겨, 앱 시작 때 초기화 코드를 자동 실행 검토해야 하지만, lifecycle-process 2.4.0 앱 시작 때부터 ProcessLifecycleOwner가 포그라운드, 백그라운드 전환을 추적 쉽다 6
  5. 문제는 늦게 드러난다 Develop 버전 한 줄 올림 Review 못

    보고 승인 QA 그대로 통과 Release 마켓 배포 사용자 Crash, 오동작 사용자에게 배포된 뒤에야 알게 된다 7
  6. 테스트로 회귀 검증하면 되지 않을까? 회귀 테스트는 알던 동작만 확인한다

    새로운 기능은 오류가 아니라서 통과한다 테스트를 추가해도 또 다른 기능이 들어온다 기존에 없던 기능이 갑자기 추가되는 변화는 으로 잡을 수 없다 8
  7. 사람이 검토를 더 꼼꼼히 한다? 업데이트할 때마다 생기는 문제가 아니다

    가끔, 길면 1년에 한 번일 수도 있다 시간이 지나면 잊혀 재발하기 쉽다 사람의 꼼꼼함에 기대는 것은 원인 찾기 확인 절차 만들기 재발 방지 ❌ 가 아니다 9
  8. 목차 마이그레이션 라이브러리 버전을 업데이트할 때 숨은 변경점을 노출하여 검토

    범위를 더 구체화한다 리팩토링 모듈을 분리하거나 모듈 간 코드를 이동할 때 규칙 위반사항을 노출하여 방지한다 13
  9. 01 마이그레이션 우리 코드는 최종적으로 라이브러리와 하나로 합쳐진다 ✦ 우리

    프로젝트 라이브러리 :app :feature :core appcompat emoji2 lifecycle APK와 AAB에는 APK / AAB 포함되는 것이 아니다 15
  10. 01 마이그레이션 - 의존성 버전 변경만으로 달라지는 것들 ✦ 의존성

    앱 동작이 달라질 수 있다 PR libs.versions.toml 버전을 올리면 숨은 의존성 변경이 있어도 인지할 수 없다 16
  11. 01 마이그레이션 - 의존성 의존성 트리로 비교하면 ✦ | -|

    -| -| +| +| +| | -| +| +--- androidx.activity:activity:1.2.4 | +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 | +--- androidx.core:core:1.1.0 -> 1.6.0 (*) | +--- androidx.lifecycle:lifecycle-runtime:2.3.1 (*) | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | +--- androidx.core:core:1.1.0 -> 1.7.0 (*) | +--- androidx.lifecycle:lifecycle-runtime:2.3.1 -> 2.4.0 (*) | +--- androidx.lifecycle:lifecycle-viewmodel:2.3.1 | | \--- androidx.annotation:annotation:1.1.0 -> 1.2.0 | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 여러 곳이 변경되어 보기 어렵고, 의존성 선언 위치만 달라져도 변경될 수 있다 17
  12. 01 마이그레이션 - 의존성 의존성 트리 대신 정제된 목록으로 ✦

    ./gradlew :app:dependencies +--- androidx.appcompat:appcompat:1.4.0 | +--- androidx.core:core:1.7.0 | +--- androidx.activity:activity:1.2.4 | | +--- androidx.core:core:1.1.0 -> 1.7.0 (*) | +--- androidx.fragment:fragment:1.3.6 | | +--- androidx.core:core:1.2.0 -> 1.7.0 (*) app/dependencies/releaseRuntimeClasspath.txt androidx.activity:activity:1.2.4 androidx.appcompat:appcompat:1.4.0 androidx.core:core:1.7.0 androidx.fragment:fragment:1.3.6 그래야 변경된 부분을 로 보기 쉽다 18
  13. 01 마이그레이션 - 의존성 dependency-guard 📚 ✦ appcompat 1.4.0 라이브러리마다

    한 줄 activity 1.2.4 fragment 1.3.6 중복은 하나로 1.1.0 1.2.0 이름순 정렬 core 1.7.0 라이브러리가 선언한 버전까지 포함해 https://github.com/dropbox/dependency-guard releaseRuntimeClasspath.txt androidx.activity:activity:1.2.4 androidx.appcompat:appcompat:1.4.0 androidx.core:core:1.7.0 androidx.fragment:fragment:1.3.6 현재 의존성 목록과 baseline 비교 이 baseline에 남는다 19
  14. 01 마이그레이션 - 의존성 dependency-guard 📚 ✦ app/build.gradle.kts plugins {

    id("com.dropbox.dependency-guard") version "0.5.0" } ./gradlew dependencyGuardBaseline dependencyGuard { configuration("releaseRuntimeClasspath") } ./gradlew dependencyGuard baseline을 업데이트한다 현재 의존성 목록과 baseline을 비교한다 비슷한 문제가 있었다면 사용을 고려해 보세요 https://github.com/dropbox/dependency-guard 20
  15. 01 마이그레이션 - 의존성 이제 appcompat 버전을 올리면 ✦ >

    Task :app:dependencyGuard FAILED Dependencies Changed in :app for configuration releaseRuntimeClasspath - androidx.appcompat:appcompat:1.3.1 + androidx.appcompat:appcompat:1.4.0 + androidx.emoji2:emoji2:1.0.0 If this is intentional, re-baseline using ./gradlew :app:dependencyGuardBaseline 의도한 변경 baseline을 업데이트하여 PR에 커밋한다 모르는 변경 어떤 라이브러리가 올렸는지 찾아 검토한다 baseline을 함께 업데이트해야 한다 21
  16. 01 마이그레이션 - 의존성 PR diff를 보면 ✦ gradle/libs.versions.toml -

    appcompat = "1.3.1" + appcompat = "1.4.0" app/dependencies/releaseRuntimeClasspath.txt -androidx.appcompat:appcompat:1.3.1 +androidx.appcompat:appcompat:1.4.0 -androidx.core:core:1.6.0 +androidx.core:core:1.7.0 +androidx.emoji2:emoji2:1.0.0 +androidx.lifecycle:lifecycle-process:2.4.0 +androidx.startup:startup-runtime:1.0.0 ✅ 버전 변경으로 달라진 의존성 목록이 모두 보인다 22
  17. 01 마이그레이션 버전 변경만으로 달라지는 것들 ✦ 의존성 버전을 올리면

    앱 동작이 달라질 수 있다 PR txt libs.versions.toml 의존성 txt 23
  18. 01 마이그레이션 - MANIFEST 버전 변경만으로 달라지는 것들 ✦ 버전을

    올리면 의존성 앱 동작이 달라질 수 있다 Manifest 권한 Play 심사, 설치할 수 있는 기기 exported 보안, 초기화 없이 열리는 진입점 PR txt libs.versions.toml 의존성 txt Merged Manifest가 변경되어도 인지할 수 없다 24
  19. 01 마이그레이션 - MANIFEST 변경된 권한은 앱을 등록할 때 뒤늦게

    알게 된다 ✦ Google Play 심사는 이 받는다 26
  20. 01 마이그레이션 - MANIFEST 민감한 권한이 추가되면 앱 심사에서 거부될

    수 있다 ✦ merged AndroidManifest.xml <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" android:required="true" /> 또는 uses-feature가 필수로 추가되면, 설치할 수 있는 기기가 줄어들 수 있다 27
  21. 01 마이그레이션 - MANIFEST 라이브러리에 exported 화면이 추가되면? ✦ 런처,

    딥링크 Intent 다른 앱에서 스플래시 앱 화면 라이브러리 화면 바로 열 수 있는 화면이 생긴다 28
  22. 01 마이그레이션 - MANIFEST 그게 WebView 화면이라면 앱 데이터가 노출될

    수 있다 ✦ 다른 앱이 보낸 file:// URL 파일 접근이 켜진 WebView라면 WebViewActivity SharedPreferences 도 노출될 수 있다 29
  23. 01 마이그레이션 - MANIFEST 이런 변경은 모두 Merged Manifest로 합쳐진다

    ✦ 앱, 모듈, 외부 AAR의 manifest AGP Manifest Merger merged AndroidManifest.xml merged AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.google.android.gms.permission.AD_ID" /> <activity android:name="com.example.cinema.MainActivity" android:exported="true" /> <activity android:name="com.google.android.gms.ads.AdActivity" android:exported="false" /> 다만 Merged Manifest는 빌드 산출물일 뿐, 30
  24. 01 마이그레이션 - MANIFEST Merged Manifest 대신 정제된 목록으로 ✦

    merged AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" /> <activity android:name="com.example.cinema.MainActivity" android:exported="true" /> <service android:name="com.example.cinema.SyncService" android:exported="false" /> 그래야 변경된 부분을 app/manifestShield/releaseAndroidManifest.txt uses-permission: android.permission.INTERNET activity: com.example.cinema.MainActivity (exported) 로 볼 수 있다 31
  25. 01 마이그레이션 - MANIFEST manifest-shield 📚 ✦ merged AndroidManifest.xml uses-permission

    activity (exported) service receiver (권한 보호) releaseAndroidManifest.txt 요소마다 한 줄 권한 없는 exported만 종류별로 정렬 uses-permission: android.permission.INTERNET activity: com.example.cinema.MainActivity (exported) 다시 합쳐 baseline과 비교 권한, exported 등 검출하고 싶은 부분만 baseline에 남긴다 https://github.com/fornewid/manifest-shield 32
  26. 01 마이그레이션 - MANIFEST manifest-shield 📚 ✦ 우리 앱의 Merged

    Manifest 중 baseline에 남는 비율 전부 적으면 골라 적으면 14% 100% 봐야 할 부분만 남겨 https://github.com/fornewid/manifest-shield 33
  27. 01 마이그레이션 - MANIFEST manifest-shield 📚 ✦ app/build.gradle.kts plugins {

    id("io.github.fornewid.manifest-shield") version "0.1.11" } ./gradlew manifestShieldBaseline manifestShield { configuration("release") } ./gradlew manifestShield baseline을 업데이트한다 다시 합쳐 baseline과 비교한다 필요한 baseline을 직접 만들 수 있다 https://github.com/fornewid/manifest-shield 34
  28. 01 마이그레이션 - MANIFEST 변경되면 diff로 드러난다 ✦ app/manifestShield/releaseAndroidManifest.txt +

    uses-feature: + android.hardware.camera (required) uses-permission: + android.permission.MANAGE_EXTERNAL_STORAGE activity: + com.example.cinema.WebViewActivity (exported) 의도한 변경 baseline을 업데이트하여 PR에 커밋한다 ✅ 리뷰어는 모르는 변경 어떤 라이브러리가 넣었는지 찾는다 을 보고 검토할 수 있다 35
  29. 01 마이그레이션 버전 변경만으로 달라지는 것들 ✦ 버전을 올리면 의존성

    앱 동작이 달라질 수 있다 Manifest 권한 Play 심사, 설치할 수 있는 기기 exported 보안, 초기화 없이 열리는 진입점 txt PR libs.versions.toml txt 의존성 txt Manifest txt 36
  30. 01 마이그레이션 - R8 규칙 버전 변경만으로 달라지는 것들 ✦

    버전을 올리면 의존성 앱 동작이 달라질 수 있다 Manifest 권한 Play 심사, 설치할 수 있는 기기 exported 보안, 초기화 없이 열리는 진입점 R8 규칙 최적화를 막고, 앱 크기를 늘릴 수 있다 txt PR libs.versions.toml txt 의존성 txt Manifest txt R8 규칙이 변경되어도 인지할 수 없다 37
  31. 01 마이그레이션 - R8 규칙 이런 R8 규칙이 추가되면 ✦

    # 넓은 keep -keep class com.google.gson.** { *; } -keep class * extends android.app.Activity # 전역 옵션 -dontshrink -dontoptimize 라이브러리에 든 -dontoptimize 같은 전역 옵션은 AGP 9부터 무시된다 최적화를 막아 가 늘어난다 38
  32. 01 마이그레이션 - R8 규칙 앱 크기를 비교하면 될까? ✦

    최적화하면 앱 크기가 줄어든다 앱 크기를 추적한다 release 빌드가 필요하다 매번 시간이 오래 걸린다 를 해야 한다 39
  33. 01 마이그레이션 - R8 규칙 Google Play의 최적화 비율을 보면

    ✦ release 빌드(App Bundle) r8.json Play Console 최적화 비율 최적화 비율도 https://developer.android.com/google/play/vitals/code-optimization BUNDLE-METADATA/com.android.tools/r8.json "stats": { "noObfuscationPercentage": ..., "noOptimizationPercentage": ..., "noShrinkingPercentage": ... } 해야 볼 수 있다 40
  34. 01 마이그레이션 - R8 규칙 앱 크기와 최적화 비율로는 부족하다

    ✦ 코드가 늘었다 R8 규칙이 추가됐다 느리다 원인을 모른다 release 빌드 앱 크기, 최적화 비율 빌드를 마쳐야 숫자가 나온다 그래서 숫자 대신, 어느 쪽 때문인지 알 수 없다 을 직접 보자 41
  35. 01 마이그레이션 - R8 규칙 R8 규칙도 baseline으로 드러낼 수

    있다 ✦ 앱의 규칙 파일 규칙마다 한 줄 AGP 기본 규칙 라이브러리 AAR 규칙, 클래스 패키지 releaseOptimizationBlockingRules.txt 최적화를 막는 것만 -keep interface androidx.webkit.ProfileStore { *; } -keep public class com.google.protobuf.** { *; } 이름순 정렬 현재 규칙 목록과 baseline 비교 컴파일 없이 규칙 파일만 읽어 https://github.com/fornewid/proguard-shield 을 적는다 42
  36. 01 마이그레이션 - R8 규칙 무엇을 baseline에 넣을까? ✦ ✅

    넣는다: 최적화를 막는 규칙 앱 규칙 파일의 전역 옵션 -dontoptimize 모든 클래스를 잡는 keep -keep class * { *; } 라이브러리가 외부 코드에 거는 keep ❌ 넣지 않는다 classpath에 없는 패키지를 가리키는 규칙 -keep class org.conscrypt.** { *; } 코드를 지우게만 하는 규칙 -assumenosideeffects class android.util.Log { *** d(...); } -keep public class com.google.protobuf.** { *; } 규칙만 넣는다 https://github.com/fornewid/proguard-shield 43
  37. 01 마이그레이션 - R8 규칙 예시로 AdMob 버전을 올리면 ✦

    gradle/libs.versions.toml app/proguardShield/releaseOptimizationBlockingRules.txt - playServicesAds = "23.6.0" + playServicesAds = "25.5.0" AdMob이 https://github.com/fornewid/proguard-shield + -keep interface androidx.webkit.ProfileStore { *; } + -keep interface androidx.webkit.ProfileStore$-CC { *; } 에 거는 keep이 잡힌다 44
  38. 01 마이그레이션 - R8 규칙 규칙마다 영향은 제각각이다 ✦ 앱

    크기가 늘어난 정도 AdMob이 넣은 keep Unity Ads가 넣은 keep 최적화 비율이 줄어든 정도 AdMob이 넣은 keep Unity Ads가 넣은 keep 거의 없음 변화 없음 잡힌 규칙만 앱 크기와 최적화 비율을 측정해 보고 판단한다 45
  39. 01 마이그레이션 버전 변경만으로 달라지는 것들 ✦ 버전을 올리면 의존성

    앱 동작이 달라질 수 있다 Manifest 권한 Play 심사, 설치할 수 있는 기기 exported 보안, 초기화 없이 열리는 진입점 txt R8 규칙 최적화를 막고, 앱 크기를 늘릴 수 있다 txt txt PR libs.versions.toml 의존성 txt Manifest txt R8 규칙 txt ✅ 3가지 변경사항이 모두 PR에서 보인다 46
  40. 01 마이그레이션 - 보너스 큰 리소스도 baseline으로 ✦ releaseLargeFiles.txt 앱

    모듈 res, assets, jni 라이브러리 AAR res, assets, jni 파일마다 크기 재기 100 KB 이상만 출처와 크기 적기 + jni/arm64-v8a/libface_detector_v2_jni.so: + - com.google.mlkit:face-detection:16.1.7 (8321 KB) + res/drawable-nodpi/onboarding_background.jpg: + - :app (150 KB) + res/drawable-nodpi/promo_banner.png: + - :app (172 KB) 현재 큰 리소스 목록과 baseline 비교 앱 크기를 측정하는 대신, 큰 https://github.com/fornewid/highlander 를 목록으로 노출하는 방법도 있다 47
  41. 01 마이그레이션 - AI 에이전트 버전 업데이트를 맡겼을 때 ✦

    AI 에이전트에게 한 줄로 요청 "androidx.appcompat을 최신 안정 버전으로 업데이트해줘" "AdMob SDK를 최신 버전으로 업데이트해줘" 버전만 올려도 변경된 의존성, Manifest, R8 규칙 가운데 AI 에이전트가 알려 준 비율 baseline 없음 baseline 있음 44% baseline이 있을 때는 AI 에이전트가 100% 알려 줬다 48
  42. 01 마이그레이션 - AI 에이전트 왜 차이가 났나? ✦ baseline

    없음 빌드 통과 릴리스 노트 확인 사람에게 알림 baseline 있음 baseline 검사 실패 AAR 안까지 조사 baseline 업데이트 후 알림 baseline이 AI 에이전트에게도 가 된다 49
  43. 01 마이그레이션 검사만 통과하려고 baseline을 업데이트하면? ✦ 사람, AI 에이전트

    baseline을 업데이트하여 커밋한다 PR diff 커밋 app/dependencies/releaseRuntimeClasspath.txt -androidx.appcompat:appcompat:1.3.1 +androidx.appcompat:appcompat:1.4.0 +androidx.emoji2:emoji2:1.0.0 검사만 CI baseline을 자동으로 커밋하지 않는다 PR 리뷰에서 확인할 수 있다 50
  44. 01 마이그레이션 baseline이 못 잡는 것 ✦ 구조적인 차이 의존성,

    권한, exported, R8 규칙, 큰 리소스 코드 안의 동작 이모지 그리는 방식 변경, 토스트 제거, 제스처 추가 txt 동작을 검증하는 도구는 아니다 51
  45. 01 마이그레이션 정리 ✦ 변경되면 문제가 되는 것을 고른다 프로젝트에서

    baseline을 추출한다 baseline과 다르면 검사가 실패한다 baseline 업데이트가 PR diff에 잡힌다 사람이 맡든 AI 에이전트가 맡든, 꼼꼼함의 52
  46. 02 리팩토링 우리 앱의 모듈 구조 ✦ APP :app FEATURE

    search api impl community api impl … DATA search api impl community api impl … CORE designsystem app 모듈에 있는 코드를 common … 하려고 한다 54
  47. 02 리팩토링 모듈화 규칙 ✦ (1) app만 impl 모듈을 참조할

    수 있다 impl 모듈이 변경되면 그 모듈만 다시 컴파일하면 된다 (2) 하위 계층은 상위 계층 모듈을 참조할 수 없다 app > feature > data > core (3) api 모듈에는 Hilt 컴파일러를 넣을 수 없다 api 모듈은 가볍게 유지해야 한다 모두 을 늘리지 않으려고 정한 규칙이다 55
  48. 02 리팩토링 AI 에이전트에게 모듈화를 맡기면 ✦ > app에 있는

    메인 화면 모듈로 분리해줘 규칙 없이 맡기면 팀에서 정한 구조를 깨뜨리기 쉽다 빌드 시간이 늘어나는 변경을 만들 수 있다 규칙을 위반했는지 규칙 문서가 있어도 AGENTS.md CLAUDE.md rules 확률적으로만 지킨다 이 필요하다 56
  49. 02 리팩토링 - 모듈 규칙 규칙 1: app만 impl 모듈을

    참조할 수 있다 ✦ APP :app FEATURE search api impl DATA search api impl ❌ module-rules.txt impl: :feature:search:impl -> :data:search:impl impl 모듈이 변경되면 그 모듈만 다시 컴파일하면 된다 58
  50. 02 리팩토링 - 모듈 규칙 규칙 2: 하위 계층은 상위

    계층 모듈을 참조할 수 없다 ✦ APP :app FEATURE search DATA search api impl api impl ❌ module-rules.txt layer: :data:search:api -> :feature:search:api data에 의존하는 모듈이 feature 모듈 컴파일을 기다리지 않아도 된다 59
  51. 02 리팩토링 - 모듈 규칙 규칙 3: api 모듈에는 Hilt

    컴파일러를 넣을 수 없다 ✦ APP :app Hilt FEATURE search api impl Hilt DATA search api Hilt impl Hilt module-rules.txt hilt: :data:search:api api 모듈에 의존하는 모듈이 Hilt 코드 생성을 기다리지 않아도 된다 60
  52. 02 리팩토링 - 모듈 규칙 규칙 위반사항을 baseline으로 ✦ 선언한

    모듈 의존성 적용한 플러그인 Hilt 규칙 1~3으로 판정 impl, layer, hilt 위반사항마다 한 줄 module-rules.txt hilt: :data:search:api impl: :feature:search:impl -> :data:search:impl layer: :data:search:api -> :feature:search:api 이름순 정렬 의존성과 플러그인을 규칙으로 판정해 https://github.com/Moop-App/Moop-Android/pull/340 현재 위반사항 목록과 baseline 비교 적는다 61
  53. 02 리팩토링 - 모듈 규칙 규칙을 위반하면 ✦ FEATURE :feature:community:impl

    :feature:community:api + layer 위반사항 DATA :data:community:api :data:community:impl Module rules changed in module-rules.txt: + layer: :data:community:impl -> :feature:community:api If this is intended, re-baseline with ./gradlew moduleRulesBaseline 검사가 실패하고, 이 표시된다 62
  54. 02 리팩토링 - 모듈 규칙 당장 고치기 어렵다면 baseline에 추가한다

    ✦ module-rules.txt hilt: :data:search:api impl: :feature:search:impl -> :data:search:impl + layer: :data:community:impl -> :feature:community:api layer: :data:search:api -> :feature:search:api 나중에 고치면 그 줄이 빠진다 - layer: :data:community:impl -> :feature:community:api baseline이 앞으로 고칠 https://github.com/Moop-App/Moop-Android/pull/341 이 된다 63
  55. 02 리팩토링 - 모듈 크기 규칙을 지켜도 큰 모듈이 있으면

    빌드가 느려진다 ✦ CORE DATA FEATURE 큰 모듈 마지막 단계 기다리는 시간 APP 그래서 규칙과 함께 마지막 단계 시간 도 본다 65
  56. 02 리팩토링 - 모듈 크기 큰 모듈도 baseline으로 ✦ 파일

    N개 이상만 적는다 :feature:search:impl (30) :data:search:impl (17) :core:designsystem (10) :core:common (6) Module sizes grew beyond the baseline: module-sizes.txt + :feature:search:impl (31) grew from 30 Split the module, or if it is meant to grow, re-baseline with: ./gradlew moduleSizesBaseline 규칙과 모듈 크기를 함께 검사해 이 늘어나는 변경을 막는다 66
  57. 02 리팩토링 정리 ✦ 구조에 맞는 규칙을 정한다 위반사항과 큰

    모듈을 baseline으로 추출한다 사람이 맡든 AI 에이전트가 맡든, baseline과 다르면 검사가 실패한다 당장 고치기 어렵다면 baseline에 추가한다 으로 검사한다 67
  58. Summary 마무리 ✦ 1부 버전을 올리면 의존성 Manifest R8 규칙

    2부 모듈을 옮기면 모듈 규칙 모듈 크기 사람 뽑는다 baseline 보여 준다 다르면 검사에서 막는다 코드만으로 알 수 없는 변화를 PR 리뷰에서 변경된 줄을 본다 AI 에이전트 검사 실패로 변경된 것을 안다 으로 확인할 수 있다 68
  59. 감사합니다 ✦ T h a n k Yo u 자신만의

    baseline을 만들어 보세요