ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含19760字,纯文字阅读大概需要29分钟。
内容图文
一、简介
在讲本篇博文之前,需要你熟知怎么自定义ReactNative组件,然后才好学习将自定义的ReactNative组件制作成第三方库。本文中的自定义的ReactNative组件LoginManager API 源自上篇文章,所以需要先看一下上篇博文。言归正传,ReactNative的确提供了一个非常便捷的方式来扩展Native模块。如果要把模块做成第三方组件的话,还有一些工作要做:首先以一个静态库工程来编译模块代码,提供JavaScript的封装,最后创建Package.json来支持node的引用。在步骤开始之前,我先把上篇文章中创建Native原生模块的LoginManager API组件的类贴出来,如下所示:
LoginManager.h
// // LoginManager.h // RNDemo // // Created by 夏远全 on 2020/1/16. // Copyright ? 2020 Facebook. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import <React/RCTUtils.h> #import <React/RCTEventDispatcher.h> #import <React/RCTBridgeModule.h> NS_ASSUME_NONNULL_BEGIN //OC中定义一个枚举并导出typedef NS_ENUM(NSInteger, MoveDiretion){ MoveDiretionNone, MoveDiretionLeft, MoveDiretionRight, MoveDiretionBottom, MoveDiretionTop }; @interface LoginManager : NSObject<RCTBridgeModule> @end NS_ASSUME_NONNULL_END
LoginManager.m
// // LoginManager.m // RNDemo // // Created by 夏远全 on 2020/1/16. // Copyright ? 2020 Facebook. All rights reserved. // #import " LoginManager.h " #ifdef DEBUG #define NSLog(format, ...) printf("[%s] %s [第%d行] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]); #else#define NSLog(format, ...) #endif@implementation LoginManager //初始化, 添加屏幕旋转监听者 -(instancetype)init { self = [super init]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; } return self; } //导出模块类RCT_EXPORT_MODULE(); //重映射,auth为code方法的新名称 RCT_REMAP_METHOD(auth,code:(NSString *)account{ NSLog(@"%s---获取验证----",__func__); NSLog(@"account----%@",account); }); //login为方法名 RCT_EXPORT_METHOD(login:(NSString *)account password:(NSString *)password{ NSLog(@"%s---登录账号----",__func__); NSLog(@"account----%@",account); NSLog(@"password----%@",password); }); //logout为方法名 RCT_EXPORT_METHOD(logout:(NSString *)account{ NSLog(@"%s---退出账号----",__func__); NSLog(@"account----%@",account); }); //设置普通的回调函数 //fetchUserInfoWithToken为方法名,successCallback为成功回调,failureCallback为失败回调 RCT_EXPORT_METHOD(fetchUserInfoWithToken:(NSString *)token success:(RCTResponseSenderBlock)successCallback failure:(RCTResponseErrorBlock)failureCallback { if(token.length>0 && successCallback){ successCallback(@[ @"account = xiayuanquan", @"password = 123456", [NSString stringWithFormat:@"token = %@",token] ]); } else{ if(failureCallback){ failureCallback( [[NSError alloc] initWithDomain:NSOSStatusErrorDomain code:404 userInfo: @{NSLocalizedDescriptionKey: @"token exception"}] ); } } }); //设置异步处理的回调函数 //sendMessage为方法名,successCallback为成功回调,failureCallback为失败回调 RCT_EXPORT_METHOD(sendMessage:(NSString *)message success:(RCTPromiseResolveBlock)successCallback failure:(RCTPromiseRejectBlock)failureCallback { if(message.length>0 && successCallback){ successCallback(@"发送成功!"); } else{ if(failureCallback){ failureCallback(@"300",@"发送失败",nil); } } }); //重写constantsToExport, 枚举常量导出 - (NSDictionary<NSString *, id> *)constantsToExport { return @{ @"MoveDiretionNone": @(MoveDiretionNone), @"MoveDiretionLeft": @(MoveDiretionLeft), @"MoveDiretionRight": @(MoveDiretionRight), @"MoveDiretionBottom": @(MoveDiretionBottom), @"MoveDiretionTop": @(MoveDiretionTop) }; } //定义一个移动方法,根据传入的枚举值移动 //move为方法名RCT_EXPORT_METHOD(move:(MoveDiretion)moveDiretion{ switch(moveDiretion){ case MoveDiretionNone: NSLog(@"仍保持原始位置 --- MoveDiretionNome"); break; case MoveDiretionLeft: NSLog(@"向左边移动位置 --- MoveDiretionLeft"); break; case MoveDiretionRight: NSLog(@"向右边移动位置 --- MoveDiretionRight"); break; case MoveDiretionBottom: NSLog(@"向下边移动位置 --- MoveDiretionBottom"); break; case MoveDiretionTop: NSLog(@"向上边移动位置 --- MoveDiretionTop"); break; } }); //可以重写队列,给当前模块类指定自定义的串行队列。若不指定,则系统默认会给当前模块类随机分配一个串行队列。 //这个方法一旦重写。当前模块的所有方法均会在该自定义的串行队列中异步执行 -(dispatch_queue_t)methodQueue{ return dispatch_queue_create("com.facebook.ReactNative.LoginManagerQueue", DISPATCH_QUEUE_SERIAL); } //定义一个方法,获取线程和队列信息 //thread为方法名RCT_EXPORT_METHOD(thread:(BOOL)newQueue{ constchar *queueName = dispatch_queue_get_label([self methodQueue]); NSLog(@"当前线程1 ------- %@-----%s", [NSThread currentThread], queueName); if(newQueue){ dispatch_async(dispatch_get_main_queue(), ^{ constchar *queueName2 = dispatch_queue_get_label(dispatch_get_main_queue()); NSLog(@"当前线程2 ------- %@ -------%s", [NSThread currentThread], queueName2); }); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ constchar *queueName3 = dispatch_queue_get_label(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); NSLog(@"当前线程3 ------- %@-------%s", [NSThread currentThread], queueName3); }); } }); //获取当前屏幕的尺寸static NSDictionary *Dimensions(){ CGFloat width = MIN(RCTScreenSize().width, RCTScreenSize().height); CGFloat height = MAX(RCTScreenSize().width, RCTScreenSize().height); CGFloat scale = RCTScreenScale(); if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){ width = MAX(RCTScreenSize().width, RCTScreenSize().height); height = MIN(RCTScreenSize().width, RCTScreenSize().height); } return @{ @"width": @(width), @"height": @(height), @"scale": @(scale) }; } //定义一个方法,获取屏幕信息 //getDimensions为方法名RCT_EXPORT_METHOD(getDimensions:(RCTResponseSenderBlock)callback{ if (callback) { callback(@[[NSNull null], Dimensions()]); } }); //监听方法,使用RCTEventDispatcher的eventDispatcher调用sendDeviceEventWithName函数发送事件信息 //可以将事件名称作为常量导出,提供给ReactNative中使用,也即添加到constantsToExport方法中的字典中即可。类似上面的枚举。@synthesize bridge = _bridge; -(void)orientationDidChange:(NSNotification *)notification { [_bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange" body:@{ @"orientation": UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"Landscape": @"Portrait", @"Dimensions": Dimensions()} ]; } //移除监听者 -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end
RCTConvert+MoveDiretion.h
// // RCTConvert+MoveDiretion.h // RNDemo // // Created by 夏远全 on 2020/1/17. // Copyright ? 2020 Facebook. All rights reserved. // #import <React/RCTConvert.h> NS_ASSUME_NONNULL_BEGIN @interface RCTConvert (MoveDiretion) @end NS_ASSUME_NONNULL_END
RCTConvert+MoveDiretion.m
// // RCTConvert+MoveDiretion.m // RNDemo // // Created by 夏远全 on 2020/1/17. // Copyright ? 2020 Facebook. All rights reserved. // #import " RCTConvert+MoveDiretion.h " #import " LoginManager.h " @implementation RCTConvert (MoveDiretion) // 给RCTConvert类添加扩展,这样在模块方法调用中使用常量导出的枚举值,通信到Native中时,会从整型自动转换为定义的枚举类型 RCT_ENUM_CONVERTER(MoveDiretion,(@{ @" MoveDiretionNone " : @(MoveDiretionNone), @" MoveDiretionLeft " : @(MoveDiretionLeft), @" MoveDiretionRight " : @(MoveDiretionRight), @" MoveDiretionBottom " : @(MoveDiretionBottom), @" MoveDiretionTop " : @(MoveDiretionTop), }), MoveDiretionNone, integerValue) @end
二、步骤
1、使用xcode创建一个名为LoginManager的静态库。
2、打开静态库,将上面贴出来的已经实现好了的Native模块LoginManager API组件的类全部拷贝进去或进行替换。
3、选择Build Settings,配置Header Search Paths路径。
6、打开终端,初始化一个新的RN项目,随意设置一个名称为:LoginManagerTestProject。(本人安装的ReactNative版本较低)
// 初始化 react-native init LoginManagerTestProject --version 0.44.3
7、进入目录node_modules。
// 进入node_modules cd LoginManagerTestProject/node_modules
8、创建要制作的第三库文件夹,指定名称为:react-native-login-manager。
// 创建第三方名称 mkdir react-native-login-manager
9、进入这个第三方库文件夹。
// 进入库文件 cd react-native-login-manager
10、创建ios文件夹。
// 创建ios文件 mkdir ios
11、将之前创建的静态库中的根目录下的文件全部copy到这个RN工程LoginManagerTestProject/node_modules/react-native-login-manager/ios目录下。目录结构如下:
12、使用xcode打开这个RN工程LoginManagerTestProject,将静态库LoginManager的.xcodeproj文件 拖到 RN工程LoginManagerTestProject的Libraries文件下。
13、手动添加libLoginManager.a静态包,然后编译,如果编译不出错,则success。
14、使用终端或者webStorm等编程工具进入到RN工程LoginManagerTestProject/node_modules/react-native-login-manager目录下,创建index.js文件,它是整个原生模块的入口,我们这里只是将原生LoginManager模块类进行导出。此时也就完成了第三方库制作的第一步了,仅仅可以自己使用。 (还需要发布到npm上,分享给大家安装使用)
三、测试
好了,咱先自己测试一下,看看行不行。结果是行的,??。
/* * * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from ‘ react ‘ ; import { AppRegistry, StyleSheet, View } from ‘ react-native ‘ ; // 使用自定义的react-native-login-manager第三方库的模块方法 import LoginManager from ‘react-native-login-manager‘; LoginManager.auth("xiayuanquan"); //使用LoginManager模块类的监听通知const RCTDeviceEventEmitter = require(‘RCTDeviceEventEmitter‘); let subscription = RCTDeviceEventEmitter.addListener(‘orientationDidChange‘, (dimensions) => { Object.keys(dimensions).forEach(key => console.log(key, dimensions[key])); }); //subscription.remove(); export defaultclass LoginManagerTestProject extends Component { render() { return ( <View style={styles.container}> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: ‘center‘, alignItems: ‘center‘, backgroundColor: ‘#F5FCFF‘, } }); AppRegistry.registerComponent(‘LoginManagerTestProject‘, () => LoginManagerTestProject);
运行的结果如下所示:标红部分确实打印出结果了。
2020-01-1814:42:21.119 [info][tid:main][RCTBatchedBridge.m:77] Initializing <RCTBatchedBridge: 0x6000023cc1c0> (parent: <RCTBridge: 0x6000031c9490>, executor: RCTJSCExecutor)2020-01-1814:42:21.173 [warn][tid:com.facebook.react.JavaScript][RCTModuleData.mm:220] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks 2020-01-1814:42:21.173562+0800 LoginManagerTestProject[89258:2044559] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks [14:30:32] -[LoginManager code:] [第34行] -[LoginManager code:]---获取验证---- [14:30:32] -[LoginManager code:] [第35行] account----xiayuanquan 2020-01-1814:42:21.391340+0800 LoginManagerTestProject[89258:2044406] Running application LoginManagerTestProject ({ initialProps = { }; rootTag = 1; }) 2020-01-18 15:20:51.450 [info][tid:com.facebook.react.JavaScript] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 15:20:51.450504+0800 LoginManagerTestProject[89634:2069334] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 15:20:51.451 [info][tid:com.facebook.react.JavaScript] ‘orientation‘, ‘Portrait‘ ...... 2020-01-18 15:21:08.148 [info][tid:com.facebook.react.JavaScript] ‘Dimensions‘, { width: 667, scale: 2, height: 375 } 2020-01-18 15:21:08.149013+0800 LoginManagerTestProject[89634:2069334] ‘Dimensions‘, { width: 667, scale: 2, height: 375 } 2020-01-18 15:21:08.149 [info][tid:com.facebook.react.JavaScript] ‘orientation‘, ‘Landscape‘ .....
注意事项,如果在xcode11运行时出现类型无法转换。可能是由于RN低版本,Xcode11(iOS13)中对未使用的接口选择器的参数unused字符串属性进行了更改成了__unused__,导致ReactNative动态收集接口时不能把声明的接口进行导入,运行时无法查找到该接口导致的错误。错误如下:
2019-09-2515:16:47.784 [error][tid:main][RCTModuleMethod.m:376] Unknown argument type ‘__attribute__‘in method -[RCTAppState getCurrentAppState:error:]. Extend RCTConvert to support this type. 2019-09-2515:16:47.784408+0800 example[68797:2090899] Unknown argument type ‘__attribute__‘in method -[RCTAppState getCurrentAppState:error:]. Extend RCTConvert to support this type.
解决办法是需要修改RCTModuleMethod类,找到RCTParseUnused静态函数,使用下面这段代码进行替换(第2行就是新添加的),如下所示:
static BOOL RCTParseUnused(constchar **input) { return RCTReadString(input, "__unused") || RCTReadString(input, "__attribute__((__unused__))") || RCTReadString(input, "__attribute__((unused))"); }
四、发布
只有将第三方库发布到了npm上,可以提供给大家安装并进行使用,这才算是真正的第三方库。但是,在将第三方库发布到npm上之前,需要先拥有一个npm账号。
1、查询是否拥有npm账号
// 查询 npm whoami // 本人没有安装,所以错误如下 npm ERR! code ENEEDAUTH npm ERR! need auth This command requires you to be logged in. npm ERR! need auth You need to authorize this machine using `npm adduser` npm ERR! A complete log of this run can be found in: npm ERR! /Users/xiayuanquan/.npm/_logs/2020-01-18T07_37_42_133Z-debug.log
2、若没有则申请注册一个
// 添加一个npm账号 npm adduser // 本人添加结果如下。 如果注册成功,npm官方会发来邮件,用户需要点击邮件进行验证。 "Verify your npm email address"。 一定要进行验证,否则发布无法成功。 Username: xiayuanquan Password: Email: (this IS public) 137xxxx7163@163.com Logged in as xiayuanquan on https://registry.npmjs.org/.
拥有了npm账号后,我们现在就可以来进行发布的步骤了。
1、进入RN项目,使用git命令在github上创建仓库react-native-login-manager,和我们的第三方库进行关联。
// 进入项目 cd /Users/xiayuanquan/Desktop/LoginManagerTestProject/node_modules/react-native-login-manager //git初始化git init . //关联远程仓库 git remote add origin https://github.com/xiayuanquan/react-native-login-manager.git
2、仍然在LoginManagerTestProject/node_modules/react-native-login-manager目录下,创建一个package.json文件。发布到npm之前,必须有这个文件存在,它和index.js目录结构是平级的。package.json文件包含了module的所有信息,比如名称、版本、描述、依赖、作者、license等。 使用npm init -y命令来创建package.json,系统帮助完成各个信息的配置(也可以使用npm init命令手动一步步输入配置信息 )。
// 创建pack.json配置文件 npm init -y //本人的配置结果如下Wrote to /Users/xiayuanquan/Desktop/LoginManagerTestProject/node_modules/react-native-login-manager/package.json: { "name": "react-native-login-manager", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "https://gituhb.com/xiayuanquan/react-native-login-manager.git" }, "keywords": [], "author": "", "license": "ISC" }
3、如果采用系统帮助创建的pack.json不够完善,可以自己打开这个文件进行编辑。例如,如果我们的第三方库需要依赖,可以手动添加一个dependencies属性。如下所示:pack.json
{ " name ": "react-native-login-manager", "version": "1.0.0", "description": "this is a third part login library", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "https://gituhb.com/xiayuanquan/react-native-login-manager.git" }, "keywords": [], "author": "xiayuanquan", "license": "ISC", "dependencies": { }, }
4、好了,pack.json配置完毕后。就可以将我们的第三方库react-native-login-manager发布到npm上了。
// 发布第三方库 npm publish
如果发布失败,出现如下错误,说明发布采用的镜像源不匹配 (有可能中途不小心切换过)。错误如下:
// 错误日志如下 ........ npm notice === Tarball Details === npm notice name: react-native-login-manager npm notice version: 1.0.0 npm notice package size: 18.8 kB npm notice unpacked size: 41.6 kB npm notice shasum: 3e576dbb0d45bcc5dd5796928abba724552ab724 npm notice integrity: sha512-NNKLeNL5XJk1l[...]RR+oP0IKtgYBw== npm notice total files: 11 npm notice npm ERR! code E403 npm ERR! 403403 Forbidden - PUT https://registry.npm.taobao.org/react-native-login-manager - [no_perms] Private mode enable, only admin can publish this module npm ERR! 403 In most cases, you or one of your dependencies are requesting npm ERR! 403 a package version that is forbidden by your security policy. npm ERR! A complete log of this run can be found in: npm ERR! /Users/xiayuanquan/.npm/_logs/2020-01-18T08_08_46_345Z-debug.log
解决办法就是先切换源,然后登录npm,再发布。本人采用nrm管理的源,所以使用nrm切换。nrm管理npm源请参看我的这篇文章,nrm管理npm源。方法如下:
// 查看当前源 nrm current //显示结果:taobao //切换源 nrm use npm //显示结果:Registry has been set to: https://registry.npmjs.org///再查看 nrm current //显示结果:npm //登录npm npm login //显示结果: Username: xiayuanquan Password: Email: (this IS public) 137xxxx7163@163.com Logged in as xiayuanquan on https://registry.npmjs.org/. //重新发布npm publish //此时,发布成功,结果如下npm notice npm notice ?? react-native-login-manager@1.0.0 npm notice === Tarball Contents === npm notice 587B ios/LoginManager/LoginManager.h npm notice 264B ios/LoginManager/RCTConvert+MoveDiretion.h npm notice 129B index.js npm notice 428B package.json npm notice 7.6kB ios/LoginManager/LoginManager.m npm notice 725B ios/LoginManager/RCTConvert+MoveDiretion.m npm notice 10.8kB ios/LoginManager.xcodeproj/project.pbxproj npm notice 238B ios/LoginManager.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist npm notice 347B ios/LoginManager.xcodeproj/xcuserdata/xiayuanquan.xcuserdatad/xcschemes/xcschememanagement.plist npm notice 20.4kB ios/LoginManager.xcodeproj/project.xcworkspace/xcuserdata/xiayuanquan.xcuserdatad/UserInterfaceState.xcuserstate npm notice 157B ios/LoginManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata npm notice === Tarball Details === npm notice name: react-native-login-manager npm notice version: 1.0.0 npm notice package size: 18.8 kB npm notice unpacked size: 41.7 kB npm notice shasum: 74fbf2900e983bc15ad78ef7c62f56c46b331fb3 npm notice integrity: sha512-gmkR+gIETJabT[...]nG2SwO1ly+Pvg== npm notice total files: 11 npm notice + react-native-login-manager@1.0.0
发布成功后,邮箱会收到通知,如“ Successfully published react-native-login-manager@1.0.0”。也可以登录npm网站进行查看:https://www.npmjs.com。如下所示:
5、至此,我们已经成功把module发布到了npmjs.org。当然,我们也需要将我们的代码发布到github。
// 来取分支 git pull origin master // 添加文件 git add . // 提交日志 git commit -m ‘add all files of project‘//提交分支 git push origin master
五、验证
1、创建一个新的RN项目进行测试。如下所示:
// 创建RN项目 react-native init TestThirdPart --version 0.44.3
2、安装react-native-login-manager第三方库。如下所示:
// 安装库 npm install react-native-login-manager --save
3、将第三方库链接到RN项目中。如下所示:
// 链接第三方库 react-native link react-native-login-manager
4、使用xcode打开项目。如下所示:
5、测试结果。如下所示:
/* * * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from ‘ react ‘ ; import { AppRegistry, StyleSheet, View } from ‘ react-native ‘ ; import LoginManager from ‘ react-native-login-manager ‘ ; // 使用自定义的react-native-login-manager第三方库的模块方法 LoginManager.auth("13710371234"); //使用LoginManager模块类的监听通知const RCTDeviceEventEmitter = require(‘RCTDeviceEventEmitter‘); let subscription = RCTDeviceEventEmitter.addListener(‘orientationDidChange‘, (dimensions) => { Object.keys(dimensions).forEach(key => console.log(key, dimensions[key])); }); //subscription.remove(); export defaultclass TestThirdPart extends Component { render() { return ( <View style={styles.container}> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: ‘center‘, alignItems: ‘center‘, backgroundColor: ‘#F5FCFF‘, } }); AppRegistry.registerComponent(‘TestThirdPart‘, () => TestThirdPart);
// 日志如下 ....... 2020-01-1817:35:58.759817+0800 TestThirdPart[96482:2177939] RCTBridge required dispatch_sync to load RCTDevSettings. This may lead to deadlocks [17:35:41] -[LoginManager code:] [第34行] -[LoginManager code:]---获取验证---- [17:35:41] -[LoginManager code:] [第35行] account----137103712342020-01-1817:36:15.866355+0800 TestThirdPart[96482:2177905] [] nw_socket_handle_socket_event [C3.1:1] Socket SO_ERROR [61: Connection refused] 2020-01-1817:36:15.868757+0800 TestThirdPart[96482:2177905] [] nw_socket_handle_socket_event [C3.2:1] Socket SO_ERROR [61: Connection refused] 2020-01-1817:36:15.870211+0800 TestThirdPart[96482:2177912] [] nw_connection_get_connected_socket [C3] Client called nw_connection_get_connected_socket on unconnected nw_connection 2020-01-1817:36:15.870855+0800 TestThirdPart[96482:2177912] TCP Conn 0x600000cd8cc0 Failed : error 0:61 [61] 2020-01-1817:36:15.888 [info][tid:main][RCTRootView.m:295] Running application TestThirdPart ({ initialProps = { }; rootTag = 1; }) 2020-01-1817:36:15.888347+0800 TestThirdPart[96482:2177597] Running application TestThirdPart ({ initialProps = { }; rootTag = 1; }) 2020-01-18 17:36:15.891 [info][tid:com.facebook.react.JavaScript] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 17:36:15.891136+0800 TestThirdPart[96482:2177939] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 17:36:15.891 [info][tid:com.facebook.react.JavaScript] ‘orientation‘, ‘Portrait‘ 2020-01-18 17:36:15.891625+0800 TestThirdPart[96482:2177939] ‘orientation‘, ‘Portrait‘ 2020-01-18 17:36:15.892 [info][tid:com.facebook.react.JavaScript] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 17:36:15.892121+0800 TestThirdPart[96482:2177939] ‘Dimensions‘, { width: 375, scale: 2, height: 667 } 2020-01-18 17:36:15.892 [info][tid:com.facebook.react.JavaScript] ‘orientation‘, ‘Portrait‘ 2020-01-18 17:36:15.892490+0800 TestThirdPart[96482:2177939] ‘orientation‘, ‘Portrait‘ ........
六、完结
至此,一个真正的ReactNative第三方库开发完成。累死我了。。。。
发布)' ref='nofollow'>ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布)
原文:https://www.cnblogs.com/XYQ-208910/p/12208955.html
内容总结
以上是互联网集市为您收集整理的ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布)全部内容,希望文章能够帮你解决ReactNative: 将自定义的ReactNative组件制作成第三方库的详细流程(制作-->发布)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。