浅谈 Node.js 软件包管理器:npm & yarn

目录

  • 简单易用
    • 对比 Java 的包管理器:Maven
    • 对比 Python 的包管理器 pip
  • 小结

简单易用

从最初接触 npm / yarn 这两个 Node.js 的包管理器到现在已经一年多了,最大的感受就是:简单易用。

相比 Python 的包管理器 pip 和 Java 的包管理器 Maven, npm / yarn 简直好用太多了。仔细想想也很合理,Node.js 比 Python 和 Java 晚诞生了那么久,自然有机会配备更成熟的包管理器。

不过也正因为其简单易用,很少碰到问题,所以我对 npm / yarn 从来没有认真了解过。直到最近参与了一个项目,依赖关系比较复杂,有时竟然需要手动修改 yarn,lock,这才不得不找时间看了看 npm / yarn。

这篇文章简单谈谈我对 npm / yarn 的印象。首先对比一下 Java 和 Python 的包管理器。

对比 Java 的包管理器:Maven

相比 npm / yarn,Maven 有两个很大的缺陷:

  • Maven 只有一个全局的本地仓库,会把你电脑里所有使用 Maven 管理的 Java 项目的依赖全部下载到这个目录下(一般叫做 .m2,连名字也很奇怪,不如 node_modules 简单直接!)

这显然是非常不方便的。一方面,你很难直观地看到每个项目的依赖有多少;另一方面,如果某个项目的依赖出了问题,想要把项目依赖全部删除重新下载也很难办到,因为所有项目的依赖都是混在一起的。无奈只好把整个 .m2 文件夹删除。

在这一点上,npm / yarn 设计得非常合理,项目依赖默认安装到项目根目录的 node_moduls 下,不仅方便浏览,而且出问题了直接把这个文件夹删了重装也很方便。

第二个缺陷更为致命:

  • Maven 无法处理“依赖地狱”的问题。简单来说,如果你的项目有两个依赖 A 和 B,它们又分别依赖不同版本的 C,例如 C@1.0.0C@2.0.0,那么 Maven 并不能在适当的位置分别使用 C@1.0.0C@2.0.0,而是只能让你选择 C 的一个版本在程序运行时加载。

Maven 这是多么脑残的设计!!万一你需要的两个 C 的版本不兼容呢?那就真是欲哭无泪了。(当然了,Java 还有另一个流行的包管理器 Gradle,不过我还没用过)

相比之下,npm / yarn 依然没有让人失望。假如你先安装了 A,由于 A 依赖 C@1.0.0,那么项目默认的 C 的版本就会是 1.0.0;当你安装 B 的时候,B 所需要的 C@2.0.0 就会安装到 B 自身目录下的 nodee_modules 下面,类似于这样:

node_modules
  A@x.x.x
  B@x.x.x
    node_modules
      C@2.0.0
  C@1.0.0

问题完美解决!

对比 Python 的包管理器 pip

不得不说,Python 的包管理体系在我看来十分混乱。直到如今,我都没完全搞清楚在 Python 中如何正确使用 relative import 。

如果你只用 Python 默认的 pip 包管理器下载,那么会遇到一个很麻烦的问题:

  • pip 会把你需要的软件包下载到某个全局目录下,和其他的项目共用同一个版本。如果你首先用 pip 安装了依赖 A 的某个版本,例如 A@1.0.0,那么当你在另一个项目中用 pip 安装 A@2.0.0 的时候,A@1.0.0 就会被覆盖。

pip 这又是一个多么脑残的设计!!让我们再次感受一下 npm / yarn 的优秀和伟大。做一个 JavaScript 开发真是一件幸福的事情!

当然了,Python 中不是没有解决的办法:你可以使用 virtualenv 这个工具,为每个项目安装一套相互隔离的依赖,储存在项目目录下的 .venv 文件夹下,类似于 node_modules。好吧,但为什么要这么麻烦??这个功能不应该默认支持吗,竟然还需要使用第三方工具,真是无语。。

并且,即便你使用了 virtualenv 这样的“隔离”工具,还是有一点需要吐槽:

  • 如果你想看一下项目的依赖列表,叫做 requirements.txt(相当于 Node.js 中的package-lock.json 或者 yarn.lock),那么你在项目目录中是找不到这个列表的,需要你手动运行命令来生成!每次我都要上网搜一下那个生成命令。

当然了,Python 还有另一个流行的包管理器:conda,解决了 pip 的很多问题。不过这又让 Python 的包管理体系更加混乱了。。

小结

本来想主要写一写 npm / yarn 的特性和有意思的地方的,结果发现光是做对比就占了这么大篇幅。

不过也是,只有在对比中才能更加凸显 npm / yarn 的特性和优点。能够使用 npm / yarn 这样优秀的包管理器真是一件幸福的事情。

之后的文章再写写 npm / yarn 其他有意思的地方吧!

你可能感兴趣的