我的GitHub
0%

无星的RN学习之旅(十)-一份不太严谨的入门教程

写在前面

菜鸡,半个iOS开发,js了解不深入,见解不一定正确,有错指出,意会一下这个意思就行了,大牛就没必要看了、、、

背景

以下所有是基于mac的,Windows老哥只能参考着看了

cmd = ctrl , option = alt

一、环境安装

其实官方的环境安装教程很简单,但也不排除有老哥看不懂,所以还是再赘述一下,下面是mac的傻瓜式环境安装教程(安装好了的不用看,windows老哥挑着看)

打开终端,我们开始了

1.开启任意来源

1
sudo spctl --master-disable

输入mac的开机密码,敲回车(linux或类linux系统,输入密码不会提示输入了,界面是空白的,不要以为是键盘坏了或者没输入)

2.安装homebrew

homebrew是mac上的包管理器,能非常方便的管理我们的各种环境和路径依赖,久了你就知道好处了。

1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

3.安装nvm

nvm是用来管理node版本的,如果直接使用brew安装node你会发现装的是最新版本(非稳定版),使用nvm可以很方便的管理本机的node环境

方式一:brew安装(不推荐)

1
2
3
4
5
brew install nvm

echo "source $(brew --prefix nvm)/nvm.sh" >> .bash_profile

source ~/.bash_profile

方式二:curl安装

1
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

安装完毕以后输入

1
2
3
4
//zsh的前往zsh环境变量修改(macOS 10.15以后默认为zsh)
vi ~/.zshrc
//bash的前往zsh环境变量修改
vi ~/.bash_profile

按i进入编辑,在后面粘贴如下环境

1
2
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

按esc 依次输入三个字符 : w q (冒号,w,q 中间不要有空格)

输入

1
2
3
4
//bash
source ~/.bash_profile
//zsh
source ~/.zshrc

运行完毕以后重启终端,输入nvm并回车,如果识别了nvm命令则nvm安装完毕

4.使用nvm安装最新的node稳定版本

打开终端输入

1
nvm ls-remote

查看最高的稳定版本(后面会有绿色字体标识lts)
输入

1
nvm install 版本号

例如:

1
nvm install v8.12.0

安装完毕以后输入刚刚安装的版本号

1
nvm use 版本号

例如

1
nvm use v8.12.0

完成以后,输入以下命令查看当前机子的node版本看与安装使用的是否一致

1
node -v

至此,node和npm安装完毕

5.1安装nrm

nrm是管理源的,相信看过看多文章都说npm源切成淘宝源或者其他什么源。

打开终端输入

1
npm install -g nrm

安装完毕后输入

1
nrm ls

查看可用版本源

输入

1
nrm use 源

例如:

1
nrm use npm

5.2 2019-11-27更新

安装cocoapods

1
brew install cocoapods

注意:后续生成rn第一个项目的时候,pod install可能需要一些时间,不是卡主,耐心等待就好

6.安装react-native

打开终端依次输入

1
brew install watchman

Watchman是由Facebook提供的监视文件系统变更的工具。安装此工具可以提高开发时的性能(packager 可以快速捕捉文件的变化从而实现实时刷新)

1
brew install yarn --without-node

安装yarn,用于react-native的包管理依赖(npm和yarn的区别可以自行百度),上面我们已经安装了nvm控制node,所以这里安装yarn的时候不要安装node,记得加上–without-node
2019-3-12更新
可能有大哥执行这一步报错,原因是brew更新了,移除了这些可选项.
建议切换命令如下进行忽略

1
brew install yarn --ignore-dependencies

git地址:https://github.com/yarnpkg/yarn/issues/6946

1
npm install -g react-native-cli

安装react-native-cli,是一个脚手架,方便进行react-native的一些命令操作

至此,react-native环境安装完毕

二、开发工具下载

Xcode Android Studio Chrome VSCode/Webstrom
iOS开发必备 安卓开发必备 调试必备 js开发必备
这里就不给下载链接了,自己下去吧

三、创建第一个项目

1.创建项目

打开终端,cd到桌面目录下

1
cd Desktop/

创建你的第一个App(默认是最新版本,写这篇文章的时候最新版本是0.57.4版本)

1
react-native init FirstApp

如果你想创建一个指定版本,例如0.57.4版本

1
react-native init FirstApp --version 0.57.4

开始下载安装react-native

开始安装react和jest

从图中我们可以看到,整个安装做了三件事

安装react-native,安装react,安装jest

安装完的图就不截了,没钱办网,流量挺贵的。。。

我们现在安装完了,开始运行。

2.运行项目

有2种运行方式

1.使用命令行启动项目

1.cd到项目根目录下

1
cd /Users/mac/Desktop/FirstApp   

2.启动iOS

1
react-native run-ios

启动安卓(安卓需要自行安装安卓模拟器,或者链接真机)

1
react-native run-android

2.使用Xcode或者Android Studio(以下简称AS)启动。(推荐)

项目文件夹
从图中可以看到,项目下面有两个命名为Android和iOS的文件夹,里面分别放着安卓和iOS工程,所有的起源,就是这两个目录。这里我们以iOS举例(安卓的我就不讲了,毕竟也不会emmm)

我们双击打开xcodeproj,就可以从xcode启动项目了。

3.项目文件大致说明

图解

看图应该都能看明白

下面我们对各文件大致进行说明。
分别用xcode和webstrom(vscode)打开项目文件

(1)app.json

app.json文件


(2)package.json

类似iOS中常用的三方库管理工具cocoapods的profile文件,用于三方库的管理。
package.json文件
从图中可以看到,有很多东西,我们一个个说

name,version,private,这三个应该不用我说。。不知道也没关系,不影响你的开发

scripts

脚本,在开发过程中我们可能会输入各种常用命令,比如启动node服务、iOS的bundle包打包、安卓的apk打包、eslint的代码检查等,每次记那么一堆命令烦都烦死了,这时候就可以用到这个脚本了,你可以将一些常用命令放到这里,并赋予一个缩写单词,执行的时候只要在项目根目录下输入

1
npm run 缩写

来执行相关命令。在这里我写一个常用命令
iOS的bundle包打包命令(可查看文章无星的RN学习之旅(七)——iOS打包(图文教程版)

1
react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index.jsbundle --platform ios --assets-dest ./ios/bundle --dev false

可以将这个命令粘贴到scripts中,例如:

1
2
3
4
5
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"iosbundle": "react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index.jsbundle --platform ios --assets-dest ./ios/bundle --dev false"
},

执行的时候,只需要输入如下命令即可完成打包

1
npm run iosbundle

dependencies

开发过程中用到的三方库的依赖管理

各位肯定在git上下载过各种项目,下载下来第一件事就是做npm install或者是yarn

其实就是下载这里标记的三方库。且这里标记的三方库会打入到正式包中。

我们在其中的版本有时候经常能看见^,这个^有什么作用可以百度一下,不做延展。

devDependencies

下载包的时候,使用npm和yarn命令下载,有的时候会添加–dev,例如eslint(大部分公司都会使用这个进行代码风格控制无星的RN学习之旅(九)-ESLint引入),这些三方库只在开发过程中需要用到,没必要打包到正式包中增加体积。

这些只在开发过程中使用而不需要打包到正式包中的库,下载时记得添加–dev,最后会被标记到devDependencies这个下面

jest

jest本身是一个测试库,可以理解为执行单元测试的一个三方库,具体作用可以百度,这里不做延展。


(3)yarn.lock

上面留了个坑,查询dependencies版本中的^的作用,yarn.lock与此有关,百度了的同学一定知道是什么作用

(4).node_modules

所有的三方库的源文件都在这个文件夹中,react-native,react都是作为三方库的框架在整个app中,所以在node_modules你也能看见它们。和原生项目的三方库引入一样,这里引入的三方库,经过

1
react-native link

link以后,会被添加到各自原生项目的三方库依赖中,比如在iOS中你会发现,引入的三方库在librarys下面都能找到。

(一般情况下,npm和yarn进行三方库下载的时候会自动执行link操作,如果没执行的话就自己手动执行一次)

如图
所以如果项目执行中出现
library -link xxxx not found

可以先看看报错的库自己是否用,是否在这里引入link了。

(5).webstrom打开文件,你还能看见一个.babelrc的文件

这个文件是个编译器文件(好像是),具体可以百度一下,一般情况下用不上,如果碰到三方库需要做什么配置的,三方库的说明文档一定会写明如何配置。这里也不多说了(因为我也不会,emmmm)

(6).Android文件夹,不提,因为不懂

(7).iOS文件夹(不是iOS开发可以不用看,直接跳过)

里面放的是iOS的原生项目,其实rn就是在原生项目里面套了个壳子,其他都是view在不停滑动(可以看下无星的RN学习之旅(四)——通信、持久化存储、iOS打包这里面记录了一些感想,文章名字是后改的,emmm)

打开iOS项目AppDelegate.m中就是一切的开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;

jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"FirstApp"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}

懒得截图了,直接复制到这说。
jsCodeLocation,这就是rn的东西了,你可以把这当做rn的入口。

1
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

第一个参数是项目中对应的js文件名,这里就是入口了,一般就写index,不做变动,因为项目初始化里面有个index。js,当然改动也无所谓,只要一一对应即可。index.js在下面讲

[RCTBundleURLProvider sharedSettings]点进去源码,你会发现其实得到一个本机内网ip地址,用来指向node服务开启后的文件源路径。

所以我们也可以自己改动一下,其实只要指向node服务的本地路径即可。
例如:

1
jsCodeLocation = [NSURL URLWithString:@"http://xxx.xxx.xxx.xxx:8081/index.bundle?platform=ios&dev=true"];

ip写自己的本地内网ip,8081是node服务的默认端口,如果你改动过就变成对应的端口,platform=ios,平台是ios平台,dev=true标识是开发状态。
这样也能正常连接上你的node服务。

如果使用codePush(热更新),那么自然会变成codePush上放置jsbundle文件的地址,入门教程,就不多谈了。

1
2
3
4
5
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"FirstApp"
initialProperties:nil
launchOptions:launchOptions];

看见这个moduleName了吗,还记得之前说的package.json文件中name和app.json中的name吗,记得一一对应。不然会报错。

另外,实测,后面两个参数都可以是nil,依旧可以得出RCTRootView。因此可以自定义ctrl作为rootctrl,添加RCTRootView,不一定要放在appdelegate里。

另外

image
这里有一个脚本,作用是干啥的,可以百度一下,埋个坑不填,从0.4几老版本升级上来的同学一定改动过(我说的是升级不是迁移)。

(8).index.js

上面iOS文件夹项目的解析中说了,这是对应的rn文件入口。相信有些同学看过其他的rn教程,里面写的可能都是index.ios.js或者index.android.js。其实都是一个东西,在0.4几的版本中将其合并了,变成了index.js。

1
2
3
4
5
6
7
/** @format */

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

AppRegistry.registerComponent,从名字我们也能看出来,这是App的注册入口,点进去粗略的我们看下

image
一共三个参数,string型,component,布尔型(可选),第一个传了appName是个sting型,第二个肯定传的是component。


这时候应该有同学要提出两个问题,()=>是啥?component又是啥?

()=>是啥?

()=>是个箭头函数,ES6语法,后面常常跟一个方法体,不跟就理解为直接return 了一个对象。可以理解为就是一个方法,function(){},前端中经常使用this(类似于iOS的self),一般得是当前类的实例化对象,如果在加了static的方法中(类方法)使用this,指的就是类本身。

this的作用域问题(iOS在block中用self有时候self指向的也不是当前类这个问题)肯定经常有人吃亏,一有两种解决方式:
1使用bind来解决2.使用箭头函数

所以箭头函数就是能解决this作用域问题的一个function。

component又是啥?

前端肯定知道啥是component,不提。

iOS同学,把他当做webkit框架,所有的UI控件有关的东西都继承自它。

安卓同学不知道,所有的UI控件有关的东西都继承自它。


闲话少扯,我们回到之前的地方

一共三个参数,string型,component,布尔型(可选),第一个传了appName是个sting型,第二个肯定传的是component我们看到,是return了一个APP。

细心的朋友注意到,import的东西有的加了{},有的没加,我们等会说这个。

(9).App.js

image

语法,css,这些不讲,自己查文档就能搞定。

export,导出,所有在外部引用的东西,都需要用export这个关键字进行导出。

export default,默认导出。

这时候可以回答上面那个问题,没有加default的,需要用{}包裹,且导出的名字和import的名字一一对应。添加了default的,不需要用{}包裹,且可以改名字,任意改名都指向默认导出的东西。

所以我个人习惯使用export不加default,因为名字和导出名一一对应,代码阅读更加清晰。看个人习惯使用哪一种。

我们可以看见,App继承自自component,return了一个大UI组件(return只能return一个组件,因此最外层必须用一个组件来包裹)。这和前面的要求类型相符合。没问题。

因此你可以在这里进行任意页面的更改。打开模拟器

Windows用户使用ctrl代替cmd

(ios)cmd+r进行刷新
(安卓)cmd+m选reload 进行刷新

会即时的将更改展现在你的页面上。

整个新项目就解析完毕

四,如何debug

安装Chrome以后

运行项目,项目启动以后,在模拟器的界面上

ios cmd+d 安卓 cmd+m 选择第二个选项,进行debug,chrome会自动启动。

谷歌浏览器启动,等待模拟器项目启动完毕cmd+j,选择source,侧边栏出现的就是本次app启动的文件,可以进行debug了。

我是阿星,阿星的阿,阿星的星!