React Native 0.79 and Expo 53
- REACT & NODE
- 2025. 7. 2.
https://reactnative.dev/blog/2025/04/08/react-native-0.79
https://react-native-community.github.io/upgrade-helper/?from=0.77.0&to=0.79.5
https://expo.dev/changelog/sdk-53
- 앱 업데이트를 출시할 수 없게 됩니다(60일 남음).
2025년 8월 31일부터 최신 Android 출시로부터 1년 이내의 대상 API 수준을 타겟팅하지 않는 경우 앱을 업데이트할 수 없습니다.
React Native 0.79 - Faster tooling and much more
React Native 0.79 - 더 빠른 툴링과 더 많은 기능들
오늘 React Native 0.79를 출시하게 되어 기쁩니다! 이번 릴리스는 다양한 측면에서 성능 개선과 여러 버그 수정을 제공합니다. 우선, Metro는 지연 해싱 덕분에 시작 속도가 빨라졌으며, 패키지 익스포트에 대한 안정적인 지원을 제공합니다. Android에서도 JS 번들 압축 변경 등으로 인해 앱 시작 시간이 개선됩니다.
주요 특징
- 새로운 Metro 기능
- JSC의 커뮤니티 패키지로 이전
- iOS: Swift 호환 네이티브 모듈 등록
- Android: 더 빠른 앱 시작
- 원격 JS 디버깅 제거
주요 특징 Metro: 더 빠른 시작과 패키지 익스포트 지원 이번 릴리스는 Metro 0.82와 함께 제공됩니다. 이 버전은 지연 해싱을 사용하여 첫 번째 yarn start의 속도를 일반적으로 3배 이상 향상시켜 (대규모 프로젝트와 모노레포에서는 더욱) 일상적인 개발 경험과 CI 빌드를 더 빠르게 만듭니다.
또한 Metro 0.82에서는 package.json의 "exports"와 "imports" 필드 해석을 안정 버전으로 승격시킵니다. "exports" 해석은 React Native 0.72에서 도입되었고, "imports" 지원은 커뮤니티 기여로 추가되었습니다 - 이 둘 모두 이제 React Native 0.79의 모든 프로젝트에서 기본적으로 활성화됩니다.
이는 최신 npm 종속성과의 호환성을 개선하고, 프로젝트를 구성하는 새롭고 표준 준수적인 방법들을 제공합니다.
주요 변경사항 커뮤니티에서 package.json "exports"를 한동안 테스트해왔지만, 이번 전환은 특정 패키지와 프로젝트 설정에서 주요 변경사항이 될 수 있습니다.
특히, Firebase와 AWS Amplify를 포함한 일부 인기 패키지들에 대한 사용자 보고 비호환성을 인지하고 있으며, 이를 근본적으로 해결하기 위해 노력하고 있습니다.
문제가 발생하는 경우:
- Metro 0.81.5 핫픽스로 업데이트하거나, resolver.unstable_enablePackageExports = false를 설정하여 옵트아웃하세요.
- 영향받는 패키지와 향후 업데이트에 대해서는 expo/expo#36551을 참조하세요.
JSC의 커뮤니티 패키지로 이전 React Native의 API 표면을 줄이려는 노력의 일환으로, JavaScriptCore (JSC) 엔진을 커뮤니티에서 유지 관리하는 패키지인 @react-native-community/javascriptcore로 이전하는 과정에 있습니다.
이 변경사항은 Hermes를 사용하는 사용자들에게는 영향을 주지 않습니다.
React Native 0.79부터, readme의 설치 지침을 따라 커뮤니티에서 지원하는 JSC 버전을 사용할 수 있습니다. React Native 코어에서 제공하는 JSC 버전은 0.79에서 여전히 사용 가능하지만, 가까운 미래에 제거할 계획입니다.
JSC를 커뮤니티에서 유지 관리하는 패키지로 이전하면 JSC 버전을 더 자주 업데이트할 수 있고 최신 기능을 제공할 수 있습니다. 커뮤니티에서 유지 관리하는 JSC는 React Native와 별도의 릴리스 일정을 따를 것입니다.
iOS: Swift 호환 네이티브 모듈 등록 이번 릴리스에서는 네이티브 모듈을 React Native 런타임에 등록하는 방식을 개선하고 있습니다. 새로운 접근 방식은 공식 문서에 설명된 컴포넌트와 동일한 방식을 따릅니다.
이 버전의 React Native부터 package.json 파일을 수정하여 모듈을 등록할 수 있습니다. ios 속성에 새로운 modulesProvider 필드를 도입했습니다:
"codegenConfig": {
"ios": {
+ "modulesProvider": {
+ "JS Name for the module": "ObjC Module provider for the pure C++ TM or a class conforming to RCTTurboModule"
+ }
}
}
Codegen이 package.json 파일에서 시작하여 모든 관련 코드를 생성하도록 처리할 것입니다.
순수 C++ 네이티브 모듈을 사용하는 경우 다음과 같은 권장 구성을 따라야 합니다: 앱에서 순수 C++ 네이티브 모듈 구성
이 새로운 접근 방식을 통해 앱 개발자와 라이브러리 유지 관리자 모두를 위한 네이티브 모듈 등록을 통합했습니다. 라이브러리는 package.json에서 동일한 속성을 지정할 수 있으며 Codegen이 나머지를 처리합니다.
이 접근 방식은 Swift AppDelegate를 사용한 순수 C++ 네이티브 모듈 등록을 방해했던 0.77에서 도입된 제한 사항을 해결합니다. 보시다시피, 이러한 변경 사항 중 어느 것도 AppDelegate를 수정하지 않으며, 생성된 코드는 Swift와 Objective-C 모두로 구현된 AppDelegate에서 작동합니다.
Android: 더 빠른 앱 시작 또한 Android 시작 시간을 상당히 개선하는 변경 사항을 제공합니다.
이 버전부터 APK 내부에서 JavaScript 번들을 더 이상 압축하지 않습니다. 이전에는 Android 시스템이 앱을 시작하기 전에 JavaScript 번들의 압축을 해제해야 했습니다. 이로 인해 앱 시작 중에 상당한 속도 저하가 발생했습니다.
이번 릴리스부터 JavaScript 번들을 기본적으로 압축하지 않은 상태로 제공하므로 Android 앱이 일반적으로 더 빠르게 시작됩니다.
Margelo 팀이 Discord 앱에서 이 기능을 테스트한 결과 상당한 성능 향상을 얻었습니다: Discord의 상호작용 시간(TTI)이 400ms 단축되었으며, 이는 한 줄 변경으로 12% 속도 향상을 의미합니다(Samsung A14에서 테스트).
반면 번들을 압축하지 않고 저장하면 사용자 기기에서 애플리케이션의 공간 소비가 증가합니다. 이것이 우려되는 경우 app/build.gradle 파일의 enableBundleCompression 속성을 사용하여 이 동작을 전환할 수 있습니다.
app/build.gradle
react {
// ...
// JS 번들을 압축하려는 경우 (느린 시작, 적은 공간 소비)
enableBundleCompression = true
// JS 번들을 압축하지 않으려는 경우 (빠른 시작, 높은 공간 소비)
enableBundleCompression = false
// 기본값은 `false`
}
이번 릴리스에서 APK 크기가 증가하지만, APK가 네트워크에서 다운로드될 때 압축되므로 사용자가 APK 다운로드 크기에서 추가 비용을 지불하지 않습니다.
주요 변경사항 원격 JS 디버깅 제거 디버깅 개선을 위한 지속적인 노력의 일환으로, Chrome을 통한 원격 JS 디버깅을 제거합니다. 이 레거시 디버깅 방법은 React Native 0.73에서 deprecated되었고 런타임 옵트인으로 이동되었습니다. 현대적이고 안정적인 디버깅을 위해 React Native DevTools를 사용하세요.
이는 또한 React Native가 더 이상 react-native-debugger 커뮤니티 프로젝트와 호환되지 않음을 의미합니다. Redux DevTools와 같은 타사 디버깅 확장을 사용하고자 하는 개발자들에게는 Expo DevTools Plugins를 권장하거나, 이러한 도구들의 독립 실행형 버전을 통합할 것을 권장합니다.
자세한 내용은 이 전용 포스트에서 읽어보세요.
내부 모듈이 export 구문으로 업데이트됨 JavaScript 코드베이스를 현대화하는 일환으로, react-native 내의 여러 구현 모듈을 module.exports 대신 export 구문을 일관되게 사용하도록 업데이트했습니다.
총 46개의 API를 업데이트했으며, 이는 변경 로그에서 확인할 수 있습니다.
이 변경사항은 기존 import에 미묘한 영향을 미칩니다:
케이스 1: 기본 export
// 변경됨 - require() 구문
- const ImageBackground = require('react-native/Libraries/Image/ImageBackground');
+ const ImageBackground = require('react-native/Libraries/Image/ImageBackground').default;
// 변경되지 않음 - import 구문
import ImageBackground from 'react-native/Libraries/Image/ImageBackground';
// 권장 - 루트 import
import {ImageBackground} from 'react-native';
케이스 2: 보조 exports 이 패턴의 경우는 매우 적으며, 루트 'react-native' import를 사용할 때는 영향을 받지 않습니다.
// 변경되지 않음 - require() 구문
const BlobRegistry = require('react-native/Libraries/Blob/BlobRegistry');
// 변경되지 않음 - 구조 분해와 함께 require() 구문
const {register, unregister} = require('react-native/Libraries/Blob/BlobRegistry');
// 변경됨 - 단일 객체로 import 구문
- import BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
+ import * as BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
// 변경되지 않음 - 구조 분해와 함께 import 구문
import {register, unregister} from 'react-native/Libraries/Blob/BlobRegistry';
// 권장 - 루트 import
import {BlobRegistry} from 'react-native';
이 변경사항의 영향은 매우 제한적일 것으로 예상되며, 특히 TypeScript로 작성되고 import 구문을 사용하는 프로젝트의 경우 더욱 그렇습니다. 코드를 업데이트하기 위해 타입 오류를 확인하세요.
팁 루트 react-native import를 강력히 권장합니다
일반적인 결론으로, 향후 불필요한 주요 변경사항을 피하기 위해 루트 'react-native' 경로에서 import하는 것을 강력히 권장합니다. 다음 릴리스에서는 React Native의 공개 JavaScript API를 더 잘 정의하는 일환으로 깊은 import를 deprecated할 예정입니다(RFC 참조).
기타 주요 변경사항 이 목록에는 제품 코드에 경미한 영향을 미칠 수 있고 주목할 만한 기타 주요 변경사항들이 포함되어 있습니다.
박스 섀도우와 필터에서 단위 없는 길이가 유효하지 않음: React Native를 CSS/Web 사양에 더 준수하도록 만들기 위해, 이제 box-shadow와 filter에서 단위 없는 길이를 더 이상 지원하지 않습니다. 즉, 1 1 black의 box-shadow를 사용하고 있었다면 더 이상 렌더링되지 않습니다. 대신 1px 1px black과 같이 단위를 지정해야 합니다.
normalize-color에서 잘못된 hwb() 구문 지원 제거: React Native를 CSS/Web 사양에 더 준수하도록 만들기 위해, 이제 hwb()에 대한 일부 유효하지 않은 구문을 제한합니다. 역사적으로 React Native는 쉼표로 구분된 값(예: hwb(0, 0%, 100%))을 지원했지만 이제 더 이상 지원하지 않습니다(hwb(0 0% 100%)로 마이그레이션해야 함). 이 변경사항에 대한 자세한 내용은 여기에서 읽을 수 있습니다.
Libraries/Core/ExceptionsManager exports 업데이트 React Native JS API를 현대화하려는 노력의 일환으로, ExceptionsManager를 업데이트하여 이제 기본 ExceptionsManager 객체를 export하고 SyntheticError를 보조 export로 제공합니다.
감사의 말 React Native 0.79에는 100명의 기여자로부터 944개 이상의 커밋이 포함되어 있습니다. 모든 노고에 감사드립니다!
이번 릴리스에서 중요한 기여를 한 커뮤니티 멤버들에게 감사를 전하고 싶습니다:
Marc Rousavy - "Android: 더 빠른 앱 시작" 기능 개발 및 문서화 Kudo Chien과 Oskar Kwaśniewski - @react-native-community/javascriptcore 패키지 작업 및 "JSC의 커뮤니티 패키지로 이전" 섹션 작성 James Lawson - Metro에서 import 하위 경로 해석 지원 추가
또한 이번 릴리스 포스트의 기능 문서화 작업을 한 추가 작성자들에게도 감사를 전합니다:
Rob Hogan - "새로운 Metro 기능" 섹션 Alex Hunt - "원격 JS 디버깅 제거" 및 "내부 모듈이 export 구문으로 업데이트됨" 섹션 Riccardo Cipolleschi - iOS 네이티브 모듈 등록 작업
0.79로 업그레이드 기존 프로젝트의 경우 업그레이드 문서와 함께 React Native Upgrade Helper를 사용하여 React Native 버전 간의 코드 변경사항을 확인하세요.
새 프로젝트를 생성하려면:
npx @react-native-community/cli@latest init MyProject --version latest
Expo를 사용하는 경우, React Native 0.79는 곧 출시될 Expo SDK 53에서 React Native의 기본 버전으로 지원될 예정입니다.
정보 0.79는 이제 React Native의 최신 안정 버전이며 0.76.x는 지원되지 않는 버전으로 이동합니다. 자세한 정보는 React Native의 지원 정책을 참조하세요. 가까운 미래에 0.76의 최종 수명 종료 업데이트를 게시할 예정입니다.
Expo SDK 53
오늘 Expo SDK 53의 출시를 발표합니다. SDK 53에는 React Native 0.79가 포함되어 있습니다. 베타 테스트에 도움을 주신 모든 분들께 감사드립니다.
새로운 아키텍처가 이제 모든 곳에서 기본값입니다 SDK 53에서는 모든 프로젝트에서 새로운 아키텍처가 기본적으로 활성화됩니다. 아직 도입할 준비가 되지 않았다면 옵트아웃할 수 있습니다. 이제 새로운 아키텍처로 마이그레이션하는 것이 대부분의 프로젝트에게 올바른 선택이라고 확신합니다. 이 글을 작성하는 시점에서, 2025년 4월 EAS Build에서 빌드된 SDK 52 프로젝트의 74.6%에서 새로운 아키텍처가 활성화되었습니다.
- 타사 라이브러리의 알려진 문제를 포함하여 새로운 아키텍처로 마이그레이션하는 방법을 알아보세요.
- 옵트아웃하는 방법을 알아보세요 — 이는 SDK 53으로 업그레이드하고 새로운 아키텍처를 별도 단계로 활성화하는 데 유용할 수 있습니다.
- 새로운 아키텍처로 마이그레이션하는 것을 막는 문제가 있다면, expo/expo에 이슈를 생성하고 문제가 해결될 때까지 옵트아웃하세요.
새로운 Android 프로젝트에서 기본적으로 edge-to-edge 배포
@zoontek과 함께 react-native-edge-to-edge 라이브러리 출시를 도왔습니다. 이 라이브러리는 "React Native에서 edge-to-edge 디스플레이를 손쉽게 활성화하여, Android 앱 콘텐츠가 시스템 바 아래로 매끄럽게 흐르도록 해줍니다." Google이 Android 16(6월 출시 예정)에서 edge-to-edge를 옵트아웃하는 것이 더 이상 불가능할 것이라고 발표했기 때문에 이는 점점 더 중요해지고 있습니다.
*Android 15는 Android 15(API 레벨 35)를 타겟하는 앱에 대해 edge-to-edge를 강제했지만, 앱은 R.attr#windowOptOutEdgeToEdgeEnforcement를 true로 설정하여 옵트아웃할 수 있었습니다. Android 16(API 레벨 36)을 타겟하는 앱의 경우, R.attr#windowOptOutEdgeToEdgeEnforcement는 deprecated되고 비활성화되며, 앱은 edge-to-edge를 옵트아웃할 수 없습니다.
SDK 53에서 Android의 edge-to-edge는 이제:
- Expo Go 앱에서 기본적으로 활성화되며, 옵트아웃이 없습니다.
- 모든 새 프로젝트에서 기본적으로 활성화되며, Expo Go 외부에서는 옵트아웃이 가능합니다.
- Expo Go 외부의 모든 기존 프로젝트에서 기본적으로 비활성화되며, 옵트인이 가능하고 권장됩니다.
미래를 보면, SDK 54에서는 edge-to-edge가 새 프로젝트와 기존 프로젝트 모두에 대한 기본값이 될 것입니다. edge-to-edge와 Expo에 대해 자세히 알아보세요.
향상된 백그라운드 작업
새로운 모듈인 expo-background-task는 Android와 iOS에서 최신 API를 사용하며, 이제 deprecated된 플랫폼 API를 기반으로 했던 expo-background-fetch 모듈을 deprecated시킵니다. 새 패키지는 최종 사용자 기기의 전력 사용량을 최적화하는 방식으로 백그라운드에서 연기 가능한 작업을 실행하는 것을 지원합니다. Expo Background Task는 Android에서 WorkManager API를, iOS에서 BGTaskScheduler API를 사용합니다.
이 패키지를 사용하면 앱이 백그라운드에 있을 때 작업을 실행하고 데이터 다운로드, 새 버전을 확인하고 다운로드하기 위한 Expo Updates 실행(이것을 해야 합니다!), 또는 데이터베이스 정리나 로컬 데이터를 정기적으로 업로드하는 것과 같은 일상적인 작업 수행과 같은 작업을 수행할 수 있습니다.
import * as TaskManager from 'expo-task-manager';
import * as BackgroundTask from 'expo-background-task';
import * as Updates from 'expo-updates';
const BACKGROUND_TASK_NAME = 'task-run-expo-update';
TaskManager.defineTask(BACKGROUND_TASK_NAME, async () => {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
await Updates.fetchUpdateAsync();
// You may not want to reload the app while it is backgrounded, this
// will impact the user experience if your app state isn't saved
// and restored.
await Updates.reloadAsync();
}
});
async function registerTask() {
const isRegistered = TaskManager.isTaskRegisteredAsync(BACKGROUND_TASK_NAME);
if (!isRegistered) {
await BackgroundTask.registerTaskAsync(BACKGROUND_TASK_NAME, {
minimumInterval: 30, // Try to repeat every 30 minutes while backgrounded
});
}
}
registerTask();
package.json exports 필드가 이제 Metro 번들러에서 기본적으로 활성화됨 React Native 0.79에서 Metro 팀은 package.json exports 필드 지원을 기본적으로 활성화로 전환했습니다 — 이는 React Native 0.72에서 처음 사용 가능했습니다. 관련 문제가 발생하면 앱에서 unstable_enablePackageExports: false를 지정하여 이를 옵트아웃할 수 있습니다. Metro의 ES 모듈 해석에 대해 자세히 알아보세요.
의존하는 라이브러리가 이 변경사항과 호환되지 않는 경우, 매우 명백할 수 있지만("... attempted to import the Node standard library module ..."과 같은 오류를 볼 수 있음) 앱에서 미묘한 방식으로 나타날 수도 있습니다. 어떤 라이브러리가 영향을 받고 이를 수정하기 위해 노력하는지 커뮤니티가 알 수 있도록 알려진 라이브러리를 이 토론에 보고하시기 바랍니다.
예를 들어, 가능한 문제 중 하나는 dual package hazard로 알려진 것에 의해 발생합니다 — 앱이 라이브러리의 ESM과 CommonJS 버전을 모두 가져오게 될 수 있으며, 해당 라이브러리가 상태를 가지고 있다면 로드될 때 서로 다른 상태를 가진 두 개의 독립적인 복사본을 갖게 됩니다. 라이브러리 작성자이고 react-native-builder-bob을 사용한다면, 이 변경사항에 적응하기 위한 그들의 가이드를 따르는 것을 권장합니다.
앱이 이 특정 문제의 영향을 받는지, 그리고 일반적으로 번들링 관련 문제의 모든 클래스를 조사하는 좋은 방법은 Expo Atlas로 번들을 분석하는 것입니다. 다음 스크린샷에서는 @react-navigation 패키지의 commonjs와 module 복사본이 있습니다(특정 문제는 이미 해결되었으며, 여기서는 단지 시연 목적으로만 포함되었습니다).
주요 특징
- React 19와 React Native Web 0.20.0을 포함한 React Native 0.79. 자세한 정보는 React Native 0.79 릴리스 노트와 React 19 릴리스 노트를 참조하세요. React 19에는 로딩 상태를 위한 Suspense와 컨텍스트 및 프로미스를 위한 use와 같은 훌륭한 기능들이 있으므로 꼭 읽어보세요! 또한 React Native 버전 추적을 위한 Expo SDK 정책에 대해 자세히 알아보세요.
- 개발 빌드를 이제 TestFlight에 배포할 수 있습니다. facebook/react-native#49154에서 더 많은 정보를 확인할 수 있습니다. 이는 개발 빌드를 배포하기 위해 모든 기기를 UDID로 등록해야 하는 ad hoc 배포를 사용하는 것의 좋은 대안이 될 수 있습니다. EAS를 사용한다면 새로운 npx testflight 패키지로 시도해보세요 — development 프로필에서 "distribution": "store"를 설정하고 eas.json에서 submit 프로필로 "development": {}를 추가한 다음 npx testflight --profile development를 실행하세요.
- 새로운 expo-audio 라이브러리의 안정 릴리스. SDK 52에서 expo-audio의 베타를 출시했고 많은 훌륭한 피드백을 받았습니다. 지난 SDK 사이클 동안 해당 피드백을 통합하고 라이브러리에 다른 개선사항들을 만들었으며, 이제 안정적이라고 부를 준비가 되었습니다! 이제 expo-av에서 마이그레이션하는 것을 권장합니다. expo-av의 Audio 컴포넌트보다 더 안정적이고, 사용하기 쉽고, 성능이 뛰어나며, 더 강력합니다. expo-audio에 대해 자세히 알아보세요.
- 새로운 expo-maps 패키지 알파 릴리스. 이 라이브러리는 맵을 위한 플랫폼 표준 API — Android의 Google Maps와 iOS의 Apple Maps에 대한 래퍼를 제공하는 것을 목표로 합니다. 각 컴포넌트에 대해 최신 Jetpack Compose와 Swift UI API 위에 구축되었습니다. 라이브러리를 사용하는 데 필요한 최소 iOS 버전이 현재 iOS 17이라는 점을 명심하세요. Swift UI API의 제한으로 인해 iOS 17보다 오래된 버전에 대한 지원은 가능하지 않을 것 같습니다. 또한 이 라이브러리에서 iOS의 Google Maps를 지원할 의도는 없습니다. Camera, Video, Audio 라이브러리와 마찬가지로 대부분의 앱이 필요로 하는 가장 일반적인 사용 사례에 안정적이고 일관되며 신뢰할 수 있는 인터페이스를 제공한다는 우리의 철학으로 구축될 것이기 때문에 expo-maps에 대해 기대하고 있습니다. 생태계의 다른 맵 라이브러리들은 더 적은 수의 앱 개발자들이 필요로 할 수 있는 더 구체적이고 일반적이지 않은 사용 사례를 채우는 데 집중할 수 있습니다. 자세히 알아보기.
- 사전 빌드된 Expo 모듈로 Android 빌드 시간 개선. 빌드 시간은 일상적인 개발에 상당한 영향을 미칩니다. 최근에 하드웨어 업그레이드로 iOS 빌드 시간을 개선했다고 발표했습니다 — 이제 Android 차례입니다. 이 SDK에서 Android용 Expo 모듈 중 일부를 사전 컴파일함으로써 로컬에서 최대 25%의 빌드 시간 단축을 경험할 수 있습니다(하드웨어에 따라 다름). EAS에서의 개선사항은 현재 더 작지만, EAS에 대한 더 견고한 캐싱 메커니즘을 구축하고 빌드 시간을 더욱 개선할 수 있게 해줍니다. 기본적으로 이 기능은 새 프로젝트 템플릿을 사용할 때 활성화됩니다 — Android 빌드를 실행하면 사전 컴파일된 패키지 옆에 [📦] 접두사가 표시되는 것을 볼 수 있습니다. Expo Autolinking 구성에 buildFromSource를 전달하여 옵트아웃할 수 있습니다**:**
{
"name": "opt-out-example",
"dependencies": {},
"expo": {
"autolinking": {
"android": {
"buildFromSource": [
".*"
]
}
}
}
}
- expo-updates는 이제 런타임에 헤더를 재정의할 수 있습니다 Updates.setUpdateURLAndRequestHeadersOverride()를 사용하여 클라이언트 측에서 업데이트에 대한 완전한 제어권을 제공합니다(주의해서 사용하세요). expo-updates 라이브러리는 의도적으로 앱이 실수로 고장날 위험을 최소화하기 위한 가드레일과 함께 구축되었지만, 때로는 이러한 보호 기능을 제어를 위해 포기하는 것을 선호하는 경우가 있습니다. 예를 들어 클라이언트가 업데이트 간에 전환할 수 있는 기능을 활성화하기 위해서입니다(내부 직원을 위한 미리보기 빌드에서와 같이). 자세히 알아보기.
- Android용 expo-updates는 더 이상 실행 시 내장된 자산을 복사하지 않습니다. SDK 53 이전에는 expo-updates가 자산 경로의 일관성을 보장하고 앱 리소스와 저장소에서 파일에 액세스하는 차이로 인해 발생할 수 있는 문제를 피하기 위해 자산을 자체 캐시 디렉토리에 복사했습니다. 이것이 일부 상황에서 실행 시 ANR이 발생할 가능성을 도입하는 것과 같은 바람직하지 않은 부작용이 있다는 것을 알게 되었습니다. 따라서 자산 복사를 안전하게 건너뛰는 방법을 찾았고, 이제 Android에서 expo-updates를 사용하는 앱은 관련 ANR을 경험하지 않아야 하며 더 빠른 시작 시간을 볼 가능성이 높습니다(우리의 테스트 프로젝트에서 업데이트가 조율하는 시작 절차가 ~300ms에서 ~100ms로 단축되었습니다). 이것이 앱에서 회귀를 야기한다면 EX_UPDATES_COPY_EMBEDDED_ASSETS=true를 설정하여 이전 동작으로 롤백할 수 있습니다. expo#36059에서 자세히 알아보기.
- React Server Functions 지원이 이제 베타 상태입니다. 이제 새로운 EXPO_UNSTABLE_DEPLOY_SERVER 환경 변수와 함께 EAS Hosting으로 React Server Functions를 프로덕션에 배포할 수 있으며, 앱 구성에서 experiments.reactServerFunctions를 true로 설정할 수 있습니다. 자세히 알아보기.
- TV와 macOS용 Expo 모듈 개선: Expo에서 현재 지원하는 주요 플랫폼은 Android, iOS, 웹이며, react-native-tvos 프로젝트를 통해 tvOS와 Android TV에도 투자하고 있습니다. Expo Orbit에서는 react-native-macos 프로젝트로 macOS를 타겟으로 하며, Orbit의 개발과 유지보수에 필요한 Expo SDK와 Expo Modules API의 일부에 이 플랫폼에 대한 지원을 구축했습니다. SDK 53에서는 macOS AppDelegate 구독자에 대한 지원을 추가했으며, 사용자는 이제 더 쉬운 설정을 위해 ExpoAppDelegate에서 직접 확장할 수 있습니다. Expo Module TV 및 macOS 플랫폼 지원에 대해 자세히 알아보기.
- expo-file-system/next는 이제 file.blob()을 사용한 파일 업로드를 위해 expo/fetch와 통합됩니다. 자세히 알아보기.
- expo-sqlite는 이제 웹에 대한 실험적 지원을 포함합니다. 몇 가지 추가 사항과 함께 wa-sqlite를 기반으로 한 SQLite의 WebAssembly 빌드를 사용합니다. 구현의 다른 세부 사항에 대해 자세히 알아보려면 expo#35207을 참조하세요. 사용 방법을 알아보려면 문서를 참조하세요.
- expo-sqlite는 이제 libsql을 지원합니다, Turso와의 협력으로 그들의 Offline Sync Public Beta에 대한 지원을 제공했습니다. 시도해보고 제품 성장을 돕기 위해 Turso 팀에 피드백을 제공하세요! 이 예제 저장소와 함께 제공되는 YouTube 비디오에서 자세히 알아보기.
- expo-notifications 개선사항: 커스텀 이미지와 아이콘이 이제 Android용 Expo Push Service에서 지원됩니다. expo-notifications의 iOS 구현이 거의 완전히 Swift와 Expo Modules API로 변환되었습니다. 이를 통해 Expo 프로젝트를 위한 알림 도구를 계속 강화하면서 미래에 더 쉽게 탐색하고 개선할 수 있습니다.
- import.meta 변환 플러그인 추가. 이는 실험적인 옵트인 기능으로, babel-preset-expo 구성에서 unstable_transformImportMeta 옵션으로 활성화할 수 있습니다(예시). 이는 ESM 통합을 개선하고 특히 LiveStore를 더 잘 지원하기 위해 추가되었습니다.
- AppDelegate가 Objective-C에서 Swift로 이동했습니다. AppDelegate 소스 코드를 수정하는 Config Plugin은 Objective-C가 아닌 Swift 수정을 하도록 업데이트되어야 합니다. 이에 대한 주요 사용 사례는 AppDelegate 이벤트를 구독하는 것이며, 이를 처리하는 방법에 대한 우리의 제안에 대해 자세히 알아보세요.
- 권장 TypeScript 버전을 상향 조정했습니다 ~5.8.3로. 이제 expo 저장소에서도 이 버전을 사용합니다.
- 개선된 오류가 제공되는 실험적 옵트인 React 19.1 지원. React 19.1은 "특정 컴포넌트를 렌더링하는 책임이 있는 컴포넌트를 식별하는 데 도움이 되는" Owner Stack API와 함께 제공됩니다. 앱 구성에서 experiments.reactCanary를 true로 토글하여 시도해볼 수 있습니다.
Expo CLI
- eslint-config-expo에서 Flat config 지원. npx expo lint는 이제 flat config를 지원하지만, 원하지 않는다면 아직 마이그레이션할 필요가 없습니다. 마이그레이션 방법 알아보기.
- Expo Atlas가 실험적에서 안정적으로 승격되었습니다. EXPO_ATLAS=1 npx expo로 활성화하여 JavaScript 번들을 조사하고 앱 크기를 개선할 수 있습니다. Atlas에 대해 자세히 알아보기.
- 웹에서 웹 워커에 대한 실험적 지원이 추가되었습니다. 이는 멀티스레드 웹 지원을 위해 expo-sqlite에서 사용됩니다. 네이티브 앱은 여전히 네이티브 모듈과 Reanimated worklet을 사용하여 메인 스레드 밖에서 JavaScript를 실행할 수 있습니다. Expo 프로젝트에서 웹 워커에 대해 자세히 알아보기.
- Expo DOM 컴포넌트에 실험적 EAS Update 지원이 추가되었습니다. 이제 eas update로 DOM 컴포넌트를 업데이트할 수 있습니다 — 프로덕션에서 DOM 컴포넌트를 업데이트하기 전에 스테이징 빌드에서 이를 테스트하고 문제가 있으면 저희에게 보고하세요.
- 오류 메시지가 개선되었습니다. React 오류가 이제 Expo CLI에서 사람이 읽을 수 있게 표시됩니다. 이를 통해 파일에 ⌘+클릭하여 관련 코드 줄로 바로 이동하는 것이 더 쉬워집니다.
Error: Couldn't find the bottom tab bar height. Are you inside a screen in Bottom Tab Navigator?
This error is located at:
20 |
21 | export default function ParallaxScrollView({
> 22 | children,
| ^
23 | headerImage,
24 | headerBackgroundColor,
25 | }: Props) {
Call Stack
ParallaxScrollView (components/ParallaxScrollView.tsx:22:11)
HomeScreen(./(tabs)/index.tsx) (<anonymous>)
Suspense (<anonymous>)
RCTView (<anonymous>)
RCTView (<anonymous>)
RNSScreen (<anonymous>)
Suspense (<anonymous>)
RNSScreenNavigationContainer (<anonymous>)
RCTView (<anonymous>)
TabLayout (app/(tabs)/_layout.tsx:12:37)
Expo Router
- 빌드 타임 리다이렉트와 리라이트 추가. 앱과 웹사이트의 URL과 라우팅을 커스터마이징하는 데 사용할 수 있습니다. 기존 프로젝트를 Expo Router로 마이그레이션하는 데 특히 유용합니다. 자세히 알아보기.
- 가드 그룹. 클라이언트 사이드 라우트를 함께 그룹화하고 guard 함수로 보호할 수 있습니다. 가드에 실패한 라우트는 앵커 라우트로 리다이렉트됩니다. 자세히 알아보기.
- 라우트 사전 로딩. 사전 로딩을 통해 라우트를 백그라운드에서 가져오고 로드할 수 있습니다. <Link /> 컴포넌트의 prop으로 또는 명령형 API의 옵션으로 사용할 수 있습니다. 자세히 알아보기.
- 초기 리다이렉트를 사용한 인증 및 기타 플로우를 더 쉽게 구축할 수 있도록 만들기. 모든 네비게이션 이벤트가 처리될 수 있도록 앱이 이제 가상 루트 네비게이터로 래핑됩니다.
- 문서 개선. 훨씬 개선된 새로운 Expo Router 문서를 공유하게 되어 기쁩니다. 예를 들어, 기초적인 라우터 지식을 다지기 위해 "Router 101" 섹션을 확인해보세요.
🧪 실험 개선된 Swift UI 및 Jetpack Compose 통합으로 새로운 Expo UI 패키지 프로토타입 지원
Expo UI는 개발자들이 Jetpack Compose와 SwiftUI의 네이티브 UI 컴포넌트에 쉽게 액세스할 수 있도록 하는 것을 목표로 합니다. Android Views와 iOS UIKit을 중심으로 구축된 기존 커뮤니티 라이브러리를 보완하기 위해 토글, 슬라이더, 컨텍스트 메뉴, 피커, 리스트와 같은 필수 플랫폼 primitives를 포함할 것입니다.
하지만 이 라이브러리는 현재 초기 프로토타입입니다 — 실험적이며 빠르게 변화하고 있습니다. 오늘 사용하고 있는 API가 내일 바뀔 수 있습니다! Swift UI와 Jetpack Compose는 아직 React Native 생태계에서 널리 사용되지 않으며, 우리는 이러한 도구들과 통합하는 몇 가지 독특한 접근 방식을 탐구해왔습니다. 문제와 제한사항을 발견하게 될 것이며, 이를 보고해주시기 바랍니다! 말할 필요도 없이, 아직 프로덕션에서 사용하는 것은 권장하지 않습니다.
개선된 Swift UI 및 Jetpack Compose 통합에 대한 더 많은 정보가 곧 공개될 예정이며, API 참조에서 Expo UI에 대해 자세히 알아보고 GitHub에서 예제를 볼 수 있습니다. SDK 53 사이클 동안 Expo UI에 대한 업데이트를 지속적으로 릴리스할 예정이며 가까운 미래에 개선사항 요약과 함께 블로그 포스트를 보실 수 있을 것입니다.
로컬 빌드를 위한 원격 캐싱 새로운 experiments.remoteBuildCache 구성은 로컬 빌드에 대한 원격 캐싱을 활성화하므로, 귀하나 팀원 중 누구라도 이미 일치하는 핑거프린트로 빌드를 생성했다면 프로젝트를 다시 컴파일할 필요가 없습니다. 자체 캐시 제공자를 구현하거나 GitHub(예시) 또는 EAS(예시)와 같은 사전 구축된 제공자를 사용할 수 있습니다.
Deprecations 및 제거
- expo-av: Video 컴포넌트는 SDK 52에서 expo-video로 대체되었고 Audio API는 SDK 53에서 expo-audio로 대체되었습니다. expo-av 패키지는 더 이상 유지보수되지 않으며 SDK 54 이후 버전에 대한 새 버전을 게시하지 않을 예정입니다. expo-video에 대해 자세히 알아보기.
- expo-background-fetch: 이 라이브러리는 최신 플랫폼 API를 사용하는 expo-background-task로 대체되었습니다. expo-background-task에 대해 자세히 알아보기.
- 앱 구성의 jsEngine 필드가 deprecated되었습니다: React Native 코어의 JavaScriptCore 지원이 react-native@0.79에서 deprecated되었으며 가까운 미래에 제거될 예정입니다(RFC0836에서 자세히 알아보기). @react-native-community/javascriptcore 패키지를 통해 앱에서 JavaScriptCore를 사용하는 것은 여전히 가능합니다. 현재는 조치가 필요하지 않지만 — SDK 54에서는 앱 구성에서 jsEngine: 'jsc'를 사용하는 대신 이 패키지로 이동해야 할 가능성이 높습니다.
- Android용 Expo Go에서 푸시 알림이 더 이상 지원되지 않습니다, SDK 52에서 deprecated된 후입니다. Expo Go에서는 알림이 작동하지만 동일한 프로젝트의 개발 빌드나 프로덕션 빌드에서는 작동하지 않는 이유에 대해 많은 혼란이 있다는 것을 발견했습니다. 이는 Expo나 EAS가 Expo Go의 통제된 환경 외부에서 알림을 자동으로 구성할 수 없기 때문입니다. 따라서 사용자들은 종종 Expo Go 외부에서 사용하기 위해 알림에 추가 설정이 필요하다는 것에 놀라게 되었는데, 이는 종종 프로젝트의 중요한 시점 — 배포하거나 프로토타입에서 개발 빌드로 성숙해질 때였습니다. EAS를 사용할 때 자동으로 구성할 수 있기 때문에 iOS용 Expo Go에서는 여전히 푸시 알림을 지원합니다. 알림 설정 방법 알아보기.
- React DevTools가 Expo CLI에서 제거되었습니다: 이제 React Native DevTools를 통해 사용할 수 있게 되어, 단일 버전으로 통합하기 위해 Expo CLI 대화형 프롬프트에서 제거했습니다(shift+m을 눌렀을 때 플러그인에 더 이상 나열되지 않음). j를 눌러 React Native DevTools를 실행하면 거기에서 React DevTools를 찾을 수 있습니다.
- Node 18이 2025년 4월 30일에 수명 종료(EOL)에 도달했습니다. SDK 53 프로젝트에는 최소 Node 20을 사용하는 것을 권장합니다.
주요 변경사항
- React 19는 몇 가지 주요 변경사항과 함께 제공되며, React 19 업그레이드 가이드에서 자세히 알아볼 수 있습니다 — 가이드의 웹 관련 지침은 건너뛰어도 됩니다.
- React Native의 내부 import가 export 구문으로 업데이트되었습니다. 중첩된 경로(react-native/x/y)로 require를 사용하여 React Native 패키지 내부에서 import하는 경우, import를 업데이트해야 할 수 있습니다. React Native 0.79 블로그 포스트의 예제를 참조하세요.
- package.json exports와 imports가 React Native 0.79부터 기본적으로 활성화되었습니다. 자세한 정보는 이 포스트의 "package.json exports 필드가 이제 Metro 번들러에서 기본적으로 활성화됨" 제목 아래와 Metro 문서의 ES 모듈 해석 섹션에서 확인할 수 있습니다.
- 기본 AppTheme 업데이트. 새로운 네이티브 Android 프로젝트와 CNG로 생성된 프로젝트는 이제 DayNight 테마를 사용합니다: expo#33964. 이 변경사항은 react-native-edge-to-edge와의 호환성을 위해 edge-to-edge 레이아웃의 출시를 촉진하기 위해 만들어졌습니다.
- Edge-to-edge가 새 프로젝트와 Android용 Expo Go에서 기본적으로 활성화됩니다. Android가 의무화하기 전에 모든 프로젝트가 곧 이를 채택하기를 권장합니다. 자세히 알아보기.
- Deprecated된 setImmediate 폴리필이 런타임에서 제거되었습니다.
- Android 패키지 이름이 더 이상 prebuild에서 링킹 스키마로 자동 추가되지 않습니다. 이 동작은 레거시 이유로 존재했으며, 더 이상 합리적인 기본값이 아닙니다. 패키지 이름을 딥 링킹 스키마로 계속 포함하려면 앱 구성의 android 키 아래에 추가할 수 있습니다: "android": { "scheme": ["your.package.name"] }.
Expo Application Services (EAS) EAS는 Expo 및 React Native 앱을 위한 CI/CD 클라우드 서비스입니다 — Expo나 React Native로 앱을 구축하는 데 반드시 필요한 것은 아니지만, 매우 유용하다고 생각합니다! SDK 53과 관련된 EAS의 여러 업데이트가 있습니다:
- EAS Build는 이제 SDK 53+ 프로젝트에서 기본적으로 고정된 lockfile을 사용합니다. 사용하는 패키지 매니저에 따라 Node 모듈을 설치할 때 적절한 명령/플래그가 사용됩니다 — npm ci, yarn install --frozen-lockfile (및 최신 동등 명령), pnpm install --frozen-lockfile 등. 프로젝트 환경 변수에서 EAS_NO_FROZEN_LOCKFILE=1을 설정하여 고정된 lockfile 사용을 옵트아웃할 수 있습니다.
- 원격 빌드 캐시에 내부적으로 사용되는 업로드 및 다운로드 명령이 추가되었습니다. 예를 들어, npx expo run:ios를 실행한 다음 eas upload를 실행하여 URL로 빌드를 공유할 수 있습니다. eas build:download를 실행하여 빌드를 다운로드할 수 있습니다.
- "빌드 비교" 및 "핑거프린트 비교" 뷰가 프로젝트를 이해하고 문제를 해결하는 데 도움을 줍니다. 이제 각 빌드와 업데이트에 대한 핑거프린트를 저장하며, expo.dev의 diff 뷰에서 직접 비교하거나 (eas fingerprint:compare 실행을 통해) 비교할 수 있습니다. 이는 예상하지 않았을 때 핑거프린트가 변경되는 이유를 이해하고, 업데이트를 안전하게 배포하기 위해 런타임 버전을 언제 범프할지 결정하는 데 유용할 수 있습니다. 빌드에도 유사한 "비교" 뷰를 추가했습니다. 빌드 로그를 diff하는 것(항상 수동으로 diff 도구에 복사 붙여넣기로 했던)이 *"이전 빌드는 성공했는데 왜 이 빌드는 실패했을까?"*라는 질문의 답을 찾으려고 할 때 매우 중요한 첫 번째 단계라는 것을 발견했습니다 — 그래서 EAS에 내장했습니다. 핑거프린트나 빌드 페이지에서 "Compare" 버튼을 눌러 시도해보세요.
- 업데이트 그룹 세부 정보에 업데이트 다운로드 횟수와 평균 다운로드 크기가 이제 표시됩니다. 이는 다운로드 횟수와 업데이트 다운로드의 평균 크기(앱 번들과 포함되었지만 아직 로컬 기기에 없는 관련 자산들)를 보여줍니다.
알려진 문제들
- React 18 피어 종속성으로 인해 여러 react 설치가 발생할 수 있습니다. 많은 라이브러리들이 React 19와 호환될 가능성이 높음에도 불구하고 React 18에 대한 피어 종속성을 가지고 있습니다. 런타임 오류를 야기할 react의 여러 복사본을 npm이 설치하는 것을 방지하기 위해, package.json에 overrides를 추가해야 할 수 있습니다(Yarn에서는 동등한 필드가 resolutions로 명명됩니다. pnpm에서는 resolutions 또는 pnpm.overrides입니다) 모든 라이브러리가 동일한 단일 버전의 React를 사용하도록 보장하기 위해서입니다.
- 일부 라이브러리들이 Metro ES 모듈 해석과 호환되지 않습니다. React Native 0.79가 기본적으로 package.json:exports를 활성화함에 따라 이제 사용됩니다. 예를 들어, @supabase/supabase-js와 @firebase/ 패키지들에서 알려진 문제들이 있습니다.* 현재로서는 이 기능을 옵트아웃하여 해결할 수 있습니다. 자세히 알아보기. 발견한 호환성 문제도 보고해주시기 바랍니다.
- Snack은 아직 SDK 53을 지원하지 않습니다. 곧 지원될 예정입니다.
알려진 리그레션
- 문제를 발견하셨나요? 리그레션을 보고해주세요.
➡️ 앱 업그레이드하기 Expo SDK 52에서 53으로 앱을 업그레이드하는 방법입니다:
- EAS CLI 최신 버전으로 업데이트 (사용하는 경우): 터미널 복사 - npm i -g eas-cli
- SDK 53에 맞게 모든 종속성 업그레이드: 터미널 복사 - npx expo install expo@^53.0.0 --fix
- package.json에 resolutions/overrides가 있다면 여전히 필요한지 확인하세요. 예를 들어, 이전 SDK 릴리스에서 expo-router를 위해 추가했던 metro와 metro-resolver overrides는 제거해야 합니다. 또한 이전에 모노레포에서 잘 작동하도록 metro.config.js를 구성했다면, 변경이 필요한지 확인하기 위해 업데이트된 모노레포 작업 가이드를 읽어보는 것을 권장합니다.
- 가능한 알려진 문제들 확인: 터미널 복사 - npx expo-doctor@latest
- 앱에 가장 영향을 줄 가능성이 높은 주요 변경사항에 대해서는 위의 "Deprecations, renamings, and removals" 섹션을 참조하세요.
- 다른 모든 주요 변경사항은 changelog를 확인하세요!
- 필요시 Xcode 업그레이드: 네이티브 iOS 프로젝트를 컴파일하려면 Xcode 16이 필요합니다. SDK 53에는 Xcode 16.2+를 권장합니다. EAS Build의 경우, image가 지정되지 않은 프로젝트는 기본적으로 Xcode 16.3을 사용합니다.
- Continuous Native Generation을 사용하는 경우:
- 로컬 프로젝트 디렉토리에서 이전 SDK 버전을 위해 생성한 android 및 ios 디렉토리를 삭제하세요. npx expo run:ios, npx expo prebuild 또는 EAS Build로 다음에 빌드를 실행할 때 다시 생성됩니다.
- Continuous Native Generation을 사용하지 않는 경우:
- ios 디렉토리가 있다면 npx pod-install을 실행하세요.
- Native project upgrade helper에서 관련 변경사항을 적용하세요.
- 선택적으로, 향후 더 쉬운 업그레이드를 위해 prebuild 채택을 고려할 수 있습니다.
- expo-dev-client와 함께 development builds를 사용하는 경우: 업그레이드 후 새로운 development build를 생성하세요.
- Expo Go를 사용하는 경우: development builds로 마이그레이션을 고려하세요. Expo Go는 프로덕션 앱의 개발 환경으로 권장되지 않습니다.
- 문제가 있나요? SDK 업그레이드 문제 해결 가이드를 참조하세요.
- 질문이 있나요? Discord에서 매주 수요일 태평양 표준시 오후 12:00에 열리는 주간 오피스 아워에 참여하세요.
'REACT & NODE' 카테고리의 다른 글
React 19 and Next.js 15 (0) | 2025.05.01 |
---|---|
React 19 (Next.js 15) 의 새로운 훅 use (0) | 2025.04.29 |
Expo SDK 53 beta is now available (0) | 2025.04.22 |
React Native 0.77 - New Styling Features, Android’s 16KB page support, Swift Template (0) | 2025.02.05 |
react native 0.76.2 on windows (0) | 2024.11.18 |