捆绑和发布 NPM 库。解析所有依赖项并将它们包含到包中是否很常见?

bundling and publishing an NPM library. Is it common to resolve all dependencies and include them into the bundle?

我的任务是开发带有自定义组件(在本例中为 React 组件)的 NPM 包,该组件使用其他依赖项,例如 plate、slate 等。

我正在准备输出 dist,但我不清楚这样做的最佳做法是什么: 是否应该解决所有依赖项并将其捆绑到一个大的 .js 文件中,还是可以忽略? (我在这里使用汇总解析)。恐怕这会产生一个巨大的文件,包括所有依赖项的来源,但正如我所说,我真的不熟悉这个过程......

另一方面,不解决此类依赖关系并让组件的最终使用者这样做是否很常见? (我这里只是假设)

一切都是关于利弊……以及什么是可能的。例如 React 本身在整个项目中只能存在于一个版本中,所以你永远不应该包含它。

需要但未包含的依赖项应作为 peerDependencies 添加到您的 package.json 中,消费者有责任下载它们。包含依赖项(如 dependencies 这样它们将被消费者自动下载)的缺点是消费者的包可能比它需要的更大。在这里你应该考虑谁会消费它;它是供贵组织内部使用还是 public 使用?你知道它将被使用的上下文吗?最好不要包含依赖项,因为它会为消费者生成更小的结果包,但如果消费者的构建环境中不太可能存在依赖项,您不妨将其添加到您的包中。您要避免的情况是您的包裹包含消费者已经在使用的同一包裹的不同版本;那么生成的包可能包含许多代码的两个版本,这些代码可能会减少到一个版本(如果消费者使用的版本和您的包使用的版本兼容)。当然,与小的不常见依赖项相比,所有这一切都可能变得更糟,并且更可能出现大的常见依赖项。

例如:在我的组织中,我们使用 Material-UI。我们有一个包含使用 Material-UI 的 React 组件的包,我们在其他项目中使用它。由于 Material-UI 将始终出现在项目中,因此将其包含在包中是一种不好的做法,尽管这会给消费者(我们)带来更高的责任,使包的不同版本与任何版本的 Material-UI 我们正在适用的项目中使用。给定另一个消费上下文,将其包含在包中可能更有意义。

根据我的说法,你永远不应该捆绑你的包裹,因为它会让 tree shaking 对消费者来说更加复杂。这适用于 esm 包(cjs 不是 tree-shakeable)。另一方面,在 cjs 中,捆绑包是毁灭性的,因为它阻止消费者进行更具体的导入以避免导入大量未使用的代码,例如

import Comp from "package/Component"

而不是

import { Comp } from "package"