從 1 到完美,用 js 和 react-native 寫一個 APP

從 1 到完美,用 js 和 react-native 寫一個 APP

facebook 在 2013 年開源了 react 後,緊接着在 2015 年就又開源了 react-native,就此打開了用 js 和前端技術寫原生 android&ios APP 之路。儘管到目前爲止 react-native 最新版本是 0.56.0,尚未發佈正式 1.0 版,但使用 react-native 開發原生 APP 的技術已經比較成熟了,不少商業公司和商業軟件都在用 react-native 作開發,好比 facebook, airbnb, uber, skype 等。javascript

另外,除了 react 在作寫原生 APP 的嘗試以外,vue 也在嘗試,詳見 vue-nativecss

1. 前言

  1. 開發時建議用 mac,由於 mac 上的 ios 模擬器能在開發時,快速的重載應用,而 android 就慢不少了
  2. 開發時建議用 yarn, 若是非要用 npm, 務必使用 npm < 5 版本,不然就可能遇到如下的問題(找不到 node_modules 下面的文件):html

    • Cannot find entry file node_modules/react-native-scripts/build/bin/crna-entry.js
    • Unable to resolve "react-navigation" from "App.js"
    • expo xde 中: Metro Bundler failed to start. (code: EMFILE)
    • expo xde 中: Metro Bundler failed to start. (code: EAGAIN)

2. 實現原理

react-native 在 APP 內啓動並維護了一個 js UI 進程(有可能還有 js background 進程),而後把 js UI 進程中的組件及其樣式映射到 APP 的原生 UI 層,這樣 js UI 進程中組件的更新就馬上反應到 APP UI 進程中,而其餘邏輯和數據等的狀態都維持在 js UI 進程中。這樣便達到了用 js 和前端技術寫原生 APP 的功能。 前端

對應 web 來看,react-native 程序只有兩個部分,stylejs,而 js 部分則分爲組件和 apivue

|-- react-native
    |-- style 樣式部分,對應 web 的 css 部分
    |-- js 部分
        |-- 組件 預約義基礎容器
        |-- api 對原生接口的封裝

2.1 style

react-nativestyle 用來描述組件的樣式、佈局等,用 js 書寫。它借鑑了 css 的語法,但只支持部分的語法,而且書寫方式和實現方式都有很大的不一樣:java

  • 沒有 class, id 等之類的 css 選擇器
  • 沒有 px, em 等之類的 css 尺寸單位
  • 屬性名使用 HTML DOM Style 對象 的語法
  • 使用樣式時只有相似於 css 的行內樣式這樣的寫法

好比:node

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default class LotsOfStyles extends Component {
  render() {
    return (
      <View>
        <Text style={styles.red}>just red</Text>
        <Text style={styles.bigblue}>just bigblue</Text>
        <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
        <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 30,
  },
  red: {
    color: 'red',
  },
});

詳見 Style, StyleSheet, View Style Props, Text Style Props, Image Style Propsreact

2.2 js

react-nativejswebjs 都是 javascript,這點沒區別;但 react-nativejs 只是純 js,並不運行在瀏覽器環境中,也就沒有 DOM,一切與 DOM 相關的語法都不可用,如 window, document 等。因此,在 web 端的純 js 庫(無 DOM)在 react-native 中一樣適用,如 redux, lodash, immutable-js 等。android

react-nativejs 分爲組件和接口。ios

組件是由 react-native 定義好的基礎容器,就像 html 的標籤同樣,如 View, Text, Image, WebView 等。

接口是 react-native 封裝好的原生 APP 的功能,如相機、存儲、系統信息等。

3. 決定是否使用 react-native

儘管 react-native 提供了使用 js 和前端技術寫原生 APP 的強大功能,但並非說就能夠用 react-native 代替 java, kotlinandroid APP、objective-c, swiftios APP 了,它只是提供了一個選擇。

其實,從上面的實現原理中,基本上能夠看出 react-native APP 是有很明顯的劣勢的:

  • 性能不及原生的 APP
  • 自由度也不及原來的 APP,由於被約束的 react-native 模式中
  • apk, ipa 文件變大了

react-native 也有很強大的優點:

  • 開發簡單、快速,入門坎比較低
  • 跨平臺,一套代碼就能夠在多個平臺上運行

因此,一種不錯的選擇是:

  1. 若是追求完美性能和體驗的 APP,用原生的方式(androi: java, kotlin, ios: objective-c, swift)開發
  2. 對性能和體驗不敏感,但對人力成本敏感,而且須要快速開發的,用 react-native 開發
  3. 二者能夠混合開發,對性能和體驗敏感的用原生的方式開發,對人力成本和時間成本敏感的用 react-native 開發

4. 決定使用何種構建方式

目前 react-native APP 的構建方式有兩種:

  1. 使用 Android Studio 或 Xcode 開發
  2. 使用 expo 方式開發

4.1 使用 Android Studio 或 Xcode 開發

這種方式是目前使用比較多的一種方式,無論是純 react-native APP 仍是混合型 APP(原生與 react-native 混合開發),都是適用的。

這種方式的好處是能夠進行原生開發、自定義打包,但對大部分前端開發人員來講,這種方式對環境的要求比較高,須要 Android Studio 或 Xcode,而且配置複雜,入門坎很高。

初始化

# 安裝 react-native-cli
npm install -g react-native-cli

# 新建項目
react-native init demo

# 切換到項目根目錄
cd demo

開發

# 開啓本地 `js` UI 進程服務(開發模式)
npm run start

# 運行 ios 程序
react-native run-ios

# 運行 android 程序
react-native run-android

打包 apk, ipa

# 打包 android APP 所需的 js bundle 文件
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ 

# 打包 apk
# 按照正常的 android 打包方式進行


# 打包 ios APP 所需的 js bundle 文件
react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/bundle/index.ios.jsbundle --assets-dest ios/bundle

# 打包 ipa
# 按照正常的 ios 打包方式進行

4.2 使用 expo 方式開發

expo 是 facebook 與 expo 合做專門爲 react-native 開發的一套工具,它讓 react-native 開發從 Android Studio 和 Xcode 中解放出來,使開發者只關注 react-native 開發部分,而不理會複雜的原生開發。

這種方式是目前純 react-native APP 開發的推薦方式。

這種方式的好處是不須要 Android Studio 或 Xcode(包括開發和打包),對環境的要求低,配置簡單,入門坎低,但不能進行原生開發、自定義打包。

初始化

# 安裝 create-react-native-app
npm install -g create-react-native-app

# 新建項目
create-react-native-app demo

# 切換到項目根目錄
cd demo

或者

# 安裝 expo
npm install -g expo-cli

# 新建項目
expo init

# 切換到項目根目錄
cd demo

開發

# 運行 ios 程序
npm run ios

# 運行 android 程序
npm run android

或者

# 手機上安裝 expo 客戶端

# 開啓本地 `js` UI 進程服務(開發模式)
expo start

# 運行 ios 程序
# 用 expo 客戶端掃描二維碼

# 運行 android 程序
# 用 expo 客戶端掃描二維碼

打包 apk, ipa

# 打包 apk
expo build:android

# 打包 ipa
expo build:ios

可能遇到的問題

  1. 若是構建出錯,嘗試刪除項目根目錄下的 .expo 文件夾以後,再試
  2. Packager is not running at ...: 嘗試從新打開一個終端,並嘗試刪除項目根目錄下的 .expo 文件夾以後,再試

5. 選擇合適的組件庫

6. 選擇合適的模板

使用 react-native initcreate-react-native-app 初始化的項目,只是搭建好了基礎的骨架,項目的其餘部分須要開發者本身去搭建,如 storybook 組件預覽、enzyme + jest 測試、eslint + prettier 代碼矯正與優化等。

因此,選擇一個合適的、已經搭建好大部分架子的模板就很受用了:

ignite 舉例:

# 安裝 ignite-cli
npm install -g ignite-cli

# 初始化項目
ignite new demo

# 切換目錄
cd demo

# 如今就能夠對項目進行操做了,如添加 screen,運行程序等

# 運行 storybook 組件預覽
npm run storybook

# 開啓本地 `js` UI 進程服務(開發模式)
npm run start

# android 打包
npm run android:build

# ios 打包須要用 Xcode

7. 開發應用

除了 stylecss 的區別和 jsDOM 外,其餘與開發 web 項目一致。

8. 應用實例

diary 即是使用 expo 開發的一個日記 APP。

9. 後續

更多博客,查看 https://github.com/senntyou/blogs

做者:深予之 (@senntyou)

版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證

相關文章
相關標籤/搜索