The Duel: React Native กับ Cordova
เผยแพร่แล้ว: 2022-03-11เนื่องจากสมาร์ทโฟนและแอปพลิเคชันมือถือได้รับความนิยมอย่างมาก นักพัฒนาเว็บจึงมองหาวิธีสร้างแอปพลิเคชันมือถือโดยใช้ JavaScript ความนิยมนี้ส่งผลให้มีการพัฒนาเฟรมเวิร์ก JavaScript จำนวนมากที่สามารถเรียกใช้แอปพลิเคชันที่เหมือนเนทีฟบนอุปกรณ์มือถือได้ ปัจจุบัน Cordova และ React Native เป็นตัวเลือกยอดนิยม Cordova รองรับแพลตฟอร์มมือถือ iOS, Android และ Windows Phone ด้วย React Native ในทางกลับกัน Android, iOS และ UWP เป็นเป้าหมายสำหรับนักพัฒนา (UWP ย่อมาจาก Universal Windows Platform ซึ่งเป็นแพลตฟอร์มของ Microsoft ที่อนุญาตให้แอปพลิเคชันเดียวกันทำงานบน Windows Phone 10 Mobile, XBox One และ Windows 10)
จากพื้นผิว ปรากฏว่า React Native และ Cordova ครอบครองพื้นที่เดียวกัน อย่างไรก็ตาม เช่นเดียวกับเทคโนโลยีทั้งหมด มีแง่มุมหนึ่งที่ด้านหนึ่งโดดเด่น และอีกด้านขาดหายไป ดังนั้น เพื่อให้เห็นภาพที่ดีขึ้นของแต่ละเทคโนโลยี และเพื่อเรียนรู้ข้อดีและข้อเสียของเทคโนโลยี เราจะเจาะลึกลงไปในรายละเอียดของเทคโนโลยีแต่ละอย่างและเปรียบเทียบกันตามสาขาวิชาต่างๆ
ความแตกต่างในปรัชญา
สิ่งสำคัญคือต้องจำไว้ว่าสโลแกนของ React Native "เรียนรู้ครั้งเดียว เขียนได้ทุกที่" แตกต่างจากมนต์ข้ามแพลตฟอร์มทั่วไป "เขียนครั้งเดียว เรียกใช้ได้ทุกที่" สิ่งนี้นำไปสู่สองสิ่ง: ประการแรก เราไม่สามารถเพียงแค่นำ React codebase ที่มีอยู่จากโครงการเว็บของเรามาแปลงเป็นแอปพลิเคชันมือถือได้ด้วยการคลิกเพียงไม่กี่ครั้ง อย่างไรก็ตาม React และ React Native แบ่งปันแนวคิดหลักมากมาย โดยตัวอย่างหนึ่งคือระบบส่วนประกอบ และด้วยเหตุนี้ React Native จึงรู้สึกคุ้นเคยในทันที แม้ว่า React จะมีความคล้ายคลึงกันมากกับ React Native แต่ก็มีความแตกต่างหลักบางประการ ซึ่งมีตั้งแต่วิธีจัดการกับสไตล์ชีตไปจนถึงประเภทของส่วนประกอบที่เราสามารถใช้ได้
ประการที่สอง เราอาจพบว่าตัวเองไม่สามารถแชร์ React Native code เมื่อกำหนดเป้าหมายแพลตฟอร์มต่างๆ สิ่งนี้เกิดขึ้นเมื่อเราต้องการให้องค์ประกอบส่วนต่อประสานกับผู้ใช้ทำงานโดยกำเนิดกับแพลตฟอร์มเฉพาะของพวกเขา ในทางกลับกัน ผู้ใช้จะได้รับประสบการณ์ที่ดีขึ้นและให้ความรู้สึกดั้งเดิมกับแอปมากขึ้น ตัวอย่างที่ชัดเจนคือเมนูด้าน Drawer ในแอป Android ซึ่งเป็นเรื่องปกติในแอป iOS
คอร์โดวาไม่แบ่งปันปรัชญานี้ ไม่ใช่เรื่องแปลกที่จะเริ่มพัฒนาเว็บแอปพลิเคชันแท้ ๆ แล้วรวมกลุ่มเป็นแอปพลิเคชัน Cordova ในภายหลัง และใช้รหัสซ้ำให้มากที่สุดสำหรับแพลตฟอร์ม (มือถือ) ทั้งหมดที่เราต้องการกำหนดเป้าหมาย
เสรีภาพในการพัฒนา
บนอุปกรณ์พกพา Cordova กำลังเรียกใช้แอปพลิเคชันหน้าเดียวภายในเว็บเบราว์เซอร์มือถือแบบรวมที่เรียกว่า WebView จากนั้นจึงรวมเป็นแอปพลิเคชันดั้งเดิม แม้ว่าจะดูเหมือนแอปพลิเคชันดั้งเดิมจากภายนอก แต่โค้ดเว็บของเรากำลังทำงานอยู่ในเอ็นจิ้นเบราว์เซอร์มือถือ สำหรับเรา หมายความว่าเราไม่ได้เชื่อมโยงกับไลบรารีหรือเฟรมเวิร์กเฉพาะ หากเราใช้ vanilla 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 หรืออย่างอื่นทั้งหมด ไม่เป็นไร ตราบใดที่ผลลัพธ์เป็นไฟล์ index.html
ที่โหลด JavaScript และสไตล์ชีตทั้งหมดที่เราต้องการ
React Native สร้างขึ้นตามชื่อ React สิ่งสำคัญคือต้องเข้าใจส่วน React ใน React Native เป็นหนึ่งในคุณสมบัติหลัก หากคุณไม่ใช่แฟนของลักษณะการประกาศของ React รวมถึง JSX การจัดองค์ประกอบ และการไหลของข้อมูล โอกาสที่คุณอาจไม่พอใจกับ 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 มี packager เป็นของตัวเอง มันรวมไฟล์ JavaScript ทั้งหมดเป็นไฟล์ขนาดยักษ์เดียว ซึ่งจะถูกใช้งานและดำเนินการโดย JavaScriptCore ซึ่งเป็นเอ็นจิ้น JavaScript ของ Apple 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 โปรดทราบว่าการอัปเดตระบบปฏิบัติการให้ทันสมัยอยู่เสมอเป็นสิ่งสำคัญ บางครั้ง รูปลักษณ์ของระบบปฏิบัติการบนมือถือก็ถูกปรับโฉมใหม่ เหมือนกับที่เกิดขึ้นเมื่อเปิดตัว iOS 7 การมีแอปที่ไม่สามารถปรับเปลี่ยนได้จะทำให้ผู้ใช้หมดประสบการณ์ นอกจากนี้เรายังสามารถใช้ปลั๊กอิน Cordova ที่เชื่อมโยงเรากับสิ่งต่าง ๆ ได้ หนึ่งในการควบคุมแบบเนทีฟที่สมบูรณ์ที่สุดคือไลบรารี Ace ของ Microsoft
ในทางกลับกัน ด้วย 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; หากเราพบข้อผิดพลาด แอปพลิเคชันของเราจะแสดงพื้นหลังสีแดง และการติดตามสแต็กจะปรากฏขึ้น ขอบคุณ sourcemaps เราสามารถดูตำแหน่งที่แน่นอนของข้อผิดพลาดได้ เมื่อเราคลิกที่มัน ตัวแก้ไขที่เราเลือกจะเปิดขึ้นที่ตำแหน่งที่แน่นอนของโค้ด
ความสามารถในการขยายและการเข้าถึงคุณสมบัติดั้งเดิม
จากด้าน JavaScript เรามีอิสระที่จะใช้ไลบรารี JavaScript ใดๆ รวมถึงแพ็คเกจจาก NPM อย่างไรก็ตาม เนื่องจาก React Native ไม่ใช่สภาพแวดล้อมของเบราว์เซอร์ เราอาจพบว่ามันยากในการใช้โค้ดที่อาศัย DOM React Native รวมโมดูล CommonJS และ ES2015 ดังนั้นไลบรารีใดๆ ที่ใช้รูปแบบเหล่านี้จึงง่ายต่อการรวมเข้าด้วยกัน
ทั้ง Cordova และ React Native มีความสามารถในการสร้างและใช้ปลั๊กอินที่เชื่อมต่อกับด้านเนทีฟของสิ่งต่างๆ Cordova จัดเตรียม API ระดับต่ำสำหรับการสร้างของเราเอง ซึ่งทำให้เราสามารถควบคุมได้มาก แต่นำไปสู่การใช้ต้นแบบของเนทีฟและ JavaScript มากขึ้น
หากเราจะเขียนปลั๊กอิน Cordova iOS ใน Objective-C โดยสมมุติฐาน อาจดูเหมือนข้อมูลโค้ดถัดไป ปลั๊กอินของเราจะบันทึกพารามิเตอร์อินพุต
#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_MODULE
และ RCT_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);
แม้ว่าเราจะพิจารณาเฉพาะการสร้างโมดูลใน iOS โดยใช้ Objective-C แต่หลักการเดียวกันกับการสร้างโมดูลสำหรับ Android โดยใช้ Java
เราจำเป็นต้องเชื่อมโยงปลั๊กอินดั้งเดิมภายในไฟล์โครงการสำหรับแต่ละแพลตฟอร์ม ตัวอย่างเช่น สำหรับ iOS หมายความว่าเราต้องเชื่อมโยงส่วนเนทีฟที่คอมไพล์กับแอปพลิเคชันของเราและเพิ่มไฟล์ส่วนหัวที่เกี่ยวข้อง นี่อาจเป็นกระบวนการที่ยาวนาน โดยเฉพาะอย่างยิ่งหากมีโมดูลเนทีฟจำนวนมาก โชคดีที่สิ่งนี้ง่ายขึ้นอย่างมากโดยใช้ยูทิลิตี้บรรทัดคำสั่งที่เรียกว่า rnpm ซึ่งกลายเป็นส่วนหนึ่งของ React Native เอง
สรุป: React Native หรือ Cordova?
React Native และ Cordova มีวัตถุประสงค์ที่แตกต่างกัน ดังนั้นจึงตอบสนองความต้องการที่แตกต่างกัน ดังนั้นจึงเป็นเรื่องยากที่จะบอกว่าเทคโนโลยีหนึ่งดีกว่าเทคโนโลยีอื่นๆ ในทุกสาขาวิชา
ด้วยการใช้ Cordova คุณสามารถเปลี่ยนแอปพลิเคชันหน้าเดียวที่มีอยู่ของคุณให้เป็นแอปพลิเคชันมือถือสำหรับแพลตฟอร์มต่างๆ ได้อย่างรวดเร็ว โดยที่ค่าใช้จ่ายในการโต้ตอบไม่จำเป็นต้องมีความรู้สึกดั้งเดิมต่อแพลตฟอร์มเฉพาะของพวกเขา
ด้วย React Native แอปพลิเคชันจะมีรูปลักษณ์และความรู้สึกที่เป็นธรรมชาติมากขึ้น แต่ต้องใช้ต้นทุนในการนำโค้ดไปใช้ซ้ำสำหรับแพลตฟอร์มเป้าหมายบางประเภท หากคุณเคยใช้ React มาก่อนและสนใจที่จะพัฒนาแอปพลิเคชันบนมือถือ React Native ให้ความรู้สึกเหมือนเป็นส่วนขยายที่เป็นธรรมชาติ