Skip to main content

为你的应用创建一个库模块

¥Create a Library for Your Module

React Native 拥有一个丰富的库生态系统来解决常见问题。我们在 reactnative.directory 网站中收集了 React Native 库,这是每个 React Native 开发者都值得收藏的绝佳资源。

¥React Native has a florid ecosystem of libraries to solve common problems. We collect React Native libraries in the reactnative.directory website, and this is a great resource to bookmark for every React Native developer.

有时,你可能正在处理一个值得在单独的库中提取以供代码重用的模块。这可以是你想要在所有应用中重用的库、你想要作为开源组件分发给生态系统的库,甚至是你想要出售的库。

¥Sometimes, you might be working on a module that is worth extracting in a separate library for code reuse. This can be a library that you want to reuse in all your apps, a library that you want to distribute to the ecosystem as an open source component, or even a library you'd like to sell.

在本指南中,你将了解:

¥In this guide, you'll learn:

  • 如何将模块提取到库中

    ¥how to extract a module into a library

  • 如何使用 NPM 分发库

    ¥how to distribute the library using NPM

将模块提取到库中

¥Extract the Module into a Library

你可以使用 create-react-native-library 工具创建一个新库。此工具设置一个包含所有所需样板代码的新库:所有配置文件和各个平台所需的所有文件。它还附带一个漂亮的交互式菜单,指导你完成库的创建。

¥You can use the create-react-native-library tool to create a new library. This tool sets up a new library with all the boilerplate code that is needed: all the configuration files and all files required by the various platforms. It also comes with a nice interactive menu to guide you through the creation of the library.

要将模块提取到单独的库中,你可以按照以下步骤操作:

¥To extract a module into a separate library, you can follow these steps:

  1. 创建新库

    ¥Create the new library

  2. 将代码从应用移动到库

    ¥Move the code from the App to the Library

  3. 更新代码以反映新结构

    ¥Update the code to reflect the new structure

  4. 发布它。

    ¥Publish it.

1. 创建一个库

¥ Create a Library

  1. 通过运行以下命令开始创建过程:

    ¥Start the creation process by running the command:

npx create-react-native-library@latest <Name of Your Library>
  1. 为你的模块添加名称。它必须是有效的 npm 名称,因此应该全部小写。你可以使用 - 来分隔单词。

    ¥Add a name for your module. It must be a valid npm name, so it should be all lowercase. You can use - to separate words.

  2. 为包添加描述。

    ¥Add a description for the package.

  3. 继续填写表格,直到到达问题 "你要开发哪种类型的库?"

    ¥Continue filling the form until you reach the question "What type of library do you want to develop?"

What type of Library

  1. 为了本指南的目的,请选择 Turbo 模块选项。请注意,你可以为新架构和旧架构创建库。

    ¥For the sake of this guide, select the Turbo module option. Notice that you can create libraries for both New Architecture and Legacy Architecture.

  2. 然后,你可以选择是否要访问平台的库(Kotlin 和 Objective-C)或共享 C++ 库(适用于 Android 和 iOS 的 C++)。

    ¥Then, you can choose whether you want a library that access the platform (Kotlin & Objective-C) or a shared C++ library (C++ for Android and iOS).

  3. 最后,选择 Test App 作为最后一个选项。此选项使用已在库文件夹中配置的单独应用创建库。

    ¥Finally, select the Test App as last option. This option creates the library with a separate app already configured within the library folder.

交互式提示完成后,该工具会创建一个文件夹,其结构在 Visual Studio Code 中如下所示:

¥Once the interactive prompt is done, the tool creates a folder whose structure looks like this in Visual Studio Code:

Folder structure after initializing a new library.

请随意探索为你创建的代码。但是,最重要的部分:

¥Feel free to explore the code that has been created for you. However, the most important parts:

  • android 文件夹:这是 Android 代码所在的位置

    ¥The android folder: this is where the Android code lives

  • cpp 文件夹:这是我们的 c++ 代码所在的位置

    ¥The cpp folder: this is where we the c++ code lives

  • ios 文件夹:这是我们的 iOS 代码所在的位置

    ¥The ios folder: this is where we the iOS code lives

  • src 文件夹:这是 JS 代码所在的位置。

    ¥The src folder: this is where the JS code lives.

package.json 已配置了我们提供给 create-react-native-library 工具的所有信息,包括包的名称和描述。请注意,package.json 也已配置为运行 Codegen。

¥The package.json is already configured with all the information that we provided to the create-react-native-library tool, including the name and the description of the package. Notice that the package.json is also already configured to run Codegen.

  "codegenConfig": {
"name": "RN<your module name>Spec",
"type": "all",
"jsSrcsDir": "src",
"outputDir": {
"ios": "ios/generated",
"android": "android/generated"
},
"android": {
"javaPackageName": "com.<name-of-the-module>"
}
},

最后,该库已经包含所有基础架构,可让该库与 iOS 和 Android 链接。

¥Finally, the library contains already all the infrastructure to let the library be linked with iOS and Android.

2. 从你的应用复制代码

¥ Copy the Code over from Your App

本指南的其余部分假设你的应用中有一个本地 Turbo Native 模块,该模块按照网站中其他指南中显示的指导原则创建:平台特定的 Turbo Native 模块或 跨平台 Turbo Native 模块。但它也适用于组件和旧架构模块和组件。你必须调整需要复制和更新的文件。

¥The rest of the guide assumes that you have a local Turbo Native Module in your app, created following the guidelines shown in the other guides in the website: platform specific Turbo Native Modules, or cross-platform Turbo Native Modules. But it works also for Components and legacy architecture modules and components. You'll have to adapt the files you need to copy and update.

  1. [对于旧架构模块和组件不需要] 将应用中 specs 文件夹中的代码移动到 create-react-native-library 文件夹创建的 src 文件夹中。

    ¥[Not required for legacy architecture modules and components] Move the code you have in the specs folder in your app into the src folder created by the create-react-native-library folder.

  2. 更新 index.ts 文件以正确导出 Turbo Native Module spec,以便可以从库中访问它。例如:

    ¥Update the index.ts file to properly export the Turbo Native Module spec so that it is accessible from the library. For example:

import NativeSampleModule from './NativeSampleModule';

export default NativeSampleModule;
  1. 复制原生模块:

    ¥Copy the native module over:

    • android/src/main/java/com/<name-of-the-module> 中的代码替换为你在应用中为原生模块编写的代码(如果有)。

      ¥Replace the code in the android/src/main/java/com/<name-of-the-module> with the code you wrote in the app for your native module, if any.

    • 用你在应用中为原生模块编写的代码(如果有)替换 ios 文件夹中的代码。

      ¥Replace the code in the ios folder with the code you wrote in your app for your native module, if any.

    • 用你在应用中为原生模块编写的代码(如果有)替换 cpp 文件夹中的代码。

      ¥Replace the code in the cpp folder with the code you wrote in your app for your native module, if any.

  2. [对于旧架构模块和组件不需要] 将所有引用从以前的规范名称更新为新的规范名称,即在库的 package.jsoncodegenConfig 字段中定义的名称。例如,如果在应用 package.json 中将 AppSpecs 设置为 codegenConfig.name,而在库中它被称为 RNNativeSampleModuleSpec,则必须将每次出现的 AppSpecs 替换为 RNNativeSampleModuleSpec

    ¥[Not required for legacy architecture modules and components] Update all the references from the previous spec name to the new spec name, the one that is defined in the codegenConfig field of the library's package.json. For example, if in the app package.json you set AppSpecs as codegenConfig.name and in the library it is called RNNativeSampleModuleSpec, you have to replace every occurrence of AppSpecs with RNNativeSampleModuleSpec.

就是这样!你已将所有必需的代码从你的应用移出并移到单独的库中。

¥That's it! You have moved all the required code out of your app and in a separate library.

测试你的库

¥Testing your Library

create-react-native-library 附带一个有用的示例应用,该应用已配置为与库正常工作。这是一种很好的测试方法!

¥The create-react-native-library comes with an useful example application that is already configured to work properly with the library. This is a great way to test it!

如果你查看 example 文件夹,你可以找到与你可以从 react-native-community/template 创建的新 React Native 应用相同的结构。

¥If you look at the example folder, you can find the same structure of a new React Native application that you can create from the react-native-community/template.

要测试你的库:

¥To test your library:

  1. 导航到 example 文件夹。

    ¥Navigate to the example folder.

  2. 运行 yarn install 以安装所有依赖。

    ¥Run yarn install to install all the dependencies.

  3. 仅适用于 iOS,你需要安装 CocoaPods:cd ios && pod install

    ¥For iOS only, you need to install CocoaPods: cd ios && pod install.

  4. example 文件夹使用 yarn android 构建并运行 Android。

    ¥Build and run Android with yarn android from the example folder.

  5. example 文件夹使用 yarn ios 构建并运行 iOS。

    ¥Build and run iOS with yarn ios from the example folder.

将你的库用作本地模块

¥Use your library as a Local Module

在某些情况下,你可能希望将你的库重用为应用的本地模块,而不将其发布到 NPM。

¥There are some scenario where you might want to reuse your library as a local module for your applications, without publishing it to NPM.

在这种情况下,你可能会遇到这样的情况:你的库作为应用的兄弟。

¥In this case, you might end up in a scenario where you have your library sitting as a sibling of your apps.

Development
├── App
└── Library

在这种情况下,你也可以使用用 create-react-native-library 创建的库。

¥You can use the library created with create-react-native-library also in this case.

  1. 通过导航到 App 文件夹并运行 yarn add ../Library,将你的库添加到你的应用中。

    ¥add you library to your app by navigating into the App folder and running yarn add ../Library.

  2. 仅适用于 iOS,请在 App/ios 文件夹中导航并运行 bundle exec pod install 以安装你的依赖。

    ¥For iOS only, navigate in the App/ios folder and run bundle exec pod install to install your dependencies.

  3. 更新 App.tsx 代码以将代码导入库中。例如:

    ¥Update the App.tsx code to import the code in your library. For example:

import NativeSampleModule from '../Library/src/index';

如果你现在运行应用,Metro 将找不到它需要提供给应用的 JS 文件。这是因为 metro 将从 App 文件夹开始运行,并且它无法访问位于 Library 文件夹中的 JS 文件。为了解决这个问题,让我们更新 metro.config.js 文件,如下所示

¥If you run your app right now, Metro would not find the JS files that it needs to serve to the app. That's because metro will be running starting from the App folder and it would not have access to the JS files located in the Library folder. To fix this, let's update the metro.config.js file as it follows

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**

* Metro configuration

* https://rn.nodejs.cn/docs/metro

* * @type {import('metro-config').MetroConfig}
*/
+ const path = require('path');

- const config = {}
+ const config = {
+ // Make Metro able to resolve required external dependencies
+ watchFolders: [
+ path.resolve(__dirname, '../Library'),
+ ],
+ resolver: {
+ extraNodeModules: {
+ 'react-native': path.resolve(__dirname, 'node_modules/react-native'),
+ },
+ },
+};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

watchFolders 配置告诉 Metro 监视一些其他路径中的文件和更改,在本例中是 ../Library 路径,其中包含你需要的 src/index 文件。需要 resolver 属性才能将应用使用的 React Native 代码提供给库。库可能会引用并导入 React Native 中的代码:如果没有额外的解析器,库中的导入将失败。

¥The watchFolders configs tells Metro to watch for files and changes in some additional paths, in this case to the ../Library path, which contains the src/index file you need. The resolverproperty is required to feed to the library the React Native code used by the app. The library might refer and import code from React Native: without the additional resolver, the imports in the library will fail.

此时,你可以照常构建和运行你的应用:

¥At this point, you can build and run your app as usual:

  • example 文件夹使用 yarn android 构建并运行 Android。

    ¥Build and run Android with yarn android from the example folder.

  • example 文件夹使用 yarn ios 构建并运行 iOS。

    ¥Build and run iOS with yarn ios from the example folder.

发布 NPM 上的库

¥Publish the Library on NPM

由于 create-react-native-library,在 NPM 上发布所有内容的设置已经到位。

¥The setup to publish everything on NPM is already in place, thanks to create-react-native-library.

  1. 在你的模块 yarn install 中安装依赖。

    ¥Install the dependencies in your module yarn install.

  2. 构建运行 yarn prepare 的库。

    ¥Build the library running yarn prepare.

  3. 使用 yarn release 发布它。

    ¥Release it with yarn release.

过一会儿,你会在 NPM 上找到你的库。要验证这一点,请运行:

¥After a while, you'll find your library on NPM. To verify that, run:

npm view <package.name>

其中 package.name 是你在初始化库期间在 package.json 文件中设置的 name

¥where package.name is the name you set up in the package.json file during the initialization of the library.

现在,你可以通过运行以下命令将库安装到你的应用中:

¥Now, you can install the library in your application by running:

yarn add <package.name>
注意

仅适用于 iOS,每当你安装带有一些原生代码的新模块时,都必须重新安装 CocoaPods,方法是运行 bundle exec pod install(推荐)或 pod install(如果你不使用 Ruby 的 Bundler(不推荐))。

¥For iOS only, whenever you install a new module with some native code, you have to reinstall CocoaPods, by running bundle exec pod install (recommended) or pod install if you are not using Ruby's Bundler (not recommended).

恭喜!你发布了第一个 React Native 库。

¥Congratulations! You published your first React Native library.