个性化阅读
专注于IT技术分析

详细解释React Native和Cordova有哪些区别?

本文概述

随着智能手机和移动应用程序变得如此流行, Web开发人员一直在寻找使用JavaScript创建移动应用程序的方法。这种流行导致开发了许多JavaScript框架, 这些框架能够在移动设备上运行类似本机的应用程序。当前, Cordova和React Native是最受欢迎的选择。 Cordova支持iOS, Android和Windows Phone移动平台。另一方面, 使用React Native, Android, iOS和UWP是开发人员的目标。 (UWP代表通用Windows平台, 这是Microsoft的平台, 该平台允许同一应用程序在Windows Phone 10移动版, XBox One和Windows 10上运行。)

从表面上看, React Native和Cordova占据了相同的空间。但是, 与所有技术一样, 在某些方面有一个亮点, 而另一方面却不足。因此, 为了更好地了解每种技术, 并了解它们的优势和陷阱, 我们将深入研究每种技术的细节, 并在不同学科之间进行比较。

哲学差异

请务必记住, React Native的标语”学习一次, 随处写”不同于通常的跨平台口号”编写一次, 随处运行”。这导致两件事:首先, 我们不能仅从几次单击中就从Web项目中获取现有的React代码库, 然后将其转换为移动应用程序。但是, React和React Native确实共享了许多关键概念, 其中一个例子就是它们的组件系统, 因此, React Native立刻感觉很熟悉。尽管React与React Native有很多相似之处, 但还是有一些核心区别, 从样式表的处理方式到我们可以使用的组件类型。

其次, 当针对不同平台时, 我们可能会发现自己无法共享React Native代码。当我们希望用户界面元素在其特定平台上具有本机行为时, 就会发生这种情况, 从而为用户提供更好的体验和更原生的应用程序体验。一个明显的例子是Android应用程序中的抽屉侧菜单, 在iOS应用程序中很少见。

科尔多瓦不同意这种哲学。开始开发纯Web应用程序, 然后将其捆绑为Cordova应用程序, 并为我们要定位的所有(移动)平台重用尽可能多的代码, 这并不少见。

发展自由

在移动设备上, Cordova在集成的移动Web浏览器(称为WebView)中运行一个单页应用程序, 然后将其包装为本机应用程序。虽然从外部看起来像本机应用程序, 但是我们的Web代码正在移动浏览器引擎中运行。对我们而言, 这意味着我们不受特定库或框架的束缚。如果我们使用的是原始JavaScript, jQuery, Angular或其他任何工具, 那么这些选项中的任何一个都可以通过Cordova捆绑到移动应用程序中。科尔多瓦不强加于我们的技术体系。只要我们有index.html文件, 我们就很好。下面的代码段是一个简单的示例:

<html>
  <head>
    <title>My Cordova App</title>
  </head>
  <body>
    <div id="tapme">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 Native中的React部分是其核心功能之一, 这一点很重要。如果你不喜欢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有自己的打包器。它将所有JavaScript文件捆绑为一个巨型文件, 然后由Apple的JavaScript引擎JavaScriptCore使用并执行。在iOS和Android上使用JavaScriptCore, 而ChakraCore在为React Native UWP应用程序提供支持。默认情况下, React Native使用JavaScript编译器Babel, 使我们可以使用ECMAScript 2015+(ECMAScript 6)语法。尽管不必使用ECMAScript 2015+语法, 但绝对值得鼓励, 因为所有官方示例和第三方模块都在使用它。由于React Native负责打包和编译过程, 因此我们的应用程序代码和第三方模块可以利用这些功能, 而无需自己配置工具。

总而言之, React Native是一种以React为中心的针对移动开发的方法, 而Cordova允许我们将Web技术捆绑在WebView Shell中。

原生外观

对用户而言重要的一件事是拥有应用程序的本机外观。由于Cordova应用程序通常是简单的Web应用程序, 因此有些事情乍一看可能很奇怪。问题可能包括缺少点击区域上的视觉反馈, 滚动感觉不如本机应用中的丝般柔滑, 甚至是点击事件延迟了300毫秒。尽管所有这些问题都有解决方案, 但我们应该记住, 如果我们希望我们的Cordova应用程序尽可能地接近本机应用程序, 则可能需要付出一些额外的努力。在Cordova中, 我们无权访问任何本机控件。如果要具有本机外观, 则有两个选择:用HTML和CSS重新创建本机控件(如按钮和输入元素), 或实现直接访问这些本机控件的本机模块。我们可以自己完成此操作, 也可以使用第三方库(例如Ionic或Onsen UI)来完成此操作。请注意, 重要的是要使它们与操作系统更新保持同步。有时, 移动操作系统的外观会有所改观, 就像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提供了类似的命令行界面, 并提供了Web开发人员熟悉的开发工作流程。我们可以即时重新加载。更改React组件后, 我们的应用程序将使用所做的更改重新加载。最激动人心的功能之一就是热模块更换, 该模块可以部分重新加载我们所做的组件中的更改, 而无需更改应用程序的状态。我们甚至可以连接到实际设备, 并查看更改是否如预期的那样在真实设备上工作。我们的React Native应用程序可以使用Chrome for Desktop进行远程调试。错误处理在React Native中很明显。如果遇到错误, 我们的应用程序将显示红色背景, 并显示堆栈跟踪。多亏了原始地图, 我们才能看到错误的确切位置。当我们单击它时, 我们选择的编辑器将在代码的精确位置打开。

可扩展性和对本机功能的访问

从JavaScript的角度来看, 我们可以自由使用任何JavaScript库, 包括来自NPM的软件包。但是, 由于React Native不是浏览器环境, 因此我们可能发现难以利用依赖DOM的代码。 React Native包含CommonJS和ES2015模块, 因此使用这些格式的任何库都易于集成。

Cordova和React Native都可以​​创建和使用连接到事物本机端的插件。 Cordova提供了一个低级API来创建我们自己的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_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);

虽然我们仅仔细研究了使用Objective-C在iOS中创建模块, 但是相同的原理适用于使用Java为Android创建模块。

我们需要在每个平台的项目文件中链接本机插件。例如, 对于iOS, 这意味着我们必须将已编译的本机部分与应用程序链接, 并添加相应的头文件。这可能是一个漫长的过程, 尤其是在有很多本机模块的情况下。幸运的是, 使用称为rnpm的命令行实用程序已将它大大简化, 该实用程序已成为React Native本身的一部分。

结论:对Native还是Cordova有反应?

React Native和Cordova具有不同的用途, 因此可以满足不同的需求。因此, 很难说一种技术在所有学科中都比另一种更好。

通过使用Cordova, 你可以快速将现有的单页应用程序转换为适用于不同平台的移动应用程序, 而交互的代价并不一定是其特定平台具有原生的感觉。

使用React Native, 应用程序具有更原始的外观, 但以重新实现某些目标平台的代码段为代价。如果你已经涉足React, 并且对开发移动应用程序感兴趣, 那么React Native就像是一个自然的扩展。

相关:冷潜到React Native:初学者的教程

赞(0)
未经允许不得转载:srcmini » 详细解释React Native和Cordova有哪些区别?

评论 抢沙发

评论前必须登录!