bower
和npm
之间的根本区别是什么?只想要简单明了的东西。我见过我的一些同事在他们的项目中交替使用bower
和npm
。
答案 0 :(得分:1875)
所有包管理器都有许多缺点。你只需挑选你可以忍受的东西。
npm开始管理node.js模块(这就是默认情况下包进入node_modules
的原因),但是当与Browserify或WebPack结合使用时,它也适用于前端。
Bower仅针对前端创建,并针对此进行了优化。
npm远比bower大得多,包括通用JavaScript(如country-data
用于国家/地区信息,或sorts
用于排序可在前端或后端使用的功能。)
鲍尔的包装数量要少得多。
Bower包括款式等。
npm专注于JavaScript。样式可以单独下载,也可以通过npm-sass
或sass-npm
等方式下载。
最大的区别是npm执行嵌套依赖项(但默认情况下是平的),而Bower需要一个平面依赖树(将依赖项解析的负担放在用户身上)。
嵌套依赖树意味着您的依赖项可以拥有自己的依赖项,可以拥有自己的依赖项,依此类推。这允许两个模块需要相同描述的不同版本并且仍然有效。请注意,从npm v3开始,依赖关系树将默认为flat(节省空间),并且只在需要的地方嵌套,例如,如果两个依赖关系需要他们自己的Underscore版本。
有些项目同时使用Bower作为前端软件包,npm用于开发人员工具,如Yeoman,Grunt,Gulp,JSHint,CoffeeScript等。
答案 1 :(得分:355)
这个答案是Sindre Sorhus答案的补充。 npm和Bower之间的主要区别在于它们处理递归依赖的方式。请注意,它们可以在一个项目中一起使用。
关于npm FAQ:(2015年9月6日的archive.org链接)
在没有嵌套的情况下避免依赖冲突要困难得多 依赖。这是npm工作方式的基础,并且具有 事实证明这是一种非常成功的方法。
在Bower主页上
Bower针对前端进行了优化。 Bower使用扁平依赖 树,每个包只需要一个版本,减少页面加载 至少。
简而言之,npm旨在稳定。 Bower的目标是最小的资源负荷。如果你绘制出依赖关系结构,你会看到:
NPM:
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有三个已安装的实例!
鲍尔:
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的更新:
与Bower相比,npm 3仍然有所不同。它将全局安装依赖项,但仅适用于它遇到的第一个版本。其他版本安装在树中(父模块,然后是node_modules)。有关详细信息,建议您阅读docs of npm 3
答案 2 :(得分:264)
TL; DR:日常使用中最大的不同之处在于没有嵌套的依赖关系...它是模块和全局变量之间的区别。
我认为之前的海报已经涵盖了一些基本的区别。 (对于管理大型复杂应用程序,npm'对嵌套依赖项的使用确实非常有用,尽管我认为它不是最重要的区别。)
然而,我很惊讶,没有人明确解释过Bower和npm之间最基本的区别之一。如果你阅读上面的答案,你会看到单词' modules'经常在npm的上下文中使用。但随便提到它,好像它甚至只是一种语法差异。但模块与全局(或模块与'脚本')的这种区别可能是Bower和npm之间最重要的区别。 将所有内容放入模块中的npm方法要求您改变为浏览器编写Javascript的方式,几乎肯定会更好。
<script>
标签从根本上说,Bower是关于加载普通的脚本文件。无论这些脚本文件包含什么,Bower都会加载它们。这基本上意味着Bower就像将所有脚本包含在HTML <script>
中的普通<head>
中一样。
所以,您已经习惯了相同的基本方法,但是您获得了一些很好的自动化方便性:
bower install
并立即在本地获得所需内容。bower.json
中指定自己的依赖项,那么也会为您下载这些依赖项。但除此之外, Bower并没有改变我们编写javascript的方式。 Bower加载的文件里面的内容根本不需要改变。特别是,这意味着Bower加载的脚本中提供的资源(通常但不总是)仍然被定义为全局变量,可从浏览器执行上下文中的任何位置获得。
Node land中的所有代码(以及因此通过npm加载的所有代码)都被构造为模块(具体地,作为CommonJS module format的实现,或者现在,作为ES6模块)。因此,如果您使用NPM来处理浏览器端依赖项(通过Browserify或执行相同工作的其他事项),您将以与Node相同的方式构建代码。
比我更聪明的人解决了为什么模块的问题?&#39;,但这是一个胶囊摘要:
window.variable
之类的东西来做这件事。仍然会发生的一件事是分配this.variable
,没有意识到当前上下文中this
实际上是window
。)对我而言,前端代码模块的使用可归结为:在更窄的环境中工作,更容易推理和测试,并且对正在发生的事情有更大的把握。
学习如何使用CommonJS / Node模块语法只需要大约30秒。在给定的JS文件中,它将成为一个模块,您首先声明要使用的任何外部依赖项,如下所示:
var React = require('react');
在文件/模块中,你可以做任何你想做的事情,并创建一些你想要向外部用户公开的对象或功能,也可以调用它myModule
。
在文件末尾,您可以导出要与世界共享的内容,如下所示:
module.exports = myModule;
然后,要在浏览器中使用基于CommonJS的工作流,您将使用Browserify之类的工具来获取所有这些单独的模块文件,在运行时封装其内容,并根据需要将它们互相注入。
AND,因为ES6模块(您可能会通过Babel或类似程序转发到ES5)正在获得广泛接受,并且在浏览器或Node 4.0中都可以使用,我们应该提到good overview那些也是。
有关在this deck中使用模块的模式的更多信息。
EDIT(2017年2月):Facebook Yarn是npm非常重要的潜在替代/补充:快速,确定性,离线包管理,建立在npm为您提供的基础之上。它值得一看任何JS项目,特别是因为它很容易交换进出。
编辑(2019年5月) &#34;鲍尔终于deprecated了。故事的结尾。&#34; (h / t:@DanDascalescu,下面,简明扼要。)而且,虽然Yarn is still active,一旦它采用了Yarn的一些主要功能,它的很多动力都会转回到npm。
答案 3 :(得分:126)
鲍尔终于deprecated了。故事结束。
From Mattias Petter Johansson, JavaScript developer at Spotify:
在几乎所有情况下,使用Browserify和npm over Bower更合适。对于前端应用而言,它只是比Bower更好的打包解决方案。在Spotify中,我们使用npm打包整个网络模块(html,css,js),它运行良好。
Bower将自己打造为网络包经理。如果这是真的那将是非常棒的 - 作为前端开发人员让我的生活变得更好的包管理器会很棒。问题是Bower没有为此目的提供专门的工具。它没有提供我所知道的npm工具,特别是没有对前端开发人员特别有用的工具。 前端开发人员使用Bower超过npm没有任何好处。
我们应该停止使用凉亭并在npm周围进行整合。值得庆幸的是,这就是is happening:
使用browserify或webpack,将所有模块连接成大型缩小文件变得非常容易,这对于性能非常好,特别是对于移动设备。 Bower不是这样,需要更多的劳动才能达到同样的效果。
npm还可以同时使用多个版本的模块。如果你没有做太多的应用程序开发,这可能最初会让你感到害怕,但是一旦你经历了一些Dependency hell的比赛,你就会发现有能力拥有多个版本的一个模块是一个非常好的功能。请注意,npm包含一个非常方便的dedupe tool,如果您实际拥有,则会自动确保您只使用模块的两个版本 - 如果两个模块都可以使用相同版本的一个模块,他们会。但如果他们无法,你就会非常方便。
答案 4 :(得分:45)
Bower维护单个版本的模块,它只会帮助您为您选择正确/最佳的模块。
NPM对于节点模块更好,因为有一个模块系统,您可以在本地工作。 Bower对于浏览器很有用,因为目前只有全局范围,并且您希望对所使用的版本保持高度选择性。
答案 5 :(得分:33)
我的团队离开了Bower并迁移到了npm因为:
有关详细信息,请参阅"Why my team uses npm instead of bower"。
答案 6 :(得分:16)
从http://ng-learn.org/2013/11/Bower-vs-npm/
中找到这个有用的解释一方面,创建了npm来安装node.js环境中使用的模块,或者使用node.js构建的开发工具,例如Karma,lint,minifiers等。 npm可以在项目中本地安装模块(默认情况下在node_modules中)或全局安装模块以供多个项目使用。在大型项目中,指定依赖项的方法是创建一个名为package.json的文件,该文件包含依赖项列表。当您运行npm install时,npm会识别该列表,然后为您下载并安装它们。
另一方面,创建了bower来管理您的前端依赖项。 jQuery,AngularJS,下划线等库。与npm类似,它有一个文件,您可以在其中指定一个名为bower.json的依赖项列表。在这种情况下,您的前端依赖项是通过运行bower install来安装的,默认情况下将其安装在名为bower_components的文件夹中。
正如您所看到的,虽然他们执行类似的任务,但他们的目标是一组非常不同的库。
答案 7 :(得分:7)
对于使用node.js的许多人来说,bower的一个主要好处是管理非javascript的依赖项。如果他们使用编译为javascript的语言,则可以使用npm来管理他们的一些依赖项。但是,并非所有的依赖项都是node.js模块。编译为javascript的一些可能具有奇怪的源语言特定的修改,使得当用户期望源代码时,将它们编译为javascript是一个不优雅的选项。
并非npm包中的所有内容都需要面向用户的javascript,但对于npm库包,至少应该有一些。
答案 8 :(得分:3)
Bower和Npm是javascript的软件包管理器。在应该使用Bower或Npm的地方有很多困惑。一些项目同时具有Npm和Bower。在这里,我已经解释了这两种工具的用途,您将了解必须在何处使用Bower,在何处使用npm。
下堡
Bower是为专门为前端开发而创建的,并且已将其优化。它使用平面依赖树,每个包仅需要一个版本,从而减少了页面负载。主要目的是最小化资源负载。
Bower有一个名为bower.json的配置文件。在此文件中,我们可以维护Bower的配置,例如我们需要哪些依赖项以及许可证详细信息,描述,名称等。
Bower适用于诸如jQuery,Angular,React,Ember,Knockout,Bridge等前端软件包。
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等。