еңЁеҸҜйҮҚ用组件еә“зҡ„`package.json`дёӯпјҢж·»еҠ `react`дҪңдёәдҫқиө–зҡ„жӯЈзЎ®ж–№ејҸжҳҜд»Җд№Ҳпјҹ

49

我制作了几个简单的可重复使用的React组件,并想知道在我的package.json中正确地包含一个对React的依赖项,以便使用npm发布。

我目前正在这样做:

假设我的组件将使用最新版本的React,并且我已经测试过它可以与该版本配合使用。 例如0.13.3

"peerDependencies": { 
  "react": "^0.13.3"
},
3个回答

104

对于可重用组件:

  1. peerDependenciesdevDependencies 中都要添加一个 react 依赖。
  2. 永远不要dependencies 中加入 react 依赖。

peerDependencies 指定您的可重用组件所支持/需要的 React 版本。使用 npm 2 时,这也会将 React 添加到要安装的模块列表中,但是在 npm 3 中不再如此。

devDependencies 确保在开发组件时运行 npm install 或在 Travis 或类似平台上运行测试时安装 React。

如果将 react 放在 dependencies 中,如果有人在自己的 package.json 中使用了不同版本的 React,则会导致安装多个版本的 React - 拥有多个版本的 React 不仅会使构建变得臃肿,还会导致不同版本试图相互交互时出错。


2
如果您在组件中这样做,如何使用require('react')?可能是因为我现在正在使用npm link链接到我的组件,但webpack无法解析我的组件的require('react') - Fiona Hopkins
2
看起来 npm linkpeerDependencies 不太顺畅。似乎使用 npm pack 进行本地测试并与 webpack 的 require 正确配合可以解决这个问题。 - Fiona Hopkins
1
prop-types 怎么样?我本来以为它也应该是 peerDependency,但我看到很多例子中它是 dependency - dralth

11
所选答案绝对是这里的规定方法,但我开始倾向于使用控制反转而不是依赖于npm同行依赖来获取我的库依赖项,它为我提供了很好的服务。
如果构建功能性库,则库更容易。似乎更容易维护导出单个函数的库,该函数接受一个包含其所有重要依赖项的对象,并导出包含每个库典型导出的对象。
图书馆“注入” lib / index.js
export default ({ React }) => {
  const InjectedComponent = props => (
    <p style={{color: props.color}}>This component has no React npm dependencies.</p>
  )

  /** other stuff */

  return { InjectedComponent }
}

应用程序

app.js

import React from 'react'
import { render } from 'react-dom'

/** Import the default export factory from our library */
import createInjectedComponent from 'injected'

/** Call the factory, passing its dependencies (guaranteed to match what we're bundling) and get back our component */
const { InjectedComponent } = createInjectedComponent({ React })

render(<InjectedComponent color="blue" />, document.getElementById('root'))
如果你的组件只能与特定版本的React或其他依赖项一起使用,可以在传递给React参数的版本上编写一些断言。总的来说,以这种方式构建库应该会减少因发布任何版本的React而出现新构建问题的可能性,并更重要的是确保您不会导致库消费者捆绑多个版本的React和其他大型库。这种模式与npm link非常搭配(我通常同时运行16个以上的npm链接库,并且在没有使用这种模式时遇到了问题)。
在您的主应用程序中,我建议始终将React、React DOM和您使用的任何React库组件拆分为供应商包(webpack),并在主包中将其标记为外部,以便您不会无意中捆绑两个版本。

这很棒。你有使用这种注入方法的图书馆示例吗? - Paul Razvan Berg
@PaulRazvanBerg 谢谢!我在自己的工作中很少见到这种方法的应用,但发现这种模式运行良好并避免了npm依赖问题。这种模式的缺点是,如果React有重大API更改,你的库可能不支持未来的版本,并且会静默失败。我建议在库中以防御性编写代码,并对你期望存在的React功能部分进行良好的断言。这是我一个库的示例:https://github.com/noderaider/react-redux-idle-monitor/blob/master/src/lib/index.js#L26 - cchamberlain

-3

你可以将react放在peerDependenciesdependencies中。区别在于,使用peerDependencies时,react仅会为使用你的包的包安装一次。如果将其放在dependencies中,则react将被安装两次,一次为使用你的包的包,另一次为你的包。

React本身似乎更喜欢peerDependencies。显然,你不希望在JavaScript捆绑包中有两个不同版本的react(如果使用dependencies,默认情况下会发生这种情况),但是使用npm dedupe很容易解决这个问题。

因此,没有正确的方法,peerDependenciesdependencies都可以工作。使用dependencies更符合node/NPM的方式,但是使用peerDependencies对于不知道npm dedupe及其必要性的你的包的用户更友好。


这已经过时了,因为npm 3只会在存在版本冲突时安装两个版本。 - Sterling Camden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接