本文介绍ReactNative入门相关知识, 包含一下知识点
没有完美的跨端技术,只有适合的场景
RN
App
上Weex
最终未能大规模流行起来,Flutter
使用的语言是 Dart
而非 JavaScript
,并不能很好支持动态更新React Native
是一个非常流行的跨端框架,开发者认可度很高 npm trends上面RN
增长势头强劲React Native
是一个跨领域的融合技术,它是你现有技术的自然延伸。React Native
新架构 与2022
年已经发布Hermes
是一款专为移动端打造的 JavaScript
引擎,它支持 JavaScript
的 AOT
预编译。node.js
使用 addon
调用 C++
、 Flutter
用 FFI
调用 C++
,以及 Java
使用 JNI
调用 C++
一样。Airbnb
的自行研发服务端渲染框架原理非常类似React Native
老架构之上实现了 SSR
,据说美团的页面渲染速度最快能达到 50ms
。首先贴出 官方文档
官方写的很文章很详细完整,我不再累赘。建议严格按照官方文档一步一步操作(比如jdk
安装了其它版本,作为外行人很难定位问题,这样学习效率不高)。推荐 完整原生环境
我使用的是苹果电脑,本文也是讲解MacOS 系统下RN环境安装问题(一般RN开发都是用mac
电脑,虽然window
电脑可以通过安装虚拟机xcode
来解决ios
构建问题,但该方案比较偏,问题也多)
但由于众所周知的原因,国内用户会遇到各种奇奇怪怪得问题。我这里记录一下我在安装过程中遇到的问题及解决方案,供参考。
作为前端node
安装不用说了(其它nvm
、yarn
/npm
、 nrm
/yrm
等可以参考我的其它文章,这里不说这些)
补充一些墙问题的解决方案
ClashX
客户端,参考网上的教程mac
顶部状态栏 ClashX
图标 打开本地配置文件,第一行就是 mixed-port: 7890
推测这个就是端口export ALL_PROXY=socks5://127.0.0.1:7890
curl -vv https://www.google.com
命令,验证是否解决命令行墙问题为什么我的终端可以翻墙 却有些包还是下载不了?
ping github.com
控制台日志 Request timeout for icmp_seq
表示丢包,网络不通,github.com
得到 ip 为140.82.113.4
配置host 140.82.113.4 github.com
,再次使用ping github.com
测试,网络已通。(pod install
安装失败,可以用此方案解决)安装失败问题
pod install
安装失败,再次执行会从上次下载失败的包处开始重新下载)brew
问题
brew install watchman
或 brew update
等阶段,可能会遇到的报错信息 Error: homebrew-core is a shallow clone
。homebrew
Xcode 安装问题
app store
里xcode
一直转圈,过一会提示 “无法下载请稍后再试”xcode
链接这里 过了一会下载完成解压后拖拽到应用 覆盖原有的xcode
,至此xcode
安装成功watchman
问题
yarn ios
或yarn android
时报错,即使在安装时正常 ,也可能第二天你执行yarn ios
或 yarn android
时报错,报错内容为ios
或anroid
机器(这里的机器包含真机或模拟器)上 还会看到全屏报错Document
目录移出,可以移动到 ~/**
目录 (~/
是用户主目录)cocoapods
问题
brew install cocoapods
失败,可以用sudo gem install cocoapods
试试看,iOS项目问题排查
yarn ios
./ios
目录 双击.xcworkspace
文件,在xcode中打开项目补充一些知识点:
Watchman
由 Facebook 提供的监视文件系统变更的工具Xcode
苹果生态应用开发唯一工具,这里开发ios app 就有用的xcode构建CocoaPods
IOS包管理器,命令行pod
, 可类比web前端的npmHomeBrew
macOS的套件管理工具,命令行brew
,可以类比unbuntu的apt-get
或centos的yum
Metro
它是RN的打包工具,类比web前端的webpack
首先补充下android相关知识背景
jdk
与jre
的关系
jdk
是java
开发工具,编译java
文件为二进制文件(.classes
);jre
是java
运行时环境- 查看
jdk
版本java -version
; 查看jre
版本javac -version
; 查看jdk
路径which java
orwhereis java
- 卸载
java sudo rm -rf /Library/Java/JavaVirtualMachines/jdkxxx.jdk
gradle
这里可以理解为 android项目构建工具, 可以把它看作保姆,下载资源并配置,可以写动态脚本。包含maven
的功能,maven
/pox.xml
可类比web前端的npm
/package.json
Android Studio
android
开发官方推荐的JIDE
Android Studio
内置了很多东西(jdk
、模拟器、adb
等)- 其中有接触过android webview 调试的同学可能了解
adb
,如果你想使用adb
命令可以使用IDE
内置adb
yarn android
如果严格按照官方文档来,android环境的安装会比较顺利
jdk
再配置IDE
,如果你先安装配置了IDE
,系统会自动为你安装jdk
,此时你使用yarn android
是跑不起来的。jdk
按官方文档安装jdk
,然后删除项目重新安装npx react-native init AwesomeProject
,最后在执行yarn andriod
才能正常跑起项目模拟器运行
error Failed to launch emulator.
或者 > Task :app:installDebug FAILED
adb device
检测设备, 如果没有 则打开Android Studio
删除设备, 在重新创建adb devices
检查电脑是否识别手机,只要能识别到手机就能真机运行!假设经过上面的前面的折腾,你也像我一样成功把脚手架跑起来了。
万事开头难,环境搭建多折腾
最早期的版本叫做热重载 HotReload
基于Webpack的模块热替换原理开发的
2) Metro收到通知就会编译涉及到的更新文件
3) 编译完成会生成一个用于更新的bundle文件
4) 本地服务会通过socket通知客户端
5) 客户端请求资源
6)服务端响应bundle,客户端在原来的RN应用的JS执行上下文中运行更新的bundle
基础的模块热替换只能实现组件级别的强制刷新,而组件的状态会丢失,如何复用组件的状态呢?
RN在运行时,用“代理”的方式管理新旧组件的切换
原生视图会复用吗?
肯定复用,RN组件进行render时判断是否需要创建原生视图,通过浅层比较决定是否复用原生视图。
当然,并不是所有情况都会复用状态和原生视图。
对于函数组件来说,hooks 的顺序非常重要, 如果hooks顺序有变化,会丢弃原先状态,新建原生组件
对于类组件 只要是类组件的代码发生更新,组件的内部状态都要重新初始化。
建议:尽可能地拥抱函数组件,放弃类组件。
默认的脚手架启动后,页面展示的是调试文档和学习指引文档。
调试文档如下:(以下操作前提是选中模拟器)
Command + M
(android模拟器)/Command + D
(ios模拟器) 或摇晃手机(真机) 弹出开发者菜单选项 (android机还可以通过adb shell input keyevent 82
)几种调试方法的对比
Terminal
调试
chrome
调试Flipper
Facebook 出 。它的功能很强大,打日志、打断点、查看元素树、抓包请求、查看存储它都支持,而且支持扩展插件。凑合参考这篇《用Flipper调试React Native应用程序》文章吧
与环境搭建一样,坑很多。。。
这里记录一下步骤和踩坑点
brew install --cask flipper
注意命令行要翻墙,否则安装不了flipper
会有警告 “不明开发者,,移到废纸篓”, 千万别移到废纸篓, 在 mac偏好设置--》安全与隐私--》点击仍然打开flipper
, 这时要检查环境配置放心没那么顺利,上图是我处理后的
SDK Installed
要选择路径,可以查AndroidStatio
的设置,我的配置为flipper
的 React DevTools
和Logs
调试 (亲测android模拟器和ios模拟器有效)adb devices
adb install -r xx.apk
adb reverse tcp:8081 tcp:8081
adb shell
进入沙盒类linux命令行环境adb push 1.png /sdcard/
copy电脑文件到手机adb pull /sdcard/1.png ./
从手机中copy文件到电脑txtandroid |-app |- src |- main |- AndroidManifest.xml |- java |- mainApplication.java |- res |- minmao-hdpi / minmao-mdpi 应用图标 |- minmao-xhdpi / minmao-xxhdpi / minmao-xxxhdpi |- values |- string.xml 修改应用名称 |- build.gradle |- build.gradle
AndroidManifest.xml
外层build.gradle
大概率改不到
内层build.gradle
mainApplication.java
Java
/ Kotlin
OC
vs Swift
.jks
build.gradle
文件中的releasePUSHY
RN中文网推荐Code Push
由于墙的原理网速比较慢,第二体检热修复包的设计思路
RN的本质只克隆了一份React并对react-dom进行了重写
用一张图对比下webview壳与RN两种混合开发上的差异
老架构的核心问题是JSBridge
的性能瓶颈
UI Manager
React创建FiberTree
后会通过bridge再渲染原视图组件,这块开销也大新架构使用JSI 替换了Bridge
,我们先来看一下架构图
JSI
JSI 是一个轻量级的通用层,用C++编写,JS引擎可以使用它直接执行或者调用native。
JSI 如何让 JavaScript 直接调用到原生方法?
在 JSI
里 Native
方法会通过 C++
Host Objects
暴露给 JS
, 而 JS
可以持有对这些对象的引用,并且使用这些引用直接调用对应的方法
Fabric
Fabric
是新的渲染系统,它将取代当前的 UI Manager
。
使用新的 Fabric
渲染,用户交互(如滚动、手势等)可以优先在主线程或 Native
线程中同步执行,而 API
请求等其他任务使用异步执行。
另外新的 Shadow Tree
将成为 immutable
,它会在 JS
和 UI
线程之间共享,以两端进行直接交互。
Turbo Modules
Turbo Modules
基本上是对这些旧的 Native 模块的增强。
仅在需要时才加载对应模块,这样可以将显着缩短 RN 应用的启动时间。
Codegen
Codegen
主要是用于保证 JS
代码和 C++
的 JSI
可以正常通信的静态类型检查器,通过使用类型化的 JS
作为参考来源,CodeGen
将定义可以被 Turbo
模块和 Fabric
使用的接口,另外 Codegen
会在构建时生成 Native
代码,减少运行时的开支。
总结
本段参考资料
本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!