如何将 React Native 组件发布到 NPM 上——比你认为的要简单(翻译)

2019-03-26

前言

本文的原作者是 Colby Miller,文章源链接为 How to publish a React Native component to NPM — it’s easier than you think,我将其翻译成中文。

你想向开源社区做贡献吗?那很赞!帮助想当年轻的 React Native 社区成长是一件很棒的事情!

当我在不久前打算进行这项任务的时候,我发现没有太多讲怎么把 React Native 组件发布到 NPM 上的材料。因此我希望这篇文章能帮助别人让这个过程变得容易一些。

注:下面的实例代码均来自 react-native-progress-steps 这是我的第一个 NPM 包。

在我们开始之前,首先要注册一个 NPM 账号。你可以在这里注册。

初始化设置

首先,创建一个目录,React Native 组件将会位于这个目录中。

mkdir <folder_name> && cd <folder_name>

# For example
mkdir my-component && cd my-component

注:为了保持文章简洁,我假设你已经安装了 Node 和 NPM。如果没有的话,请参见这篇文档

进入创建的目录后,我们需要通过 npm init 命令来初始化 NPM 包。

这会创建一个 package.json 文件,它内部有一些重要的关于 React Native 组件的元信息。

命令会询问一系列问题,包括包名、版本、描述、关键字等等。

重要:当被询问入口点(entry point)的时候,一定要输入 index.js 并回车。这会是导出你的主组件的文件。

package.json:

{
  "name": "react-native-progress-steps",
  "version": "1.0.0",
  "description": "A simple and fully customizable React Native component that implements a progress stepper UI.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/colbymillerdev/react-native-progress-steps.git"
  },
  "keywords": [
    "react-native",
    "react-component",
    "react-native-component",
    "react",
    "react native",
    "mobile",
    "ios",
    "android",
    "ui",
    "stepper",
    "progress",
    "progress-steps"
  ],
  "author": "Colby Miller",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/colbymillerdev/react-native-progress-steps/issues"
  },
  "homepage": "https://github.com/colbymillerdev/react-native-progress-steps#readme"
}

工程结构

下一步是为你的 React Native 组件设置一个目录结构。

这完全取决于你,下面我分享一下我的简单示例:

你会注意到有些文件不是我们创建的。我们后面会解释他们。

首先我们创建 index.js 文件,这个文件最为重要,它的作用是导出/导入你的组件。

将当且目录切到项目根目录,并执行命令 touch index.js

这个文件的内容有多种编写方法:

  • 直接在 index.js 中编写组件,并将它导出
  • 在单独的 JavaScript 文件中编写组件,在 index.js 中导出
  • 最后一种是,创建多个组件和容器的 JavaScript 文件,在 index.js 中导出必要的。在下面的示例中,我采用这个方法:

index.js:

import ProgressSteps from './src/ProgressSteps/ProgressSteps';
import ProgressStep from './src/ProgressSteps/ProgressStep';

export { ProgressSteps, ProgressStep };

不论采用哪种方法,这个文件最终导出的,是使用这个 APP 的库最终导入并展示的。这个很重要需要记住。

import { ProgressSteps, ProgressStep } from 'react-native-progress-steps';

依赖

为了让我们的 React Native 组件正常工作,我们需要决定使用那些依赖。

依赖分为三种类型:

  • peerDependencies: 组件需要这些依赖才能运行,他们被认为是已经安装在 APP 中。一个例子就是 react-native 本身。但是,在 React Native 的场景下,不需要把 react-native 作为一个 peer dependency。
  • dependencies: 这也是组件需要它们才能运行的依赖。但是你不用假设 APP 已经安装了这些依赖。一些例子包括 lodashprop-types
  • devDependencies: 这些依赖一看就知道。它们是在开发 React Native 组件时需要的依赖。例子包括你的 linter、测试框架和 babel。

安装 Babel 依赖

我们的下一步是将我们的组件与 Babel 建立关联。我们可以简单地通过安装下面的 dev dependency 完成这一步:

npm install metro-react-native-babel-preset --save-dev

安装完成后,我们要创建一个 .babelrc 并添加如下内容:

{
    "presets": ["module:metro-react-native-babel-preset"]
}

创建 .gitignore 和 .npmignore

最后一步是创建标准的 .gitignore.npmignore,遵循最佳实践。这会避免在发布到 NPM 时遇到问题。

.gitignore:

# Logs
*.log
npm-debug.log

# Runtime data
tmp
build
dist

# Dependency directory
node_modules

.npmignore:

# Logs
*.log
npm-debug.log

# Dependency directory
node_modules

# Runtime data
tmp

# Examples (If applicable to your project)
examples

测试

通常,在发布到 NPM 之前,我们可以直接将我们的包本地连接到 APP 上。

这可以在包的根目录下使用 npm link 命令完成。之后,跳转到 APP 目录下,再输入 npm link <package-name> 之后再输入 npm install 完成连接。

但是,在截止写本文的时间为止,React Native 和 npm link 命令还没发很好地一起工作。

到目前为止,我找到了两个解决这个问题的方法:

① 使用本地路径在应用中安装包

要完成这个,进入 APP 目录并使用路径直接安装包:

npm i <path_to_project>

# For example
npm i ../my-component

当包代码改动之后,需要重新进入 APP 的目录重新安装依赖。

这个方法不太理想,但是它可以工作。

② 使用 npm pack 创建一个 Example 目录

npm pack 命令是一种将你的 React Native 组件打包的好方法,并且是能够测试的。

它会创建一个一个 .tgz 文件,之后被安装到一个线程的 APP 中。

首先在包的根目录创建一个 /examples 目录,这个目录是一个 React Native 应用,主要目的是展示你的示例。

这个目录可以通过 react-native init examples 命令创建。

注意:这需要你的电脑上已经安装 React Native。你可以参见 Facebook 的指南

完成之后,执行 npm pack 命令,会创建一个文件,文件名类似于 package-name-0.0.0.tgz

之后进入 /examples 目录,安装你的组件,通过执行 npm i ../package-name-0.0.0.tgz 或者 yarn add ../package-name-0.0.0.tgz。记住分别替换 package-name0.0.0

创建一个 JavaScript 文件来展示你的组件。在本例中,我们称其为 ExampleOne.js。需要指出的是,应该在这个文件中导入前面用 yarn 或 npm 安装的组件。

一但文件被创建,打开 App.js 并导入/导出示例文件。

这个文件中导出的内容是在模拟器或设备上运行项目时显示的内容。

App.js:

import ExampleOne from './ExampleOne'

export default ExampleOne;

最后,我们可以使用 react-native run-iosreact-native run-android 运行应用。

现在我们应该能够看到我们的组件并正确地测试它。

在你修改了 NPM 包之后,记住需要执行 npm pack 指令,之后进入 /examples 目录执行 npm installyarn add

这种方法带来的好处是,别的用户可以运行你的示例工程。这样他们不用再应用中导入组件,就能先使用组件效果。同时,.tgz 文件也能很容易地在协作者之间共享。

发布到 NPM

最后,我们已经准备好把我们的 React Native 组件分享到超赞的开源社区了!

发布非常简单快速。只需要使用 npm login 登录 NPM 账号,之后使用 npm publish 进行发布。

有一点需要注意的是 NPM 要求我们每次发布前递增版本号。

结论

在本文中我们总结了大量材料。如果你遇到问题请再下面评论提问。

感谢阅读,我期待你的创造!

react-native-progress-steps 也欢迎贡献,PR 建议都欢迎提出!

译者注

在读完后,我对 examples 文件夹还有一点疑问。

在使用《使用 npm pack 创建一个 Example 目录》一节中通过 react-native init examples 命令创建工程,但在项目的实际目录下并非这样,它不是一个 React Native 工程。

我目前的猜测是作者没有提交 examples 下的所有文件,而是只提交了必要的文件。