最近前同事問(wèn)我react-native方面的問(wèn)題,幾年前我粗略地學(xué)習(xí)過(guò)react-native的開(kāi)發(fā),時(shí)至今日,差不多又還回去了。于是就搜索react-native方面的文章看。看到這篇文章,對(duì)評(píng)論區(qū)一個(gè)掘友的留言很好奇,這款用react-native開(kāi)發(fā)的仿掘金APP的應(yīng)用,界面到底長(zhǎng)什么樣子?文中的作者并沒(méi)有截屏展示。于是打算把文中的項(xiàng)目下載下來(lái),運(yùn)行一下,看看效果。過(guò)程沒(méi)有我想得那么順利,一波三折,踩了一些坑,好在最后跑起來(lái)了,在Android Studio模擬器中的運(yùn)行效果如下圖所示。現(xiàn)在我們回溯一個(gè)過(guò)程,把遇到的問(wèn)題的解決方法給大家分享一下。
npx react-native init react-native-junjin
生成的目錄結(jié)構(gòu)如下圖所示:
react-native-junjin/
├── __tests__/ // 測(cè)試目錄,包含測(cè)試文件
├── android/ // Android 項(xiàng)目的原生代碼
├── ios/ // iOS 項(xiàng)目的原生代碼
├── node_modules/ // Node.js 模塊目錄,包含所有依賴包
├── .eslintrc.js // ESLint 配置文件,用于 JavaScript 代碼風(fēng)格檢查
├── .gitignore // Git 忽略文件配置
├── .prettierrc.js // Prettier 配置文件,用于代碼格式化
├── .watchmanconfig // Watchman 配置文件,用于監(jiān)視文件變化
├── App.tsx // 主要的 React 組件文件,使用 TypeScript 編寫
├── app.json // 應(yīng)用的配置文件
├── babel.config.js // Babel 配置文件,用于 JavaScript 轉(zhuǎn)譯
├── index.js // JavaScript 入口文件,注冊(cè)根組件
├── metro.config.js // Metro bundler 配置文件
├── package.json // 項(xiàng)目的包管理配置文件,定義項(xiàng)目依賴及腳本
├── README.md // 項(xiàng)目說(shuō)明文件
├── yarn.lock // Yarn 鎖定文件,確保依賴版本一致
├── .bundle/ // 這個(gè)文件夾通常包含打包配置和緩存,用于優(yōu)化打包過(guò)程
├── Gemfile // Ruby 的依賴管理文件,,通常與 CocoaPods 一起使用,以管理 iOS 項(xiàng)目的依賴。
├── jest.config.js // Jest 配置文件,用于測(cè)試設(shè)置
├── tsconfig.json // TypeScript 配置文件
└── .yarnrc.yml // Yarn 配置文件,定義 Yarn 的行為
別的文件都好理解,對(duì)于初學(xué)者,可能不知道Metro和Gemfile是干什么的。
Metro 是 React Native 項(xiàng)目中開(kāi)發(fā)工具鏈的重要組成部分。Metro 是 React Native 的 JavaScript 打包器,將所有的 JavaScript 文件打包成一個(gè)或多個(gè)文件,以便應(yīng)用程序可以在設(shè)備或模擬器上運(yùn)行。它會(huì)解析項(xiàng)目中的依賴關(guān)系樹(shù),將所有依賴項(xiàng)捆綁在一起,生成一個(gè)高效的包。它具有快速增量構(gòu)建、熱重載和代碼拆分等功能使得開(kāi)發(fā)過(guò)程更加高效和便捷。項(xiàng)目的根目錄下有一個(gè) metro.config.js 文件,用于配置 Metro 的行為。這個(gè)文件可以包含如下配置:
配置示例:
module.exports={
transformer: {
babelTransformerPath: require.resolve('react-native-typescript-transformer'),
},
resolver: {
sourceExts: ['jsx', 'js', 'ts', 'tsx'], // 支持的文件擴(kuò)展名
},
};
Gemfile 在一個(gè) React Native 項(xiàng)目中,Gemfile 通常用于管理 iOS 開(kāi)發(fā)所需的 RubyGems。RubyGems 是 Ruby 的包管理系統(tǒng),Gemfile 的主要作用是列出項(xiàng)目所依賴的所有 gems(RubyGems所管理的包或者依賴,我們稱之為 gem),并確保在不同環(huán)境下這些依賴項(xiàng)的一致性,其中一個(gè)比較重要的gem是 CocoaPods,這是一個(gè)流行的依賴管理器,用于管理和集成 iOS 項(xiàng)目的第三方庫(kù)。
一個(gè)典型的 Gemfile 文件結(jié)構(gòu)如下:
# 指定 gem 的源,這通常是 `https://rubygems.org`,這是官方的 RubyGems 倉(cāng)庫(kù)
source "https://rubygems.org"
# 指定 Ruby 版本
ruby ">=2.6.10"
# 指定項(xiàng)目所需的 gem 及其版本
gem 'cocoapods', '>=1.13', '< 1.15'
gem 'activesupport', '>=6.1.7.5', '< 7.1.0'
# 可以定義不同的組,例如開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境
group :development, :test do
gem "rspec"
end
先介紹一個(gè)檢測(cè)工具react-native doctor ,它是 React Native 開(kāi)發(fā)環(huán)境中一個(gè)非常有用的命令行工具,能幫助開(kāi)發(fā)者檢測(cè)和修復(fù)本機(jī)系統(tǒng)中的各種開(kāi)發(fā)工具和依賴項(xiàng),確保安裝正確且版本合適。會(huì)檢查 Node.js、yarn, Metro,JDK,Android Studio、Android SDK,Xcode 以及其它相關(guān)工具,并提供自動(dòng)修復(fù)問(wèn)題的選項(xiàng)。如果 doctor 無(wú)法自動(dòng)解決問(wèn)題,它將顯示消息和鏈接,說(shuō)明如何手動(dòng)修復(fù)此問(wèn)題。
執(zhí)行下面的命令,就會(huì)開(kāi)始檢查React Native開(kāi)發(fā)依賴的大多數(shù)軟件和工具是否正確安裝且版本正確
npx react-native doctor
這是檢查結(jié)果,因?yàn)楣P者已經(jīng)安裝好了各種軟件和工具,所以只有一項(xiàng)是打叉的。這一項(xiàng)打叉是因?yàn)闆](méi)有在Android Studio中啟動(dòng)模擬器。
要在PC端運(yùn)行一下Android應(yīng)用,如果你是初學(xué)者,百分之百會(huì)遇到一些跟Android平臺(tái)相關(guān)的專業(yè)名詞如JDK、Android Studio,Android SDK,Gradle、Gradlew,不知道這些名稱概念的含義的話,就算效果運(yùn)行正確,也不代表你會(huì)了。別人對(duì)你談起這些名詞,你會(huì)感覺(jué)一頭霧水,不知所以然, 無(wú)法與別人交流。所以我們先夯實(shí)一下基礎(chǔ),了解一下這些名詞概念。
在 React Native 和 Android 開(kāi)發(fā)中,JDK、Android Studio、Android SDK 和 Gradle 是幾個(gè)核心組件,它們之間相互關(guān)聯(lián),為開(kāi)發(fā)和構(gòu)建 Android 應(yīng)用提供完整的支持。它們各自的功能和彼此的關(guān)系如下:
總結(jié)一下就是:
它們共同構(gòu)成了 Android 應(yīng)用開(kāi)發(fā)和構(gòu)建的完整工具鏈,相互依賴且緊密集成。
ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
去Oracle官網(wǎng),下載win版的jdk安裝包 。注意版本jdk版本,doctor提示jdk的版本必須是>=17,<=20, 去官網(wǎng)一看, 只有22,21,17三個(gè)版本可以下載,那只能選擇jdk17。衍生問(wèn)題-jdk下載過(guò)慢。解決方法: 將下載鏈接的協(xié)議頭由https改成http,由于下載時(shí)默認(rèn)是https,所以會(huì)慢一些,使用http之后會(huì)好很多,速度能穩(wěn)定在400k左右,十分鐘之內(nèi)就可以下完,速度還可以。另外,配置JAVA_HOME環(huán)境變量的時(shí)候,路徑后面不能帶bin。
安裝Android Studio時(shí),直接搜索Android Studio下載地址,去官網(wǎng)下載,發(fā)現(xiàn)國(guó)內(nèi)用戶直接下載不了。訪問(wèn)這個(gè)地址,界面的語(yǔ)言默認(rèn)是英文,卻可以正常下載,默認(rèn)打開(kāi)的Android Studio頁(yè)面語(yǔ)言是中文的話,就下載不了。莫非是美國(guó)佬不讓大陸開(kāi)發(fā)者使用Android Stduio.
安裝好Android Studio之后,需要?jiǎng)?chuàng)建一個(gè)模擬器。就不會(huì)報(bào)這個(gè)錯(cuò)誤了。Android模擬器查看和啟動(dòng)方法
emulator -list-avds
emulator -avd 模擬起名稱
用 java -version命令查看發(fā)現(xiàn)返回為空,是因?yàn)榘惭b了兩個(gè)版本的JDK所致。一個(gè)是本次在Android Studio安裝中,一個(gè)是以前手動(dòng)安裝的。要?jiǎng)h除一個(gè)。刪除jdk時(shí),搜索的應(yīng)用名稱應(yīng)該是Java,此外,手動(dòng)刪除JDK的安裝目錄文件,是不行的,必須用系統(tǒng)的軟件卸載功能進(jìn)行卸載。
安裝Android Studio時(shí)不要自定義安裝路徑,安裝到默認(rèn)路徑。
出現(xiàn)這個(gè)報(bào)錯(cuò)是因?yàn)橄螺dgradle-8.6-all.zip包超時(shí)引起的,可以修改一下項(xiàng)目根目錄下的 android\gradle\wrapper\gradle-wrapper.properties文件配置,把gradle的下載路徑改成本地路徑,然后手動(dòng)下載這個(gè)壓縮包,放到配置的本地路徑中。
distributionUrl=gradle-8.6-all.zip
這個(gè)錯(cuò)誤的意思是在 Gradle 構(gòu)建過(guò)程中,嘗試將臨時(shí)工作空間移動(dòng)到最終位置時(shí)出錯(cuò),錯(cuò)誤原因通常與文件系統(tǒng)權(quán)限或路徑問(wèn)題有關(guān)。默認(rèn)配置下載的gradle-8.6-all.zip會(huì)報(bào)這個(gè)錯(cuò)誤,將gradle工作包降級(jí)為gradle-8.5-bin.zip后,此問(wèn)題消失。
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
操作菜單路徑 File==> Settings==> Languages & Frameworks==>Android SDK==>Edit,如下圖所示。
SDK安裝目錄為:
C:\Users\Administrator\AppData\Local\Android\Sdk
如果用pnpm安裝會(huì)出現(xiàn)這個(gè)問(wèn)題,用yarn安裝則不會(huì),因?yàn)閥arn會(huì)安裝自動(dòng)隱式依賴。
Settings file 'D:\juejin-main\android\settings.gradle' line: 2 apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) Could not read script '項(xiàng)目路徑\node_modules@react-native-community\cli-platform-android\native_modules.gradle' as it does not exist.
補(bǔ)充安裝這兩個(gè)包
pnpm add -D @react-native-community/cli-platform-android @react-native/gradle-plugin
What went wrong: A problem occurred configuring project ':react-native-screens'. [CXX1101] NDK at C:\Users\Administrator\AppData\Local\Android\Sdk\ndk.1.10909125 did not have a source.properties file
Android NDK(Native Development Kit)是一個(gè)工具集,允許開(kāi)發(fā)者使用 C 和 C++ 代碼來(lái)構(gòu)建 Android 應(yīng)用程序的一部分。NDK 提供了構(gòu)建和打包原生代碼的工具和庫(kù),幫助開(kāi)發(fā)者創(chuàng)建高性能的應(yīng)用程序,尤其是在涉及到計(jì)算密集型任務(wù)時(shí),如游戲、圖形處理和信號(hào)處理等。
通過(guò) Android Studio 安裝 NDK,操作步驟:
注意下載版本要與報(bào)錯(cuò)的NDK版本保持一致。
解決方法:修改項(xiàng)目下的android\build.gradle項(xiàng)目依賴項(xiàng)的像源地址。添加阿里云鏡像地址,并配置在前面,優(yōu)先使用。
buildscript {
// 定義了 Gradle 構(gòu)建腳本所需的依賴項(xiàng)應(yīng)該從哪些存儲(chǔ)庫(kù)中獲取。常見(jiàn)的存儲(chǔ)庫(kù)有 `google()` 和 `mavenCentral()`。
repositories {
maven { url "https://maven.aliyun.com/repository/public" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/google" }
google()
jcenter()
mavenCentral()
}
// ...
}
allprojects {
// 定義了所有子項(xiàng)目在解析依賴項(xiàng)時(shí)使用的存儲(chǔ)庫(kù)
repositories {
maven { url "https://maven.aliyun.com/repository/public" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/google" }
google()
jcenter()
mavenCentral()
}
}
apply plugin: "com.facebook.react.rootproject"
沒(méi)動(dòng)手實(shí)踐之前,本以為依葫蘆畫瓢,能很快把效果做出來(lái)。實(shí)際在做的時(shí)候,發(fā)現(xiàn)自己把這件事想得簡(jiǎn)單了。在運(yùn)行項(xiàng)目的過(guò)程中,出現(xiàn)了許多報(bào)錯(cuò),上面的這些問(wèn)題我把解決方法都記錄下來(lái)了,有些也遺漏了。我踩過(guò)的坑,希望你看完這篇文章之后,就不要再重蹈覆轍了。這樣才能體現(xiàn)出你閱讀本文的價(jià)值。還有就是看完一篇技術(shù)文章,不能看一看就覺(jué)得自己會(huì)了,最好動(dòng)手做一做。有許多潛在的技術(shù)問(wèn)題在看的過(guò)程中是無(wú)法暴露出來(lái)的,你以為你會(huì)了,實(shí)操的時(shí)候還是會(huì)遇到一大堆問(wèn)題,平時(shí)有時(shí)間的話要提前掃雷, 這樣將來(lái)遇到相關(guān)問(wèn)題時(shí)就不會(huì)手忙腳亂。
原文:https://juejin.cn/post/7382891974942048282
在經(jīng)過(guò)前一天Messenger應(yīng)用平臺(tái)、Parse物聯(lián)網(wǎng)開(kāi)發(fā)者工具等驚喜的轟炸,F(xiàn)acebook于今天凌晨在F8開(kāi)發(fā)者大會(huì)上正式開(kāi)源了React Native。不過(guò)目前,只有iOS版,Android版還需要再等一段時(shí)間,這是最新的用JavaScript語(yǔ)言開(kāi)發(fā)原生App的嘗試,其示例代碼相當(dāng)簡(jiǎn)潔,內(nèi)置控件也不少。同時(shí)還為React Native開(kāi)發(fā)了一款基于Atom的IDE——Nuclide,也已開(kāi)源。
React Native主要特性如下:
React Native主張“Learn once, write everywhere”而非其他跨平臺(tái)工具一直宣揚(yáng)的“Write once, run everywhere”。通過(guò)React Native,開(kāi)發(fā)者可以使用UITabBar、UINavigationController等標(biāo)準(zhǔn)的iOS平臺(tái)組件,讓應(yīng)用界面在其他平臺(tái)上亦能保持始終如一的外觀、風(fēng)格。
var React=require('react-native'); var { TabBarIOS, NavigatorIOS }=React; var App=React.createClass({ render: function { return ( <TabBarIOS> <TabBarIOS.Item title="React Native" selected={true}> <NavigatorIOS initialRoute={{ title: 'React Native' }} /> </TabBarIOS.Item> </TabBarIOS> ); }, });
JavaScript應(yīng)用代碼和原生平臺(tái)之間所有的操作都采用異步執(zhí)行模式,原生模塊使用額外線程,開(kāi)發(fā)者可以解碼主線程圖像、后臺(tái)保存至磁盤、無(wú)須顧忌UI等諸多因素直接度量文本設(shè)計(jì)布局。
React Native引入了一個(gè)類似于iOS上Responder Chain響應(yīng)鏈?zhǔn)录幚頇C(jī)制的響應(yīng)體系,并基于此為開(kāi)發(fā)者提供了諸如TouchableHighlight等更高級(jí)的組件。
var React=require('react-native'); var { ScrollView, TouchableHighlight, Text }=React; var TouchDemo=React.createClass({ render: function { return ( <ScrollView> <TouchableHighlight onPress={=> console.log('pressed')}> <Text>Proper Touch Handling</Text> </TouchableHighlight> </ScrollView> ); }, });
Facebook在 React Native的主頁(yè)上詳細(xì)介紹了React Native的種種功能特性,想要了解更多細(xì)節(jié),可直接進(jìn)入主頁(yè)查看,而其為React Native搭配的開(kāi)源IDE Nuclide支持React Native、Web和原生移動(dòng)開(kāi)發(fā),基于Atom構(gòu)建,不過(guò)也需要翻墻。