ios开发 热搜词demo_自己开发一个React Native 模块

fe5c1b2ab3659a9a0f2712ddaff7f4b1.png

大纲

  • 为什么需要 React Native Module
  • 如何创建一个 React Native的模块
  • 编写 Android Toast 功能模块
  • 如何调试 React Native 模块---------官方文档中未提及或者我没有找到,这里是我自己探索的
  • npm 发布一个 React Native 模块(外链接)

为什么需要 React Native Module

各位使用 React Native 时候是否会有碰到仅用React Native 提供的现有API 无法实现的功能。如微信登录、微信/支付宝支付,访问App的数据库SQLite,还有针对性能的提升等等。这些东西在使用React Native 现有的功能无法实现的时候,将需要开发React Native Moduel。当然也可以使用社区中第三方库,这些三方库也是 React Native Module 。

总之,React Native Module 是可以给JS层扩展一些新的功能,这些功能是现有React Native API无法实现的功能,需要与原生代码进行交互的部分。

如何创建一个 React Native的模块

通过官方文档的查阅和学习,知道可以使用 react-native-create-library 这个库来快速创建一个包含Android ,IOS,Windows 系统下的模块,这个模块并且可以直接使用react-native link 快速链接到现有的 React Native 的应用中。

下面将简单介绍如何安装使用 react-native-create-library。

  • 安装 react-native-create-library
# npm
npm install -g react-native-create-library

# yarn
yarn add -g react-native-create-library
  • 创建一个 React Native Module 模块
# 这样将创建一个具有 Android ios  windows 3个模块的 React Native Module
react-native-create-library demo 

# 这样将仅创建一个具有 Android ios 2个模块的 React Native Module
react-native-create-library demo --platforms android,ios

上面就是创建一个React Native Module 的简单介绍,更多关于 react-native-create-library 的使用请移步GitHub官方仓库。

编写 Android Toast 功能模块

这里是参考官网【Android 原生模块】,可以点击查看详情,下面是简单介绍。

  • 所有的Android 原生模块都是继承于ReactContextBaseJavaModule类。
  • ReactContextBaseJavaModule.getName 方法是将当前这个模块暴露给JavaScript层的名字
  • ReactContextBaseJavaModule.getContants 返回的Map对象,是暴露给JavaScript层的一些常量
  • 在ReactContextBaseJavaModule类中使用 @ReactMethod 注解导出一个方法给JavaScript
// 这是上面几个步骤的共同代码

// 这里定义一个类继承 ReactContextBaseJavaModule
public class RNToastModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;

  public RNToastModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }

  /**
   * 这里导出的字符串为当前模块的 JS 名称
   * 在js中获取到当前模块中如下获取到当前模块:
   * NativeModules.RNToast
   * NativeModules 为 import { NativeModules } from 'react-native'; 中的 NativeModules
   * @return
   */
  @Override
  public String getName() {
    return "RNToast";
  }

  /**
   * 这里返回的值会被JS模块当做常量来使用
   * 使用方式为
   *
   * NativeModules.RNToast.SHORT === Toast.LENGTH_SHORT
   * NativeModules.RNToast.LONG === Toast.LENGTH_LONG
   *
   * @return
   */
  @Nullable
  @Override
  public Map<String, Object> getConstants() {
    final Map<String, Object> constants = new HashMap<>();

    constants.put("SHORT", Toast.LENGTH_SHORT);
    constants.put("LONG", Toast.LENGTH_LONG);

    return  constants;
  }

  /**
   * 这里暴露一个方法给 React Native
   *
   * 在JS中使用方式为:
   *
   * NativeModules.RNToast.show(msg, duration); // duration 可以使用上面 getConstants 方法暴露出来的常量
   *
   * @param msg
   * @param duration
   */
  @ReactMethod
  public void show( String msg, int duration ){
    Toast.makeText(getReactApplicationContext(), msg, duration).show();
  }
}
  • 封装一个JavaScript模块
import { NativeModules } from "react-native";
// 下一句中的ToastExample即对应上文
// public String getName()中返回的字符串
export default NativeModules.RNToast;

经过上面几个简单的步骤就开发好了一个 React Native Module 模块,但是这里有一个重要的问题,开发的React Native Module 不可能每个都像Toast这个模块如此简单,应该如何在开发的过程中调试是一个重要的问题,不可能每次都发布到npm上来进行调试,每次发布调试也将影响他人正常使用该模块,而且也给开发带来了非常多不必要的麻烦,因此需要一个非常有效的调试方式,接下来将介绍如何调试React Native 模块。

如何调试 React Native 模块

基本思路为:既然是要调试 React Native 模块,就需要一个 React Native App,然后将自己写的React Native Module模块导入React Native App 中,并且启动App,修改Module,再次安装调试,这样一系列的操作。具体步骤如下:

  • 创建 React Native App
# 创建一个名为 toast_demo 的工程
react-native init toast_demo
# 等待命令的执行,执行完后安装依赖,启动服务,安装app到模拟器或者真机,这样完成了一个react native app的创建
  • 将 React Native Module 模块导入现有的App
# 先在 toast 工程中, yarn link 命令可以将toast工程导入全局,
# 在别的工程中使用yarn link react-native-toast 就可以使用当前的toast工程
# 为什么是 react-native-toast 而不是 toast,可以点开 toast > package.json文件
# 将会发现 toast 工程的 name 是 react-native-toast, 
# 前缀 react-native 是由 react-native-create-library 加上的。
# 因此这里是 react-native-toast 而不是 toast。
yarn link

# 在 toast_demo 工程中敲击yarn link react-native-toast,
# 再点开 toast_demo 工程下的node_modules 会发现 react-native-toast被
# 加载到toast_demo/node_modules里面了
yarn link react-native-toast

# react-native link 命令不用多说
react-native link react-native-toast

上面的事情都做完了你很开心的启动你的工程,并安装到手机上调试的时候会发现下面这个问题(unable to resolve module 'react-native-toast')

8ffba74d1e6577c0440a69b912d50c2e.png

这个问题主要导致的原因是React Native工程不支持 symlinks。怎么解决这个问题呢?

这里使用 haul , 这是一个用于开发 React Native App 的命令行工具。它可以很好的使用 Webpack 生态,以及支持热更新,不用每修改等待React Native 来重新编译,当然它也支持 symlinks ,所以可以使用 haul 来解决上面遇到的这个问题,具体使用方式可以查看官方 GitHub仓库,下面是简单介绍:

# 安装 haul
yarn add --dev haul

# 初始化 haul和安装haul的依赖,但是npx 不会准确的安装所有的依赖,因此在使用haul的时候可能会提示漏掉了某些库,
# 只要根据提示安装完所有的依赖即可
yarn haul init
# npm >= 5.2.0 :
npx haul init
# npm < 5.2.0 :
npm install -g npx
npx haul init

# 然后启动 haul 相关服务
yarn haul start --platform ios
# Or:
npx haul start --platform ios

我是使用 haul^1.0.0-rc.15 这个版本的 haul,会碰到这个issue中的问题,haul的作者有提供解决方案,修改haul.config.js 为一下内容。

import { createWebpackConfig } from "haul";

export default {
  webpack: env => {
    const config = createWebpackConfig({
      entry: './index.js',
    })(env);

    config.module.rules.some(rule => {
      if (rule.test && rule.test.source.includes('js')) {
        rule.use = [
          {
            loader: require.resolve('babel-loader'),
            options: {
              presets: [['module:metro-react-native-babel-preset', { enableBabelRuntime: false }]],
              plugins: [require.resolve('haul/src/utils/fixRequireIssues')],
            },
          },
        ];
        return true;
      }
    });
    return config;
  }
};

然后重新启动 haul, 将能够正常的运行React Native App 了。

修改 Android Studio 中 react-native-toast 中的代码将会直接映射到 toast 工程中,这是 symlinks 的功能,这个功能非常的方便调试和修改module。

(官方文档中未提及调试这块或者我没有找到,这里是我自己探索的,有更好的方式请各位告知)

开发好一个module,希望别人可以使用或者自己在下次工程中使用,这该怎么办呢?当然是将当前的react native module 发布到 npm 上,怎么发布请继续往下看。

npm 发布一个 React Native 模块(外链接)

这是其他博主写的npm包的创建和发布流程,主要使用 npm publish来发布和更新一个npm包,发布的npm包他人将可以使用npm或者yarn 进行下载和安装使用你写的模块。

以上就是开发一个 React Native Android Module 的过程,如果是IOS也可以类比这个流程来开发调试。

toast 工程样例

toast_demo 工程样例

【参考】

  • Native Modules Setup
  • React Native 中文官方文档 Android 原生模块
  • React Native: npm link local dependency, unable to resolve module
  • haul - Attempted to assign to readonly property
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值