关于javascript:Bower和NPM有什么区别?

What is the difference between Bower and npm?

bowernpm的根本区别是什么?只想要简单明了的东西。我看到我的一些同事在他们的项目中可以互换使用bowernpm


所有的包管理器都有许多缺点。你只需要选择你可以生活的地方。

历史

NPM开始管理node.js模块(这就是默认情况下软件包进入node_modules的原因),但与browserify或webpack结合使用时,它也适用于前端。

Bower是专为前端设计的,并考虑到这一点进行了优化。

回购规模

NPM比Bower大得多,包括通用的javascript(如用于国家信息的country-data或用于对前端或后端可用的函数进行排序的sorts)。

鲍尔的包裹数量要少得多。

风格处理等

包厢包括款式等。

NPM专注于JavaScript。样式可以单独下载,也可以由类似于npm-sasssass-npm的东西来要求。

依赖项处理

最大的区别是,NPM执行嵌套依赖(但默认情况下是扁平的),而Bower需要扁平的依赖树(将依赖解析的负担推给用户)。

嵌套的依赖树意味着依赖关系可以有自己的依赖关系,也可以有自己的依赖关系,等等。这允许两个模块需要相同深度的不同版本,并且仍然可以工作。注意:由于NPM v3,依赖树在默认情况下是扁平的(节省空间),并且只在需要的地方嵌套,例如,如果两个依赖项需要它们自己的下划线版本。

有些项目同时使用Bower作为前端包,而NPM用于开发工具,如Yeoman、Grunt、Gulp、JShint、CoffeeScript等。

资源

  • 嵌套依赖项-深入了解节点模块的工作方式


这个答案是对辛德·索罗斯答案的补充。NPM和Bower的主要区别在于它们处理递归依赖关系的方式。请注意,它们可以在单个项目中一起使用。

关于NPM常见问题:(archive.org链接,2015年9月6日起)

It is much harder to avoid dependency conflicts without nesting
dependencies. This is fundamental to the way that npm works, and has
proven to be an extremely successful approach.

在鲍尔主页上:

Bower is optimized for the front-end. Bower uses a flat dependency
tree, requiring only one version for each package, reducing page load
to a minimum.

简而言之,核电站的目标是稳定。鲍尔的目标是将资源负荷降到最低。如果绘制依赖关系结构,您将看到:

NPM:

1
2
3
4
5
6
7
8
9
10
11
12
13
project root
[node_modules] // default directory for dependencies
 -> dependency A
 -> dependency B
    [node_modules]
    -> dependency A

 -> dependency C
    [node_modules]
    -> dependency B
      [node_modules]
       -> dependency A
    -> dependency D

如您所见,它以递归方式安装一些依赖项。依赖项A安装了三个实例!

Bower:

1
2
3
4
5
6
project root
[bower_components] // default directory for dependencies
 -> dependency A
 -> dependency B // needs A
 -> dependency C // needs B and D
 -> dependency D

在这里,您可以看到所有唯一的依赖关系都在同一级别上。

那么,为什么还要使用NPM呢?

可能依赖项B需要依赖项A的不同版本,而不是依赖项C。NPM安装了这两个版本的依赖项,因此它无论如何都可以工作,但Bower会给您带来冲突,因为它不喜欢重复(因为在网页上加载相同的资源效率非常低且成本高昂,也会导致一些严重的错误)。您必须手动选择要安装的版本。这可能会导致其中一个依赖项中断,但无论如何,这是您需要修复的问题。

因此,对于要在网页上发布的包(例如运行时,避免重复),常见的用法是bower;对于其他东西(例如测试、构建、优化、检查等),则使用npm(例如开发时间,在开发时间,重复不太受关注)。

NPM 3的更新:

与鲍尔相比,NPM 3的工作方式仍然不同。它将全局安装依赖项,但仅限于遇到的第一个版本。其他版本安装在树中(父模块,然后是节点模块)。

  • [节点模块]
    • DE1.A V1.0
    • DEPB V1.0
      • dep a v1.0(使用根版本)
    • DEC C V1.0
      • DEP A v2.0(此版本与根版本不同,因此将是嵌套安装)

更多信息,我建议阅读NPM 3的文档


TL;DR:日常使用中最大的区别不是嵌套的依赖关系…它是模块和全局的区别。好的。

我认为之前的海报已经很好地涵盖了一些基本的区别。(NPM对嵌套依赖项的使用确实对管理大型、复杂的应用程序非常有帮助,尽管我认为这不是最重要的区别。)好的。

然而,我很惊讶,没有人能明确解释鲍尔和NPM之间最基本的区别之一。如果你阅读上面的答案,你会看到"模块"这个词经常在NPM的上下文中使用。但这只是随便提到的,就好像它可能只是语法上的差异。好的。

但是模块与全局(或者模块与脚本)之间的区别可能是Bower和NPM之间最重要的区别。把所有东西都放在模块中的NPM方法要求您改变为浏览器编写JavaScript的方式,几乎可以肯定是为了更好。好的。鲍尔方法:全球资源,如标签

在根目录下,Bower将加载普通的旧脚本文件。无论这些脚本文件包含什么,Bower都将加载它们。这基本上意味着Bower就像在HTML的中包含所有的脚本一样。好的。

所以,你已经习惯了同样的基本方法,但是你得到了一些很好的自动化便利:好的。

  • 您以前需要在项目repo中包含JS依赖项(在开发过程中),或者通过cdn获取它们。现在,您可以在repo中跳过额外的下载权重,而有人可以快速执行bower install,并立即在本地获得他们需要的内容。
  • 如果Bower依赖项在它的bower.json中指定了它自己的依赖项,那么也将为您下载这些依赖项。

但除此之外,Bower不会改变我们编写JavaScript的方式。鲍尔加载的文件中的内容完全不需要更改。特别是,这意味着Bower加载的脚本中提供的资源(通常,但不总是)仍然被定义为全局变量,可以从浏览器执行上下文的任何位置获得。好的。NPM方法:通用JS模块,显式依赖注入

节点域中的所有代码(因此所有通过NPM加载的代码)都被构造为模块(特别是作为CommonJS模块格式的实现,或者现在作为ES6模块)。因此,如果您使用NPM来处理浏览器端的依赖关系(通过browserify或其他执行相同任务的方法),您将像节点那样构造代码。好的。

比我更聪明的人解决了"为什么是模块?"但是这里有一个胶囊摘要:好的。

  • 模块中的任何内容都被有效地命名为名称空间,这意味着它不再是一个全局变量,并且您不能无意中引用它。
  • 模块内的任何内容都必须有意注入特定的上下文(通常是另一个模块),以便使用它
  • 这意味着您可以在应用程序的各个部分中拥有相同外部依赖项(比如lodash)的多个版本,它们不会发生冲突/冲突。(这种情况经常发生,这令人惊讶,因为您自己的代码希望使用依赖项的一个版本,但是您的一个外部依赖项指定了另一个冲突的版本。或者您有两个外部依赖项,每个依赖项都需要不同的版本。)
  • 因为所有依赖项都是手动注入到一个特定的模块中的,所以很容易解释它们。您知道一个事实:"在处理这个问题时,我需要考虑的唯一代码就是我有意选择在这里注入的代码。"
  • 因为即使注入模块的内容也封装在分配给它的变量后面,并且所有代码都在有限的范围内执行,所以意外和冲突变得非常不可能。您的某个依赖项中的某个对象会意外地重新定义一个全局变量,而您没有意识到这一点,或者您会这样做,这种可能性非常小。(这是可能的,但你通常不得不用你的方式去做,比如window.variable。一个仍然容易发生的事故是分配this.variable,没有意识到this实际上是当前上下文中的window
  • 当您想要测试一个单独的模块时,您可以非常容易地知道:到底还有什么(依赖性)影响了模块内部运行的代码?而且,因为您显式地注入了所有内容,所以可以轻松地模拟这些依赖项。

对我来说,前端代码模块的使用可以归结为:在更窄的上下文中工作,这样更容易理解和测试,并且对正在发生的事情有更大的确定性。好的。

学习如何使用commonjs/node模块语法只需大约30秒。在将成为模块的给定JS文件中,首先声明要使用的任何外部依赖项,如下所示:好的。

var React = require('react');好的。

在文件/模块内部,您可以做您通常会做的任何事情,并创建一些您希望向外部用户公开的对象或函数,称之为myModule。好的。

在一个文件的末尾,导出您想与世界共享的任何内容,如下所示:好的。

module.exports = myModule;好的。

然后,要在浏览器中使用基于通用JS的工作流,您将使用browserify之类的工具来获取所有这些单独的模块文件,在运行时封装它们的内容,并根据需要将它们相互注入。好的。

而且,由于ES6模块(您很可能会使用Babel或类似软件在ES5中使用)得到广泛的认可,并且可以在浏览器或节点4.0中使用,因此我们也应该提到这些模块的良好概述。好的。

关于在这个面板中使用模块的模式的更多信息。好的。

编辑(2017年2月):Facebook的"纱线"是当今NPM的一个非常重要的潜在替代/补充:快速、确定性、离线包管理,建立在NPM给你的基础上。对于任何JS项目都值得一看,特别是因为它很容易将其换入/换出。好的。好啊。


2017 OCT更新

鲍尔终于被否决了。故事的结尾。

老一套的回答

来自Spotify的javascript开发者Mattias Petter Johansson:

In almost all cases, it's more appropriate to use Browserify and npm over Bower. It is simply a better packaging solution for front-end apps than Bower is. At Spotify, we use npm to package entire web modules (html, css, js) and it works very well.

Bower brands itself as the package manager for the web. It would be awesome if this was true - a package manager that made my life better as a front-end developer would be awesome. The problem is that Bower offers no specialized tooling for the purpose. It offers NO tooling that I know of that npm doesn't, and especially none that is specifically useful for front-end developers. There is simply no benefit for a front-end developer to use Bower over npm.

We should stop using bower and consolidate around npm. Thankfully, that is what is happening:

Module counts - bower vs. npm

With browserify or webpack, it becomes super-easy to concatenate all your modules into big minified files, which is awesome for performance, especially for mobile devices. Not so with Bower, which will require significantly more labor to get the same effect.

npm also offers you the ability to use multiple versions of modules simultaneously. If you have not done much application development, this might initially strike you as a bad thing, but once you've gone through a few bouts of Dependency hell you will realize that having the ability to have multiple versions of one module is a pretty darn great feature. Note that npm includes a very handy dedupe tool that automatically makes sure that you only use two versions of a module if you actually have to - if two modules both can use the same version of one module, they will. But if they can't, you have a very handy out.

(请注意,截至2016年8月,Webpack和Rollup被普遍认为优于Browserify。)


Bower维护一个单一版本的模块,它只试图帮助您选择正确/最好的模块。

Javascript dependency management : npm vs bower vs volo?

NPM对于节点模块更好,因为有一个模块系统,并且您在本地工作。Bower非常适合浏览器,因为目前只有全局范围,您希望对所使用的版本非常有选择性。


我的团队从鲍尔搬到了新产品管理公司,因为:

  • 程序性使用很痛苦
  • 鲍尔的界面不断变化
  • 一些功能,比如URL速记,完全被破坏了。
  • 在同一个项目中同时使用Bower和NPM很痛苦
  • 保持bower.json版本字段与git标签同步是很痛苦的。
  • 源代码管理!=包管理
  • CommonJS支持并不简单

有关更多详细信息,请参阅"为什么我的团队使用NPM而不是Bower"。


从http://ng-learn.org/2013/11/bower-vs-npm找到了这个有用的解释。/

On one hand npm was created to install modules used in a node.js environment, or development tools built using node.js such Karma, lint, minifiers and so on. npm can install modules locally in a project ( by default in node_modules ) or globally to be used by multiple projects. In large projects the way to specify dependencies is by creating a file called package.json which contains a list of dependencies. That list is recognized by npm when you run npm install, which then downloads and installs them for you.

On the other hand bower was created to manage your frontend dependencies. Libraries like jQuery, AngularJS, underscore, etc. Similar to npm it has a file in which you can specify a list of dependencies called bower.json. In this case your frontend dependencies are installed by running bower install which by default installs them in a folder called bower_components.

As you can see, although they perform a similar task they are targeted to a very different set of libraries.


对于许多使用node.js的人来说,Bower的一个主要好处是管理完全不是javascript的依赖项。如果他们使用编译为JavaScript的语言,则可以使用NPM来管理它们的一些依赖项。但是,并不是所有的依赖项都是node.js模块。有些编译为javascript的程序可能有奇怪的源语言特定的管理,当用户希望使用源代码时,将它们传递给javascript是一个不雅的选择。

并非NPM包中的所有内容都需要面向用户的JavaScript,但是对于NPM库包,至少其中一些应该是这样的。


Bower和NPM是JavaScript的包管理器。在我们应该使用Bower或NPM的地方有很多困惑。有些项目既有NPM又有Bower。在这里,我已经解释了这两个工具的用途,您将了解必须在哪里使用鲍尔,在哪里使用NPM。

凉亭

Bower是专为前端开发而创建的,并基于这一点进行了优化。它使用平面依赖树,每个包只需要一个版本,从而减少了页面负载。它主要是为了最小化资源负载。

Bower有一个名为bower.json的配置文件。在这个文件中,我们可以维护Bower的配置,比如我们需要哪些依赖项,以及许可证详细信息、描述、名称等。

Bower适用于jquery、Angular、React、Ember、Knockout、主干等前端包。

NPM(节点包管理器)

NPM最常用于管理node.js模块,但它也适用于前端。它使用嵌套的依赖关系树,这意味着依赖关系可以有自己的依赖关系,也可以有自己的依赖关系,等等。嵌套的依赖树意味着依赖关系可以有自己的依赖关系,也可以有自己的依赖关系,等等。这在服务器上非常好,您不必太在意空间和延迟。

这显然在前端没有那么好地工作,因为我们的项目中需要jquery。我们只需要jquery的一个副本,但是当另一个包需要jquery时,它将再次下载jquery的一个副本。这是NPM的主要缺点之一。

NPM有一个名为package.json的配置文件。在这个文件中,我们可以维护NPM的配置,比如我们需要哪些依赖项,以及许可证详细信息、描述、名称等。NPM提供依赖项和devdependencies。依赖项将下载并维护前端文件,如jquery、angular等。DevDependencies将下载和维护开发工具,如Grunt、Gulp、JShint等。

许多项目使用这两者的原因是,它们将Bower用于前端包,将NPM用于开发工具,如Grunt、Gulp、JShint等。