golang和Node.js的包管理对比
YanyiWu · · 4905 次点击 · · 开始浏览golang 和 Node.js 身为当今语言两大新贵,在使用这两者的时候常常会互相对比一下。 对语法上来讲,个人还是最喜欢 golang 的简单和创新。而 Node.js 最让我满意的则是 npm 。 但是在此主要说说两者包管理对依赖处理的解决方案差异。
先说说 golang 的。golang 对依赖的处理宗旨是让你 察觉不到依赖是远程的还是本地的仓库 。
一切都是通过 go get 来实现。只要在源码里面是
import "github.com/username/projectname"
在 go get 的时候工具自动帮你下载该依赖的源码包。
这样看上去非常简单,操作简单,但是却给我带来了不少困扰。
比如当我们今天需要依赖项目 pA 所以在源码里面写上
import "code.google.com/uA/pA"
但是有天你发现 code.google.com 被墙且翻墙不易,你想使用 github.com 上的镜像仓库。
你就需要修改含有这句 import 的源码。也就是,对于 golang 来说,仓库依赖和源码耦合在一起 。
又或者,你在 github 上面 Fork 了该项目,
从 github.com/uA/pA Fork 成 github.com/uB/pA 。
而该项目的源码里面存在 import "github.com/uA/pA/sub1/" 之类的依赖本项目子目录包的语句。
而你 Fork 之后,go build 就会报错说找不到 github.com/uA/pA/sub1 这个包里。
这个问题说白了不是什么新问题,比如在 C/C++ 中,#include "xxx" 时,xxx 的路径应该是写相对路径。
而不能写绝对路径,因为当你写上绝对路径的时候,比如 #include "/home/yanyiwu/code/xxx" ,这样的话,源码就丧失可移植性了。
当然对付这个问题的话也是有现成的解决方案的,只是这个解决方案不是完美解决方案。
具体请看 using-forked-package-import-in-go 。
而对于 npm 的话,这个事情就简单很多。因为 npm 的包管理策略是 集中式管理 ,
当你使用 npm publish 发布一个新包的时候,你的代码是被上传到 npmjs.org 上集中管理。
所以当你使用 npm install 安装一个新包的时候,你的代码是从 npmjs.org 下载得到。
当然这样集中式管理有单点故障,比如 npmjs.org 挂掉了或者被墙了就要悲剧? 回答是否定的。
因为 npm 也支持指定仓库下载,比如在天朝内,勤劳自强的程序员们就搭建了一个国内的镜像 cnpm ,而且速度非常不错。
使用镜像也非常简单,比如这样:
npm --registry=http://r.cnpmjs.org install koa
具体用法可以参考 faster-npm。
说到这里,就可以注意到差别是在哪里。
就是对于依赖管理。Node.js 的包管理解决方案是和源码无关的。
在 Node 源码里面是不需要管这个包在哪个仓库下面。
就拿 koa 这个项目来说,在 koa 的 package.json 里可以看到:
"dependencies": {
"accepts": "^1.1.0",
"co": "^3.1.0",
...
},
里面依赖了 accepts 这个包,在 koa 的源码里面直接 var acceps = require(‘accepts’); 即可,
源码并不需要知道 accepts 源码的仓库是在 github.com 上面还是 gitcafe.com 上面。
而且,由 npm 通过 package.json 文件来统一管理的另一个好处是依赖非常清晰,
可以看到所有的依赖和对应的版本。一目了然。
npm 这种集中式包管理的好处也能避免 golang 里面 包管理和源码 耦合在一起导致的问题。
所以个人看来,npm 的包管理解决方案确实是比较好。 希望 golang 的之后的改进里面能参考一下这种解决方案。
其实现在国内的技术论坛有个风气不太好,就是当发表一些不同语言的分析对比时,总是会不可避免引起各种语言粉的敌意。 就比说我说 golang 的包管理解决方案确实不如 Node 的 npm 。就会 golang 粉们觉得我是专门来挑刺踢馆的。 其实我也是 golang 粉,所以真心对于这种敌意很无语。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
golang 和 Node.js 身为当今语言两大新贵,在使用这两者的时候常常会互相对比一下。 对语法上来讲,个人还是最喜欢 golang 的简单和创新。而 Node.js 最让我满意的则是 npm 。 但是在此主要说说两者包管理对依赖处理的解决方案差异。
先说说 golang 的。golang 对依赖的处理宗旨是让你 察觉不到依赖是远程的还是本地的仓库 。
一切都是通过 go get 来实现。只要在源码里面是
import "github.com/username/projectname"
在 go get 的时候工具自动帮你下载该依赖的源码包。
这样看上去非常简单,操作简单,但是却给我带来了不少困扰。
比如当我们今天需要依赖项目 pA 所以在源码里面写上
import "code.google.com/uA/pA"
但是有天你发现 code.google.com 被墙且翻墙不易,你想使用 github.com 上的镜像仓库。
你就需要修改含有这句 import 的源码。也就是,对于 golang 来说,仓库依赖和源码耦合在一起 。
又或者,你在 github 上面 Fork 了该项目,
从 github.com/uA/pA Fork 成 github.com/uB/pA 。
而该项目的源码里面存在 import "github.com/uA/pA/sub1/" 之类的依赖本项目子目录包的语句。
而你 Fork 之后,go build 就会报错说找不到 github.com/uA/pA/sub1 这个包里。
这个问题说白了不是什么新问题,比如在 C/C++ 中,#include "xxx" 时,xxx 的路径应该是写相对路径。
而不能写绝对路径,因为当你写上绝对路径的时候,比如 #include "/home/yanyiwu/code/xxx" ,这样的话,源码就丧失可移植性了。
当然对付这个问题的话也是有现成的解决方案的,只是这个解决方案不是完美解决方案。
具体请看 using-forked-package-import-in-go 。
而对于 npm 的话,这个事情就简单很多。因为 npm 的包管理策略是 集中式管理 ,
当你使用 npm publish 发布一个新包的时候,你的代码是被上传到 npmjs.org 上集中管理。
所以当你使用 npm install 安装一个新包的时候,你的代码是从 npmjs.org 下载得到。
当然这样集中式管理有单点故障,比如 npmjs.org 挂掉了或者被墙了就要悲剧? 回答是否定的。
因为 npm 也支持指定仓库下载,比如在天朝内,勤劳自强的程序员们就搭建了一个国内的镜像 cnpm ,而且速度非常不错。
使用镜像也非常简单,比如这样:
npm --registry=http://r.cnpmjs.org install koa
具体用法可以参考 faster-npm。
说到这里,就可以注意到差别是在哪里。
就是对于依赖管理。Node.js 的包管理解决方案是和源码无关的。
在 Node 源码里面是不需要管这个包在哪个仓库下面。
就拿 koa 这个项目来说,在 koa 的 package.json 里可以看到:
"dependencies": {
"accepts": "^1.1.0",
"co": "^3.1.0",
...
},
里面依赖了 accepts 这个包,在 koa 的源码里面直接 var acceps = require(‘accepts’); 即可,
源码并不需要知道 accepts 源码的仓库是在 github.com 上面还是 gitcafe.com 上面。
而且,由 npm 通过 package.json 文件来统一管理的另一个好处是依赖非常清晰,
可以看到所有的依赖和对应的版本。一目了然。
npm 这种集中式包管理的好处也能避免 golang 里面 包管理和源码 耦合在一起导致的问题。
所以个人看来,npm 的包管理解决方案确实是比较好。 希望 golang 的之后的改进里面能参考一下这种解决方案。
其实现在国内的技术论坛有个风气不太好,就是当发表一些不同语言的分析对比时,总是会不可避免引起各种语言粉的敌意。 就比说我说 golang 的包管理解决方案确实不如 Node 的 npm 。就会 golang 粉们觉得我是专门来挑刺踢馆的。 其实我也是 golang 粉,所以真心对于这种敌意很无语。