备注
这是很久以前保存的文件,将原始的内容放到这里以备不时之需。
目录
1. 为什么要使用RN
1. 编程人员永远的梦想
1. 一次编写,到处运行之路
1. C/Java/Qt
2. write once, run everywhere
2. learn once, write everywhere
1. Chrome撑起的梦想
1. Electron/Chrome App
2. virtual-dom
1. 虚拟dom
3. React
1. Web
2. Native
2. 屏蔽了底层代码, 学习成本低
1. 我的全栈工程师之路 => 21天精通React
3. 快速发版
4. 性能优势
5. 为什么不用Weex
1. 池建强的博客截图
2. React Native Init
1. 初始框架的搭建
1. react-native init jumeiReactNative
2. 多项目的改造
1. 引入
3. React Native 工具包
1. Chrome Developer Tools
2. react-devtools
1. 安装时需要在npmrc中指定electron地址: `ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/`
3. React Native工程化
1. 配置系统(接口开关)
1. 平台控制
1. 项目开关
1. 总开关
1. 失败次数控制
1. 系统版本控制(Android/iOS)
1. Rom版本控制(安卓定制系统, iOS具体版型(iOS6/7/8))
1. 客户端版本控制
1. CPU版本控制
当检测到可以开启RN后, 由客户端下载bundle包
2. Module同步(bundle包下载)
1. 调用接口,获取最新bundle列表
1. 依次检测本地是否已下载过bundle包
检测标准:
1. 文件名相同
1. 版本号相同
1. 文件签名相同
未下载 => 启动下载流程
1. bundle下载
1. 下载失败
1. 网络异常
1. 存储空间不足
1. 解压缩失败
1. 校验不通过(文件hash不对, 文件名不对)
1. 下载成功
1. 校验并保存文件
已下载 => 跳过
3. 启动RN
1. 本地是否有对应bundle
1. 存在 => 载入bundle
1. RN启动
1. 活动流程是否正常(日常测试)
1. 原生通信是否正常, 是否可以正常调用原生功能(RN项目测试)
1. 检查调用原生功能情况
1. 页面跳转,返回,读取本地存储,本地通知,Dialog,Toast弹出
2. 不存在 => 降级启动H5页面
2. 日志记录与上报
3. 测试过程中的Tips
4. 爬坑之路
2. 按路径引入
3. setState
5. 资源推荐
1. [React Native标准文档](http://reactnative.cn/docs/0.51/getting-started.html)
2. [React Native小书](https://hydrographer-vivian-23728.netlify.com/)
4. [React 样式表手册](https://shenbao.github.io/ishehui/html/RN%20%E5%9F%BA%E7%A1%80/React%20Native%20%E6%A0%B7%E5%BC%8F%E8%A1%A8%E6%8C%87%E5%8D%97.html#)
5. [React Native动画进阶(中文版)](https://future-challenger.gitbooks.io/react-native-animation/content/)
3. [构建 F8 App / 官方React Native 开发指南](https://f8-app.liaohuqiu.net/tutorials/)
6. [Redux 中文文档(劝退指南)](http://cn.redux.js.org/)
6. 劣势
1. 还处于快速发展期, 频繁更新
2. 性能和原生页面毕竟还是有差距, 不能绘制过于复杂的动画
正文
大家好, 今天由我和孙阳来为大家做一下React Native的分享. 在这次的分享里, 我会先简单介绍一下React的相关知识和选用React Native的原因, 然后由孙阳来为我们详细介绍下React Native具体的工程化过程, 最后会介绍一些项目实施中遇到的坑和相关的学习资源.
让我们先从React开始. React是Facebook编写的一套前端框架. 在React之前, 大家写HTML的思路是按标签去写, p标签a标签之类的, 然后如果想写一个复杂点的功能的话就需要把这些标签全都摞起来, 一个个的调位置. 这种思路在标签量小的情况下还好, 但是标签量一大就会很难办, 一大坨标签密密麻麻挤一堆, 谁都维护不了. 当然了, 在真实工作中碰到这种问题我们也是有解决办法的, 就是结构化编程, 把标签按功能拆分开, 每个功能区之间互相独立互不影响, 这样一个页面无论再怎么复杂, 都可以通过拆分的方式把它分成一个个的小块, 我们只要组织好这些小块就行了. 如果我们再给这些小块起一个专用的名字, 比如说组件 => vue1.0 就诞生了. 但为什么这个思路只是vue1.0 不是React呢, 因为在我们刚才的构想里, 组件和网页元素标签还是一一对应的, React比这更近一步, 他在组件和元素标签之间引入了一层虚拟dom, 组件被映射成虚拟的dom结构, 然后再由框架将这些虚拟的dom元素转换成真正的HTML标签列表.
ok, 关键的地方来了. React的界面是由组件构成的, 而我们知道安卓和iOS的界面也都是由和组件类似的控件构成的, 那么, 有没有可能利用虚拟dom这个中间层, 把React的组件给转换成安卓和iOS的组件呢?如果再加上底层库的配合, 让js可以请求网络/存储数据/触发弹窗/记录日志的话, 对于纯数据的展示, 是不是就可以直接用React去写了呢? 当然, 这些问题我们现在都已经知道答案了, 2015年4月, React Native第一版上线, React开始支持iOS平台, 2015年9月, React Native正式支持Android的开发. 至此, 如果你会写React的话, 相当于你不光能写网页, 同时也能写Android和iOS的应用.
而且问题在于, 跟iOS和Android开发比起来, React确实要更简单. 如果你是一个原生开发人员, 系统自带的数据库存储要会, 文件系统结构要会, 进程线程模型要知道, 事件模型要知道. 但是如果只是为了展示数据进行交互的话, 根本不需要了解这些系统底层的知识, 只要知道展示文本用Text组件, 展示图片用Image组件就够了. 而且, React发版速度也很快. 因为React 项目就是一个js文本文件, 发版的时候只要把这个文本文件传到网上, 更新下配置就可以.
总结一下: 对于展示页面来说, React 技术栈 入门简单, 开发效率高(一次编写, 三端运行), 发版速度快, 作为技术人员我们实际上没什么理由不用React. 当然, 有同学可能会问, Vue技术栈下边也有和React Native相同的Weex, 为什么我们不直接沿用现在前端的技术栈, 而是要用一个全新的React技术栈呢. 这就是React 的另一项优点了: 社区大,坑少.
React 2013年首次对外发布, 15年推出Native框架, 现在京东, QQ, 去哪儿都在大量使用React Native相关的技术栈, 可以说是一套比较成熟的框架了. 但是基于Vue的Weex, 这个, 也不多说啥. 前段时间极客邦基于Weex推出了一款App, 这是他们在结项后的感谢辞: 感谢Weex团队, 感谢张小龙帮忙协调资源, 然后在这么强的支持下, 极客时间项目整体延期, 10月17号iOS上线, 12月8号安卓才发布上线...然后, 如果我们的人脉没有那么强, 请不动张小龙, 也找不到Weex开发组, 然后这样的话, 你们都懂.
介绍完React Native, 我们来讲下它的具体使用.
首先当然是执行react-native init jumeiReactNative
初始化项目, 然后npm install
安装依赖, react-native run-android
启动debug模式. 这些官网上都有, 我这儿就不多说了.
重点要介绍的是这两个地方:
- 首先, 我们来看下RN的代码, 他这个就是React的代码, 没有其他多余的东西. 也就是说, React Native确实像他描述的一样, 只要会写React 就能写React Native. 没有其他学习成本
- 因为React Native的代码只是一层皮, 他的本质是被编译好了的, 随时可以修改的js, 因此React Native的代码可以和普通的js代码一样调试, 而且还可以直接在Chrome浏览器里打日志, 单步调试. 就像这样(开启远程调试功能, 展示Chrome浏览器下的日志打印和单步调试功能)
- 除了这些, 我们还可以直接用react-devtools查看组件的效果(展示react-devtools的效果). 不过这里有个小坑, 因为这个工具用到了electron, 而electron的安装地址又被国家屏蔽了, 所以安装工具的时候经常会因为网络异常失败. 所以我们需要在系统的npmrc配置里指定electron的安装源才行.
- 然后顺带讲一下, 他这里的electron实际上跟我们的RN是一样的, 也是提供一个壳, 然后里边实际跑的是js代码. 比如现在前端开发常用的VS Code 编辑器, 实际上就是用Chrome浏览器加上HTML画出来的. 15年之后各种桌面系统的原生开发在事实上已经停滞了, 现在新出的软件都是用js+chrome浏览器外壳去实现. React Native其实只是这种浪潮下的一个分支而已.
然后, 关于RN的基础知识已经讲的差不多了, 下面让我们请孙阳来为我们介绍下聚美RN的具体实施过程.
孙阳部分
ok, 孙阳分享完了测试的要点, 我来分享下RN项目在开发时的一些坑.
先是一个小坑:
- 按路径引入
- react-native里有一个小问题, 就是它默认只能用相对路径去引入模块. 这样就意味着我们在写代码的时候要写一大堆的"../.."去回到根目录, 而且代码目录越深".."就用的越多, 写起来非常恶心.
- 不过RN提供了一个hack的方式, 就是我们可以通过在指定目录下添加一个package.json的文件来给一个目录指定模块名, 比如, 我们可以在src目录下添加一个package.json, 内容是
{ "name": "src" }
, 这样src这个目录就会被RN识别为src模块, 以后引用的时候就可以直接引了 - 之所以说这是一个坑是因为这个解决方案在中文网络里没有, 是在Github的一个issue里找到的, 所以专门提一下
然后有一个状态管理的大坑.
RN的样式展示和逻辑代码是分属与两个线程的. 当逻辑线程更新了组件状态, 样式展示代码就会根据新状态去渲染组件. 这个看起来没什么问题, 但是在实践的时候出现了这种情况, 就是: 逻辑线程在更新完状态之后自动退出, 然后RN所在的Activity也跟着被回收了回去, 这里没问题, 但是因为线程之间的消息不同步, 然后轮到样式展示线程的时候展示线程看到状态有更新, 就直接去更新组件, 但是组件又不存在, 导致代码Crash.
这其实很坑,因为检测组件存不存在这种事属于脏活,而且也是基础功能, 应该由框架自己负责.我当时没想到RN发展了两年连这个功能都没做,所以也没忘这块考虑, 导致这一个bug找了半天. 不过这个bug最后是这么解决的: 我们加了一个onMounted信号量, 组件载入就设成true, 组件销毁就改成false, 然后在每次更新状态和更新组件前都检测一下这个信号量, 如果为false就直接返回.这样才算是解决了.
最后一点就是性能问题. 前面说了, RN虽然最后会被翻译成原生代码进行执行, 但是毕竟经过了一层虚拟dom中间层, 导致他的性能肯定会比真正的原生要差一点.因此RN不适合展示复杂的动画, 这点需要注意.
好了, 最后再介绍一下RN的学习资源
首先是官方文档, 这个不用说了, 从搭建环境到实际开发, 肯定要经常翻看的.
然后是React Native小书, 这是一本由中国开发者写的RN介绍, 建议搭建完环境后就直接看这本书, 在引领入门方面写的比文档要好.
然后是RN支持的全部样式表和RN的动画手册, 这块前端同学在开发的时候肯定要翻的.
最后是一个Facebook官方的示例代码, 和Redux使用指南. 官方示例这个就不说了, 直接看就行. Redux这个要说一下. 一般来说大型React系统都需要上Redux去管理组件的各种状态, 但是如果是小项目的话, 文档和我的建议都是不要上这个, 对于我们平常用的小页面来说, 它带来的复杂度的提升会远远大于引入他所能获得的在开发效率上的收益.
我们的分享讲完了, 谢谢大家