듀얼: React Native 대 Cordova

게시 됨: 2022-03-11

스마트폰과 모바일 애플리케이션이 대중화되면서 웹 개발자들은 JavaScript를 사용하여 모바일 애플리케이션을 만드는 방법을 찾고 있습니다. 이러한 인기로 인해 모바일 장치에서 네이티브와 유사한 애플리케이션을 실행할 수 있는 많은 JavaScript 프레임워크가 개발되었습니다. 현재 Cordova와 React Native가 가장 인기 있는 선택입니다. Cordova는 iOS, Android 및 Windows Phone 모바일 플랫폼을 지원합니다. 반면에 React Native를 사용하면 Android, iOS 및 UWP가 개발자의 대상입니다. (UWP는 Windows Phone 10 Mobile, XBox One 및 Windows 10에서 동일한 응용 프로그램을 실행할 수 있도록 하는 Microsoft 플랫폼인 Universal Windows Platform을 나타냅니다.)

겉보기에는 React Native와 Cordova가 같은 공간을 차지하고 있는 것처럼 보입니다. 그러나 모든 기술이 그렇듯이 하나는 빛을 발하고 다른 하나는 부족한 측면이 있습니다. 따라서 각 기술을 더 잘 이해하고 장점과 함정을 알아보기 위해 각 기술에 대해 자세히 알아보고 다양한 분야에서 비교할 것입니다.

철학의 차이

React Native의 슬로건인 "한 번 배우고 어디에서나 작성하십시오"는 일반적인 크로스 플랫폼 만트라인 "한 번 작성하면 어디에서나 실행하십시오"와 다르다는 것을 기억하는 것이 중요합니다. 이것은 두 가지 결과로 이어집니다. 첫째, 웹 프로젝트에서 기존 React 코드베이스를 가져 와서 단 몇 번의 클릭만으로 모바일 애플리케이션으로 전환할 수 없습니다. 그러나 React와 React Native는 구성 요소 시스템을 예로 들며 많은 핵심 개념을 공유하므로 React Native는 즉시 친숙하게 느껴집니다. React는 React Native와 많은 유사점을 공유하지만 스타일시트가 처리되는 방식에서 사용할 수 있는 구성 요소 유형에 이르기까지 몇 가지 핵심적인 차이점이 있습니다.

둘째, 다른 플랫폼을 대상으로 할 때 React Native 코드를 공유하지 못할 수도 있습니다. 이는 사용자 인터페이스 요소가 특정 플랫폼에서 기본적으로 작동하도록 하여 사용자에게 더 나은 경험과 앱에 대한 기본적 느낌을 제공할 때 발생합니다. 확실한 예는 iOS 앱에서는 매우 드문 Android 앱의 서랍 사이드 메뉴입니다.

Cordova는 이 철학을 공유하지 않습니다. 순수한 웹 응용 프로그램 개발을 시작하고 나중에 Cordova 응용 프로그램으로 번들하고 대상으로 지정하려는 모든 (모바일) 플랫폼에 대해 가능한 한 많은 코드를 재사용하는 것은 드문 일이 아닙니다.

개발 자유

모바일 장치에서 Cordova는 WebView라고 하는 통합 모바일 웹 브라우저 내에서 단일 페이지 애플리케이션을 실행한 다음 이를 기본 애플리케이션으로 래핑합니다. 외부에서는 기본 애플리케이션처럼 보이지만 웹 코드는 모바일 브라우저 엔진 내부에서 실행됩니다. 그것은 우리가 특정 라이브러리나 프레임워크에 얽매이지 않는다는 것을 의미합니다. 바닐라 JavaScript, jQuery, Angular 또는 기타를 사용하는 경우 이러한 옵션 중 하나를 Cordova와 함께 모바일 애플리케이션에 번들로 제공할 수 있습니다. Cordova는 우리의 기술 스택에 부과하지 않습니다. index.html 파일만 있으면 계속 진행할 수 있습니다. 한 가지 간단한 예는 다음 코드 스니펫입니다.

 <html> <head> <title>My Cordova App</title> </head> <body> <div>Tap me</div> <script> // Select our element var element = document.getElementById('tapme'); // Send an alert once it was tapped/clicked element.addEventListener('click', function() { alert('Hello there!'); }); </script> </body> </html>

이 예제는 NPM 또는 Bower와 같은 패키지 관리자 사용, Babel, CoffeeScript 또는 TypeScript와 같은 트랜스파일러, Webpack 또는 Rollup과 같은 번들러 사용 또는 완전히 다른 것과 같이 우리가 원하는 거의 모든 것을 사용할 수 있음을 의미합니다. 결과가 필요한 모든 JavaScript와 스타일시트를 로드하는 index.html 파일이면 문제가 되지 않습니다.

React Native는 이름에서 알 수 있듯이 React를 기반으로 합니다. React Native의 React 부분은 핵심 기능 중 하나라는 것을 이해하는 것이 중요합니다. JSX, 컴포넌트화, 데이터 흐름을 포함한 React의 선언적 특성을 좋아하지 않는다면 아마도 React Native에 만족하지 못할 것입니다. React Native는 React 개발자에게 즉시 친숙하게 느껴지지만 첫눈에 기억해야 할 몇 가지 차이점이 있습니다. React Native를 사용하면 HTML이나 CSS가 없습니다. 대신 이 기술은 JavaScript 쪽에 중점을 둡니다. CSS의 대안으로 스타일이 인라인으로 작성되고 Flexbox가 기본 스타일 모델입니다.

가장 기본적인 React Native 애플리케이션은 다음 예와 유사합니다.

 // Import the React module for JSX conversion import { React } from 'react'; // Import React Native's components import { View, Text, AppRegistry, TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Define our press handler const onPress = () => alert('Hello there!'); // Compose the components we are going to render return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

React Native에는 자체 패키지 도구가 있습니다. 모든 JavaScript 파일을 하나의 거대한 파일로 묶은 다음 Apple의 JavaScript 엔진인 JavaScriptCore에서 사용하고 실행합니다. JavaScriptCore는 iOS 및 Android에서 사용되고 있으며 ChakraCore는 React Native UWP 애플리케이션을 지원합니다. 기본적으로 React Native는 JavaScript 변환기 Babel을 사용하므로 ECMAScript 2015+(ECMAScript 6) 구문을 사용할 수 있습니다. ECMAScript 2015+ 구문을 사용할 필요는 없지만 모든 공식 예제와 타사 모듈이 이를 수용하므로 확실히 권장됩니다. React Native가 패키징 및 트랜스파일링 프로세스를 처리하기 때문에 애플리케이션 코드와 타사 모듈은 도구를 직접 구성할 필요 없이 이러한 기능을 활용할 수 있습니다.

요약하자면, React Native는 모바일 개발에 대한 React 중심의 독선적인 접근 방식인 반면 Cordova를 사용하면 WebView 셸 내부에 웹 기술을 번들로 묶을 수 있습니다.

네이티브 룩앤필

사용자에게 중요한 한 가지는 응용 프로그램의 기본 모양과 느낌을 갖는 것입니다. Cordova 애플리케이션은 일반적으로 단순한 웹 애플리케이션이기 때문에 처음에는 이상하게 느껴질 수 있는 몇 가지 사항이 있습니다. 문제는 탭 영역에 대한 시각적 피드백 누락, 기본 애플리케이션에서처럼 매끄럽게 느껴지지 않는 스크롤, 탭 이벤트에서 300밀리초 지연에 이르기까지 다양합니다. 이러한 모든 문제에 대한 솔루션이 있지만 Cordova 애플리케이션이 가능한 한 기본 애플리케이션에 가깝게 느껴지도록 하려면 약간의 추가 노력이 필요할 수 있음을 기억해야 합니다. Cordova에서는 기본 컨트롤에 액세스할 수 없습니다. 네이티브 룩앤필을 원하는 경우 두 가지 옵션이 남아 있습니다. 버튼 및 입력 요소와 같은 네이티브 컨트롤을 HTML 및 CSS로 다시 생성하거나 해당 네이티브 컨트롤에 직접 액세스하는 네이티브 모듈을 구현하는 것입니다. 우리는 스스로 이 작업을 수행하거나 Ionic 또는 Onsen UI와 같은 타사 라이브러리를 사용하여 이 작업을 수행할 수 있습니다. OS 업데이트가 나올 때마다 최신 상태로 유지하는 것이 중요합니다. 때로는 iOS 7이 도입되었을 때와 같이 모바일 운영 체제의 모양이 바뀌었습니다. 적응할 수 없는 앱이 있으면 사용자가 경험하지 못하게 됩니다. 우리는 사물의 기본 측면에 우리를 연결하는 Cordova 플러그인을 포함할 수도 있습니다. 가장 완벽한 기본 컨트롤 중 하나는 Microsoft의 Ace 라이브러리입니다.

반면에 React Native를 사용하면 기본 컨트롤 및 상호 작용에 즉시 액세스할 수 있습니다. Text , TextInput 또는 Slider 와 같은 구성 요소는 기본 구성 요소에 매핑됩니다. 일부 구성 요소는 모든 플랫폼에서 사용할 수 있지만 다른 구성 요소는 특정 플랫폼에서만 작동합니다. 응용 프로그램이 기본 모양과 느낌을 갖기를 원할수록 이 특정 플랫폼에서만 사용할 수 있는 구성 요소를 더 많이 사용해야 하므로 코드베이스가 더 많이 분기됩니다. 마인드 터치 상호 작용 및 제스처도 React Native의 일부입니다.

성능 비교

Cordova는 WebView만 사용할 수 있으므로 WebView의 제한 사항이 적용됩니다. 예를 들어, 4.0 버전에 이어 Android는 마침내 (훨씬 더 빠른) Chrome 엔진을 기본 WebView로 사용하기 시작했습니다. iOS를 사용하는 동안 기본 WebView 엔진 내에서 실행되는 애플리케이션은 오랫동안 Safari 모바일 브라우저의 동일한 애플리케이션보다 훨씬 느렸습니다. 게다가 JavaScript는 단일 스레드이기 때문에 애플리케이션 코드에서 너무 많은 일이 발생하면 문제가 발생할 수 있습니다. 이러한 제한으로 인해 애니메이션이 느려지고 응용 프로그램이 원하는 만큼 응답하지 않을 수 있습니다. 우리가 여기저기서 사용할 수 있는 몇 가지 트릭이 있을 수 있지만 결국에는 모바일 브라우저의 한계에 묶여 있습니다.

React Native는 여러 스레드를 활용하므로 렌더링 UI 요소는 자체 스레드에서 실행됩니다. React 구성 요소는 기본 보기에 연결되기 때문에 JavaScript는 React Native에서 무거운 작업을 수행하지 않습니다.

개발자 워크플로

Cordova는 시뮬레이터에서 애플리케이션을 시작하고 프로덕션 모드에서 실제 장치용 애플리케이션을 빌드하여 새 프로젝트 템플릿을 생성하는 명령줄 유틸리티를 제공합니다. 대부분의 경우 데스크톱 브라우저에서 애플리케이션을 개발 중이며 나중에 모바일 애플리케이션으로 번들링할 수 있습니다. Cordova가 제공하는 자유로 인해 우리는 개발 워크플로를 직접 처리해야 합니다. 장치에서 실시간 다시 로드를 원하면 직접 구현해야 합니다. Cordova 애플리케이션을 디버그하기 위해 웹사이트 디버그에 사용된 것과 동일한 원칙을 적용합니다. 예를 들어 iOS에서는 USB를 통해 모바일 장치를 연결하고 Safari와 개발자 도구를 엽니다.

React Native는 유사한 명령줄 인터페이스를 제공하며 웹 개발자에게 친숙한 개발 워크플로를 제공합니다. 우리는 상자에서 라이브로 다시 로드합니다. React 구성 요소를 변경하면 응용 프로그램이 변경 사항으로 다시 로드됩니다. 가장 흥미로운 기능 중 하나는 애플리케이션 상태를 변경하지 않고 구성 요소의 변경 사항을 부분적으로 다시 로드하는 핫 모듈 교체입니다. 실제 장치에 연결하여 변경 사항이 실제 장치에서 예상한 대로 작동하는지 확인할 수도 있습니다. React Native 애플리케이션은 데스크톱용 Chrome을 사용하여 원격으로 디버깅할 수 있습니다. 오류 처리는 React Native에서 명백합니다. 오류가 발생하면 애플리케이션에 빨간색 배경이 표시되고 스택 추적이 표시됩니다. 소스맵 덕분에 오류의 정확한 위치를 볼 수 있습니다. 그것을 클릭하면 선택한 편집기가 코드의 정확한 위치에서 열립니다.

기본 기능에 대한 확장성 및 액세스

JavaScript 측면에서 NPM의 패키지를 포함하여 모든 JavaScript 라이브러리를 자유롭게 사용할 수 있습니다. 그러나 React Native는 브라우저 환경이 아니기 때문에 DOM에 의존하는 코드를 활용하기 어려울 수 있습니다. React Native는 CommonJS 및 ES2015 모듈을 수용하므로 이러한 형식을 사용하는 모든 라이브러리는 쉽게 통합할 수 있습니다.

Cordova와 React Native는 모두 사물의 기본 측면에 연결하는 플러그인을 만들고 사용할 수 있는 기능이 있습니다. Cordova는 자체 생성을 위한 저수준 API를 제공하여 많은 제어를 제공하지만 더 많은 기본 및 JavaScript 상용구를 사용하게 됩니다.

Objective-C에서 Cordova iOS 플러그인을 가상으로 작성한다면 다음 코드 조각처럼 보일 수 있습니다. 플러그인은 입력 매개변수만 기록합니다.

 #import <Cordova/CDVPlugin.h> // Create a class that inherits from CDVPlugin @interface Log : CDVPlugin - (void)log:(CDVInvokedUrlCommand*)command; @end // The actual implementation of the class we just defined @implementation Log - (void)log:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; // We are getting all parameters and taking the first one NSString* echo = [command.arguments objectAtIndex:0]; // We are checking for the validity of the parameters if (echo != nil && [echo length] > 0) { // We are just printing the parameter using the native log method NSLog(echo); // Let's create a result for the plugin pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; } // Let's send a signal back with the plugin's result [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end

모듈을 사용하려면 이 JavaScript 코드가 도움이 될 것입니다.

 window.log = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Log", "log", [str]); };

플러그인을 사용하려면 log 함수를 호출하기만 하면 됩니다.

 window.log('Hello native!');

반면에 React Native는 다른 철학을 따릅니다. 플러그인을 작성할 때 JavaScript 유형을 기본 유형에 자동으로 매핑하므로 기본 코드를 JavaScript와 더 쉽게 연결할 수 있습니다. React Native로 네이티브 모듈을 만드는 데 필요한 코드를 살펴보겠습니다.

 #import "RCTBridgeModule.h" @interface Log : NSObject <RCTBridgeModule> @end @implementation Log RCT_EXPORT_MODULE(); // This makes this method available NativeModules.Log.log RCT_EXPORT_METHOD(log:(NSString *)message) { NSLog(message); } @end

React Native는 RCT_EXPORT_MODULERCT_EXPORT_METHOD 호출로 모듈을 바인딩합니다. 이제 NativeModules.Log.log 를 사용하여 다음과 같이 액세스할 수 있습니다.

 import { React } from 'react'; import { View, Text, AppRegistry, NativeModules TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Log with our module once we tap the text const onPress = () => NativeModules.Log.log('Hello there'); return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

Objective-C를 사용하여 iOS에서 모듈을 만드는 방법만 자세히 살펴보았지만 Java를 사용하여 Android용 모듈을 만드는 경우에도 동일한 원칙이 적용됩니다.

각 플랫폼의 프로젝트 파일 내에서 네이티브 플러그인을 연결해야 합니다. 예를 들어 iOS의 경우 이는 컴파일된 네이티브 부분을 애플리케이션과 연결하고 해당 헤더 파일을 추가해야 함을 의미합니다. 이는 특히 기본 모듈이 많은 경우 긴 프로세스가 될 수 있습니다. 다행스럽게도 이것은 React Native 자체의 일부가 된 rnpm이라는 명령줄 유틸리티를 사용하여 크게 단순화되었습니다.

결론: React Native 또는 Cordova?

React Native와 Cordova는 목적이 다르므로 요구 사항도 다릅니다. 따라서 모든 분야에서 한 기술이 다른 기술보다 우수하다고 말하기는 어렵습니다.

Cordova를 사용하면 기존 단일 페이지 애플리케이션을 다양한 플랫폼용 모바일 애플리케이션으로 신속하게 전환할 수 있습니다. 단, 상호 작용이 특정 플랫폼에 대한 고유한 느낌을 가질 필요는 없습니다.

React Native를 사용하면 애플리케이션이 더 네이티브 모양과 느낌을 갖게 되지만 특정 대상 플랫폼에 대한 코드 조각을 다시 구현해야 합니다. 이미 React를 접했고 모바일 애플리케이션 개발에 관심이 있다면 React Native가 자연스럽게 확장된 것처럼 느껴집니다.

관련 항목: React Native에 대해 자세히 알아보기: 초심자를 위한 자습서