updated(18 Nov 2015):
Bower is alive, looking for contributors:
https://bower.io/blog/2015/bower-alive-looking-contributors/
简单地说,Bower 解决问题的思路已经跟不上前端的发展了,被取消是一个明智的决定。
具体说来我觉得原因有以下几点:
它只解决了包和依赖的下载问题,但没解决加载顺序问题(虽然有第三方的解决方案),开发者还是需要手动加载模块并调整顺序。另外在解决依赖冲突方面做得也不够好,如果需要的包比较多,很容易会经常手动管理 resolutions,非常不方便。
几年前,开发者需要一个插件,就要去往上找插件,手动下载文件并且用 script 标签引用。那个时期 Bower 的包管理思路对开发方式是有极大改善的。但在前端发展越来越复杂,对模块化要求越来越多(框架模块化,UI 组件化,甚至 CSS 都要随模块按需加载)的情况下 Bower 能提供的就很有限了。
对开发者造成了负担。NPM,Bower,JSPM,Component 这些都是比较有名的包管理器的选择。每种都有自己的拥簇。这对包的开发者来说是个负担,往往一个热门项目要兼顾几种包的格式,有的还要分多个子项目如 xxx-bower,xxx-component。这对使用者来说也是个负担,因为每种包管理器都有擅长的地方,所以一个项目中往往混用两种或以上的包管理器。比如很长一段时间大家都觉得 NPM 适合后端包管理,Bower 适合前端包管理,所以一个 Node.js 项目往往要同时用 NPM 和 Bower,这无疑降低了统一性并且加大了维护成本。
第一点中 Bower 的缺点在 NPM 中本来就不是问题。Browserify 和 Webpack 的崛起也直接让 NPM 成了前端包管理的主流选择。使用 NPM 还让一个项目几乎不需要第二个包管理器。从各种方面来看 NPM 已经是大势所趋。
bower 当年很流行的时候还试着用了一次。发现没啥大用处,而且还挺坑:http://segmentfault.com/q/1010000000494228 当时就发誓再也不用它了。
按照我的理解,npm 并不是前端的包管理器,虽然很多前端的包有对应的 npm,但一般是 gulp 或者 grunt 的封装,需要运行安装任务。 而且我认为 Bower 和 Browserify 和 Webpack 也不是干一样的事情,一个是包安装器,一个是模块加载器。
@so_zengtao 第一次见我是啥样的?
@sharpx 确实包管理和模块加载器确实是两个概念。Bower 不该负责模块如何加载,以此作为缺点是有失偏颇。不过我觉得包管理和模块加载的关系非常密切,所以混到一起来谈。我的看法是:所谓的包封装的也是模块,打包只是为了更好地分享,所以包管理器提供包格式的定义,打包,上传,下载;模块加载器提供的才是如何加载模块和管理依赖,包的依赖实际上是因为被封装的模块之间有依赖。所以理想情况下包管理器是无所谓前端还是后端的。
很多人以前不用 NPM 作为前端包管理器,大概就这么几个原因:
<script>
标签加载打包并且压缩好的文件,模块化的思想还没有成为共识。个人觉得这是根本原因。现在模块化的思想都普遍被认可了,上面的问题就都不是问题了。所以 NPM 也被用于前端包管理也就是顺理成章的事情。
Bower is alive, looking for contributors http://bower.io/blog/2015/bower-alive-looking-contributors/
第二点是:CommonJS 模块风格在浏览器上没法用。
缪也
https://www.npmjs.com/package/browserify
如果是非 react + webpack 项目,NPM 作为前端包管理器仍然不成熟
前端开发一大难点就是似是而非的概念比较多。
我的看法是 npm 是在 nodejs 服务器环境下,在运行时动态加载模块,并且 require 是同步的,我不清楚 npm 是不是在老式的 pipeline 的时候会被用到,这一点请指教
目前的前端模块管理一般是通过 requirejs/webpack/browserily 对 js 文件做预处理,然后丢给浏览器。
@i5ting 所以我说的是 以前 。虽然我不知道 Browserify 是怎么工作的,不过我用过 Webpack,它把代码编译成浏览器可以运行的模块风格,然后提供一个轻量级的 runtime 去加载模块,Browserify 应该同理。预编译的手段连语言层面的差异都可以忽略(CoffeeScript, TypeScript),更何况模块风格(CommonJS, AMD, ES6 module)。所以我想表达的意思是,CommonJS 风格的模块代码在前端不是没法用,是以前没有多少人想这么做,这是为什么我也不知道,也许是因为 AMD?我感觉的原因可能是当时很多前端项目不复杂导致没有普遍的高度模块化的需求。如果说错了欢迎指正。
@sharpx 这点我也不知道,毕竟我是正牌 Ruby 工程师加 Node.js 半桶水。Node.js 对我来说大部分时候就是构建下 build 工具和写点 proxy。不懂的也很多。如果不是现在对 Node.js 服务器端异步编程比较感兴趣,我连 NPM 怎么做包管理都不会去看……
@darkbaby123 CommonJS 模块如果没有 requirejs 等的支持,确实没法在浏览器上使用,ES 模块或许可以,那么我得出的结论是 webpack/requirejs/Browserify 相当于浏览器环境下的'npm', 可以异步 require 模块。 npm 也可以处理前端模块,因为语法兼容,但是仅限于 node 环境,但好像对前端没有什么实际的意义,对后端或许可以引入一些前端的包复用。
#18 楼 @sharpx http://browserify.org/
Browserify lets you require('modules') in the browser by bundling up all of your dependencies.
bower 还不如 sprockets
webpack 挺好的,其实在 webpack 和 browserify 之前,就有 https://github.com/SaitoWu/linner 了
至于 grunt 和 gulp, 可能... 还不如直接 makefile
#20 楼 @i5ting requirejs 有适配器,可以支持 commonJS 的:) http://requirejs.org/docs/node.html#2
说一点实际的,是自己目前在项目里面用的,没有大家说的高大上,但是感觉下来,还是方便的,
我用 bower-rails,Bowerfile
是这么写的:
asset 'datatables', main_files: ["./media/js/dataTables.bootstrap.js", "./media/css/dataTables.bootstrap.css"]
asset 'moment', main_files: ["./locale/zh-cn.js"]
asset 'lodash'
asset 'store'
asset 'jquery-timeago', main_files: ["./locales/jquery.timeago.zh-CN.js"]
asset 'bootstrap-modal', main_files: ["./css/bootstrap-modal-bs3patch.css"]
......
application.js
部分是这样的:
...
//= require common/namespace
//= require common/ajax-injection
//= require datatables/media/js/jquery.dataTables
//= require datatables/media/js/dataTables.bootstrap
//= require jquery-timeago/jquery.timeago.js
//= require jquery-timeago/locales/jquery.timeago.zh-CN.js
...
对我的项目来说,如果前端有需要用的插件,在Bowerfile
里面写好,用rake bower:update bower:clean bower:resolve
跑好,帮我解决了几个事情:
要做的就是在 rails 的 js 或者 css entry 文件中加入对应的引用。没有各位说的高大上,但是就目前的项目来说,还够用,也挺顺畅的。
一直想要尝试 webpack 这种,但是在和 rails 的整合上,还没找到一个合适的点,发现很多人在说不好,好的时候,其实每个人都有自己的场景,还是要看适合自己的。
@lips 如果是 Rails 项目,又没有很重的前端逻辑,Sprocket 就可以干 Bower 干的事情。前端项目直接用 NPM 加上一个模块加载器就行了,推荐 Webpack。
#30 楼 @leeboqiang npm 不适合用来管理前端包吧?
#31 楼 @darkbaby123 用 webpack 替代 bower 么? bower 只是停止开发,用的人应该还不少吧?
#32 楼 @lips 目前我也尚未发现 bower 的替代品,所以仍然得用。大多人都是 npm 管本地的各种开发依赖包,bower 管打包发布到应用中的各种前端包,完全互不影响!用 npm 来管前端包的话,到至今为止,我并没有找到正确的、简洁易行的使用方式。
至于说使用人数,npm install bower 每天安装的次数达十万次,10000+ 的 star,bower 的优点还是非常明显的,非常非常的简单易用,特别是相对于 sprockets 而言(主要是不会产生什么奇葩错误,哈哈)。
另外,bower 和 webpack, browserify 之类的东西是两回事吧?bower 只是包管理器,和 npm 差不多的。那为什么一个应用要用两个包管理器呢,那是因为 npm 的初衷就是为 node.js 管包的,bower 的初衷就是为前端管包的,能够干掉其中一个当然好,但是明明两者各有所长,为什么非得要只用其中一个呢?至少在我目前的项目中,如果只用 npm 的话当然也是做得到的,就象这篇文章所说的那样整,但是,我为什么不用 bower?毕竟,换个角度思考就是:只要使用 bower,文章中所说的这些步骤和工具都是不需要的,你看文章中为了去掉 bower,提及了好多个三方库?
结论: bower 最大的问题是影响了社区的统一和团结 ,同一种东西,存在两种来源是有点令人感觉不爽。但对于开发者而言,只要要用的包还在,不管是在 bower 中,还是在 npm 中,真的没有什么区别,当然,强迫症患者除外。
@xhj6 这个当然是有区别的。用一套系统依赖只在一处,用两套依赖在两处。另外你如果用 webpack, browserify 的话 npm 是首选,因为很多 bower 包是不匹配 CommonJS 的。
@lips 工具不是选流不流行,而是应该根据应用场景挑选适合自己工作方式的。我也没号召大家都不用 Bower。但是从开发者的角度来说,只推崇一种工具很容易养成“拿着锤子看什么都是钉子”的心态。从工具的角度来看,任何一个流行的工具都是没那么快消亡的,所以短时间来说继续用 Bower 一点问题都没有。
npm 定位感觉和 bower 不一样 目前无法不使用 bower 话说谁说 bower 停止开发了 标题也该改改了 一直有在更新 要换新的维护者而已 看#14 http://bower.io/blog/2015/bower-alive-looking-contributors/