热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScript的ReactWeb库的理念剖析及基础上手指南

这篇文章主要介绍了JavaScript的ReactWeb库的理念剖析及基础上手指南,ReactWeb的目的即是把本地的ReactNative应用程序项目变为Web应用程序,需要的朋友可以参考下

React Web的目的及意义非常明确: 让React Native代码跑在Web上 让一套代码运行在各个移动终端,对前端及业务来说,这是开发效率中一个质的提升。在项目初期,我们也曾向 React团队咨询过类似的问题,他们团队的核心同学 @vjeux 也认为这是非常酷的事情,也是他们未来想做的事情。也许在发布React Native for Android的时候,也会发布React Web也说不定。(YY一下)
技术架构
基于React Native的适配方案,有几个:
1.制定一个Bridge标准,RN与RW 各自用最优的方式实现这套标准。
比如基于Flex布局,我们实现一套一致的 Flex Component, 等。
2.完全向RN看齐,RW实现RN的所有能实现的API。
在讨论中,最终选择了后者。
因为React Web的理念,让React Native代码跑在Web端,那么就决定了RW只是一个构建及打包工具,脱离RN,RW的实现则没有太大的意义,那么整体的技术方向就非常明确了: 实现RN一致的Style、Component及API,最终通过构建工具编译成web版本。

2016510152622276.png (550×307)

示例

下面我们来看一下React Web项目的创建过程:
第一步:安装 React web 并进行相关配置
这一步操作主要是安装 react-web 包以及相关依赖,并配置 webpack 打包脚本等。
为了简化这一步操作,我们开发了命令行工具 react-web-cli 只需要执行两行命令即可。同时命令行工具还支持启动调试服务器、打包等功能,在后面介绍。
安装 cli 工具:

npm install react-web-cli -g

安装配置 React web 等:

react-web init <当前项目目录>

执行完成之后,会在你项目目录下面 npm install 相关库,并自动创建 web/webpack.config.js 文件,里面有一份写好的配置。此时目录结构为:

.
├── README.md
├── android/
├── index.android.js
├── index.ios.js
├── ios/
├── package.json
└── web/
 └── webpack.config.js

第二步:添加入口文件并进行相关配置
每个项目都需要有一个入口文件,通常用来引入调用其他组件并初始化项目,比如 index.ios.js 表示 iOS 平台上的该项目的入口文件。为了符合 React Native 的文件命名规范,我们创建一个 index.web.js 作为入口文件,并且需要在 webpack 中指定该文件为入口文件。打开 web/webpack.config.js 文件,修改 config 变量:

var cOnfig= {
 paths: {
 src: path.join(ROOT_PATH, '.'),
 index: path.join(ROOT_PATH, 'index.web'),
 },
};

然后我们创建 index.web.js 文件。这个文件其实跟 index.ios.js 非常像,只是略有不同。主要区别在于:iOS 只需要 AppRegistry.registerComponent('Awes', () => Awes); 即可让 Xcode 的 Native 代码接收处理你的 JS 代码,而 Web 端是需要插入到 DOM 节点中才可以用。因此我们需要在 index.web.js 最下面添加如下代码:

AppRegistry.registerComponent('Awes', () => Awes);
if (Platform.OS == 'web') {
 var app = document.createElement('div');
 document.body.appendChild(app);
 AppRegistry.runApplication('Awes', {
 rootTag: app
 });
}

然后在最上面 require 部分需要引入 Platform 组件。这样配置部分就已经处理完成了,执行 react-web start 命令即可启动调试服务器啦!

2016510152827702.jpg (832×1388)

可以随便修改试下,跟 React Native 模拟器里面的体验几乎一样。
第三步:测试并打包 Web 版本代码
当你修改开发完,并对 Web 端也测试好了,就可以打包发布了。react-web-cli 工具打包的命令是:

react-web bundle

打包完成后,文件会存放在 web/output/ 目录下面,可以直接打开 index.html (如果 app 有请求操作,需要起本地服务器查看),再检查一下就可以发布了。
这个过程中发生了什么?
好奇的同学看到这里可能会有一些疑问,上面命令行工具的一些命令做了什么事情?为什么 React web 将 React Native 代码打包出一份用在 Web 端的代码?React web 安全可靠吗,里面都是什么东西?
这里简单的介绍下 React web 的实现原理和上面步骤实际做的事情。
React Web 将 React Native 组件做了 Web 端的实现
React 将代码与平台环境分离,多了一层,这样开发者可以在平台环境层面做一些处理,使得同样一份代码适应更多的平台环境等。
比如 react-canvas 按照 React 的语法书写代码,在平台环境层面做一些处理(将你 React 代码运行并用 canvas 渲染),然后实现特定目标(在移动端提高性能)。
React Native 中,一份代码能同时跑在 iOS 和 Android 上面,也是一样的道理。React Native 团队在对应平台的 Native app 上面做了一些处理,使其可以解析执行 React 语法的代码。
还有同构(isomorphic)的应用,服务器端使用 React + Node.js 生成 HTML,客户端使用 React 获取进行客户端相关交互和功能,也是一样的道理。
为此, React v0.14.x 版本开始,专门分成两个库 react 和 react-dom ,其实是把对浏览器平台的特殊处理剥离了出来,单独变成了 react-dom 库。
React Native 比较特殊的地方在于,组件最底层的实现是 Native 的实现,所以就不支持 span、div 等标签。而动画等,也是直接调用 Native 进行界面渲染。所以不支持 Web 端,但是绝大部分组件,都是可以用 Web 技术进行模拟实现。动画可以用 CSS3 、基础元素可以用同等 HTML 标签模拟、布局以及兼容性问题可以用 CSS 来处理,所以 React web 只需要把 React Native 的组件用 Web 技术重新实现一遍,借助 React 这一层,即可实现一份代码运行在多个平台上面。
举一个非常简单的例子,Text 组件:
React Native 的实现 是调用了很多 React Native 底层的代码实现的。
对于 Web 端,输出一行文本使用 标签即可,所以 React web 的实现 就直接搞一个 标签,绑一些事件什么的就 OK 了。
在 UI Explorer demo 中能跑起来的 React Native 组件,你都可以放心的用。
webpack 帮你切换打包目标
做出了兼容 Web 端的组件,那打包的时候岂不是要把所有要打包的组件中的 require('react-native') 全部更换成 require('react-web')?不然怎么用的我的 Web 组件打包?
强大的 webpack 附带了 alias 配置项可以帮你解决这个问题:

resolve: {
 alias: {
 'react-native': 'react-web',
 'ReactNativeART': 'react-art',
 },
 extensions: ['', '.js', '.jsx'],
},

这样在打包时,但凡 require('react-native') 的地方全都用 react-web 包替换,而 react-web 的 module.exports 与 react-native 的保持一致即可让代码不替换也可以工作。
此外配合插件还可以实现另外一种引入方法,请看下面。
通过 Haste 方法引入组件以提高性能
webpack 以及其他的支持 CommonJS 规范的打包工具,都会把文件中 require 的所有组件都打包在一起。对于 React Native 来说代码体积大小无关紧要,而在 Mobile web 来说,就要稍微重要一些了。特别是如果你的项目只需要 Text 组件,但由于 require('react-web') 结果把所有的组件全部打包进来了,就比较伤感。
基于 webpack 插件,还可以用另一种方式引入组件以解决这个问题,你可以叫它 Haste 方式。使用这种方式需要加载 webpack 插件 haste-resolver-webpack-plugin,默认的 webpack 配置已经帮你加载好了,你可以直接在组件里面这样用:

var Text = require('ReactText');

而不是以前那样:

var {Text} = require('react-native');

这样 webpack 打包时,对于前者,只会把那一个组件内容打包进来,因此可以减小体积、提升性能。这是怎么实现的呢?
加载了插件的 webpack 打包时,会先扫描所有组件并读取组件头部 @providesModule 的信息(比如 Text 组件的信息),然后当其他文件中 require 了这个组件名称,就会自动定位到这个文件进行打包。同时还可以区分平台,即便是同一个名字,打包时会区分平台去打包对应的文件(根据 index.xxx.js 的命名规则确定文件)。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
author-avatar
adu
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有