【问题标题】:bundling and publishing an NPM library. Is it common to resolve all dependencies and include them into the bundle?捆绑和发布 NPM 库。解析所有依赖项并将它们包含到包中是否很常见?
【发布时间】:2022-12-18 19:04:26
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript npm bundle rollup npm-publish


    【解决方案1】:

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

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

    举个例子:在我的组织中,我们使用 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"
    

    【讨论】:

    • 太棒了,谢谢你的解释。我将深入研究您提到的概念。
    【解决方案2】:

    几乎没有充分的理由将依赖项嵌入到库包中。这就是您最终在 Web 应用程序中获得多个依赖项副本的方式。充其量,网络应用程序的捆绑包最终会变得不必要地臃肿。在最坏的情况下,依赖项在重复时会中断(例如 React),从而产生各种意想不到的行为。

    防止依赖重复的可靠方法是完全避免捆绑库。如果您检查任何 Web 应用程序项目中的 node_modules 文件夹,您可能会发现许多未捆绑的第三方依赖项。他们没有捆绑不会对您的网络应用程序产生影响。这证明库捆绑是毫无意义的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-05
      • 2015-03-12
      • 1970-01-01
      • 2019-04-16
      • 2019-06-06
      • 2015-10-04
      • 1970-01-01
      相关资源
      最近更新 更多