为什么我不建议使用npm做前端包管理?

 

npm欲取代bower的想法已经存在了很多时间,但是目前为止仍没有明显的迹象表明npm取代了bower。并且随着npm3的问题的发酵,npm3在处理node自身的问题上也显得力不从心,那么npm能处理好前端的包管理吗?...



前一阵子听说bower团队有意找维护人员,于是我就发了个申请。没几天就收到了bower的官方邀请,同意后就正式成为bower成员。虽然刚成为bower的维护人员,还没有太多权限,也还没有提交过代码。但是我也有义务将bower吹一吹,让更多的人了解使用bower作为前端的包管理工具是必要的,也是正确的选择。

由于bower的一些设计缺陷,导致很多用户鼓吹使用npm取代bower,但是口号喊了好多年,却并没有产生多大的作用。原因是npm连node自己的问题都没有能很好的解决,更别说解决什么前端的版本管理问题了。

npm3引入的问题

我们来看看npm升级后产生的问题:
1. 从npm3之后,npm从nested转向了flat,结果一堆软件无法工作。
2. 即使是全面支持flat的包,不同的版本也无法实现一致化。
比如一个包A的版本是1.2.xx,支持基于npm3发布的。如果有两个包引用了这个包A,分别是版本,1.2.xx,跟1.3.xx,那么npm3就会安装两个版本的npm包。从而无法实现A包在一个系统里的一致性,从而产生与npm2时代一样的问题。所以用一句网络流行语评价npm3:“然而并没有什么卵用”。
3. 包灾难。使用npm3之后,本来你只是引用了2个包,结果node_modules目录下面出来上百个包,让你找个包都困难死了。完全没有npm2时代引入多少包就产生多少个目录的整洁。

所以npm的升级完全没有解决node自己的问题,反而引入了一堆新的问题。
有些问题甚至还不如npm2时代解决的好。

npm解决node问题都自顾不睱,还好意思来管前端的事情吗?

前端与后端不宜混合在一起

会产生冗余问题

前端与后端使用同一套包管理软件可以减少公共部分的耦合,但是会导致不必要的冗余。
比如一个bootstrap包,是不可能被后端使用的。但是如果统一使用npm管理,每次npm install都会安装bootstrap包,而后端一辈子都用不倒,完全是浪费带宽、存储空间、时间。并且你在运行后端前,每次都安装个bootstrap,你不觉得恶心吗?

运行环境完全不同

前端与后端的运行环境是完全不同的,前端运行于浏览器内(即主要是DOM与BOM环境,相对受限),后端则运行于OS内(有无限的API与可能性)。所以这两种开发环境是完全不同的。不同的开发环境使用同一个包管理文件显然是不合时宜的,也不符合模块化的理念。

开发人员也可能不同

前端与后端通常是不同的开发团队,因些前端关注的是HTML,CSS,DOM,BOM, js的UI库与动作库。而后端关注的是性能,安全,效率,数据,缓存,用户管理。他们可能都会用到gulp/grunt,而后端通常不会用到webpack,wiredep,bootstrap, jQuery这类纯前端的包。所以强行将他们捆绑在一起是没有必要的。

同构包可以分开打包

由于isomorphic js的流行,同构包也会越来越多。但是其实你会发现,不管如何同构,前后端的运行环境还是不同的。所以同构包的调用环境还是不一样的。前端的包通常需要通过browserify,webpack或者gulp等工具发布成前端可用的包。跟npm包直接通过package.json决定从什么地方接入是不同的。即使npm可以为前端包提供字段供前端接入,也会显得非常混乱。

Do one thing and do it well

Unix的一个很重要的原则是:Write programs that do one thing and do it well. 如果npm想搞前后端,则违反了这个基本的原则,所以我不会看好。虽然unix原则并非所有的时候都是对的。但是他经历了千万次的考验。

总结

bower存在不少问题,但是只要改进,一定会比npm更加符合前端对于包管理的需求。bower也仍在不断的演进之中,未来可能会带来更多便利的功能来促进前端的发展。所以它仍是一个可信的前端包管理解决方案。


    关注 Web前端


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册