100steps/Blogs

包管理工具漫谈

tugui opened this issue · 11 comments

tugui commented

introduction

大家都知道,程序员喜欢造轮子。那么如果我们想用别人的轮子,应该怎么办呢?最简单的方法当然是到github里去找,但我们需要手动将其clone|download下来,再整合到自己的项目中,所以从开发者的角度来看,那只能叫代码仓库而并非一个很好的项目构建&管理工具。

另一方面,在项目的开发阶段,可能会引用到一些第三方的库,而它们可能又依赖于其它的库,如果我们自己去找这些依赖关系的话,势必会花费一定的时间和精力。那么能否通过一种工具,自动安装我们想要的库和相关依赖呢?答案是肯定的。

为了解决项目构建自动化以及安装包依赖的问题,一些猿引入了包管理工具。对于现代语言,它们基本上是不可或缺的了,下面列举了部分对应关系:

  • Java:Maven
  • Python:pip
  • Ruby:Rubygems
  • Nodejs:npm
  • PHP:composer
  • Go:gopm

example

以npm为例,由于Nodejs是以模块化为标榜,每一个文件对应一个模块,所以如何在项目中进行布局,使得整个结构有层次感,就需要好好的考虑了(特别是模块之间的依赖比较多的时候)。而npm提供了一种通用的解决方案,以统一的依赖描述和引入方式来进行管理,同时也对库的版本作了规定。下面介绍两个比较重要的东西:

  • package.json:项目的描述文档,用于声明依赖并自动构建项目

    {
        "name": "demo",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "dependencies": {
            "express": "*"
        },
        "author": "tugui"
    }
    
  • node_modules:存储第三方模块的文件夹,以平面的方式来组织依赖关系,好处是可以实现包依赖的重用,同时避免一些多重嵌套的情况

image 16-4-23 at 7 42

上面是原始依赖关系,下面为经过重新组织之后的结构。

image 16-4-23 at 9 19

我们可以看到,对于express(Nodejs的一个框架)来说,它所依赖的模块是相当多的,而使用npm进行安装的话却只需要一条命令就能够完成。另外,包管理器还可以替我们做一些重复性的工作,比如对某些库进行更新/卸载,或者是对项目的重新构建,当然还有某些必要文件的生成(LICENSE等),它们的命令格式大同小异,大家可以自行去了解。

summary

npm makes it easy for Javascript developers to share the code that they've created to solve particular problems, and for other developers to reuse that code in their own applications.

值得一提的是,它们都维护有一个官方的仓库,开发者可以在这个平台上与他人交换轮子,形成了良好的生态系统。在软件规模越来越大的现在,对于第三方库/包的管理显得十分必要,而上面讲到的这些工具,很好地将规范与实践结合了起来,为我们的开发提供了一定的方便。

image 16-4-23 at 9 05

另外,对于软件的安装也存在相互依赖的情况,所以在一些操作系统提供了方便的解决方案供人们使用,比较常见的有Ubuntu下的apt-get、Red Hat/CentOS/Fedora有yum、MacOS自然就是homebrew了,在使用这些工具时只需要输入一条命令,就可以按顺序下载并安装相关的依赖包了(其中的软件包列表是由对应的开发商进行维护的)。

最后借着Composer 1.0.0版本发布的余热,我引用其创始人Jordi Boggiano的一段话作为结语:

... I can barely remember what it was like to write PHP code without having a whole ecosystem at my fingertips.

update

使用包管理工具还有一个好处,就是在进行项目版本控制的过程中,不需要包含第三方的库文件,而是在项目的构建阶段才进行相关依赖的安装,这样即使想对库版本进行升级,也可以保证整个版本控制的干净(要知道有些库体积是十分庞大的,每次改动会给git仓库造成不必要的压力)……这样我们只需要对package.json进行修改和管理就可以了。

然后这里有一篇关于Composer的介绍,有兴趣的可以看看:

更新后的 PHP: 用于 PHP 依赖关系处理的 Composer

说起 npm, 之前出了一个 leftpad 的事件很值得去思考的。
延伸阅读 NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?

tugui commented

更新了一点内容..在文章的最后面。

gem本身只是包。。

tugui commented

就作用而言它是管理其它包的包?

ruby的管理包的工具是rvm..gem只是包,也就是它的管理对象。不过ruby的包管理工具好像不止这一个,但大概是rvm用得最多。。。
另外很早之前听说rvm的作者面试时因为不能现场写反转二叉树的算法被刷掉了2333333
不过时间久远可能记的不是很准确。。

反转二叉树那个是 homebrew 的作者吧...

都是管理工具的作者。。我弄混口胡了。。

虽然我不会 ruby,但是我看了一下,rvm (https://github.com/rvm/rvm) 全称 Ruby enVironment (Version) Manager, 是环境/版本管理工具,对应 node 就应该是 nvm 或者 n 吧? 然后 gem 有不同含义,gem 既是基于 Ruby 的一些开发工具包,也是 rubygems (https://github.com/rubygems/rubygems) 命令行工具的名字,这个工具就是用来做 package management (包管理)的,所以对应 node 的 npm。是不是应该这样理解?

唔,是的。。

RVM 主要是管理 ruby 解释器版本的,你想说的是 bundler 吧?

gem,rvm,bundler 的区别与联系

http://stackoverflow.com/questions/15586216/bundler-vs-rvm-vs-gems-vs-rubygems-vs-gemsets-vs-system-ruby

我把rvm当管理器是因为它能为不同的版本安装不同的gems作为环境。。恩。。其实我并没有用过这个功能。。