npm 的工作原理

来源:互联网 发布:济南专业淘宝拍摄 编辑:程序博客网 时间:2024/04/30 13:41

包(Package)和模块(Module)

如何定义一个Package

满足如下条件都可以称为一个包:

  • 一个文件夹包含应用程序,使用package.json来描述它(a)
  • 一个用gzip压缩的文件夹,满足(a)定义(b)
  • 一个url可以获取(b)描述的压缩包(c)
  • 一个@描述的一个包已经被发布到npm仓库 (d)
  • 一个@描述的包同(e)
  • 一个描述的包,并且具有latest标签,满足(e) (f)
  • 一个git url 可以被克隆,满足(a) 定义

即使没有把包推送到公共的npm仓库,依然可以从npm获得很多好处:
+ 如果你只是想写一个基于nodejs的应用程序,或者
+ 如果你想安装一个压缩的包

git URL可以是以下几种格式:

  • git://github.com/user/project.git#commit-ish
  • git+ssh://user@hostname:project.git#commit-ish
  • git+http://user@hostname/project/blah.git#commit-ish
  • git+https://user@hostname/project/blah.git#commit-ish

commit-ish 是一个可以git checkout的参数。默认为master


如何定义一个Module

Module是任何的能被nodejs程序使用require加载的模块。满足以下条件均可以称为Module

  • 一个文件夹包含package.json文件并指定了main字段
  • 一个文件夹包含index.js文件
  • 一个javascript文件

大多数Package都是一个Module

譬如说一些cli程序的package只包含一些可执行的命令行程序,并没有提供main字段来指定程序供外部使用。 这些package不是module


npm v2解析包的依赖关系

想像一下现在有三个模块module Amodule Bmodule C。A依赖B的V1版本,C依赖于B的V2版本。
deps2

现在创建一个应用程序依赖AC
deps4


模块依赖地狱(Dependency Hell)

包管理器必须必须提供一个module B的版本。在nodejs之前的runtime,都会尝试通过提供一个折中的版本来解决它。
deps3

npm采取了另外一种方式,把依赖的模块包嵌入子目录:
deps


npm V3 解析包的依赖关系

npm3和npm2的不同之处在于:

npm2使用嵌套的方式来管理依赖包,npm3尝试缓和过长的包依赖路径问题。 把二级依赖的包安装在同一级目录下。

想像一下我们有一个模块A依赖模块B。我们在安装模块A的时候,在项目的node_modules文件夹下: 可以看到 npm v2npm v3的差异:

deps2deps3

现在我们需要安装一个模块C,模块C依赖模块B但是版本与模块A依赖的不同:

deps3deps3

由于B v1.0已经安装在node_modules目录的根目录下了,不能把B v2.0也安装在根目录下。这个时候npm v3的处理方式和npm v2类似:

deps3deps4

通过 npm ls查看当前项目所有包的依赖关系。如果只是想看顶级包的依赖关系可以执行npm ls --depth=0


npm v3去重

npm dedupe

该命令会删除node_modules顶级目录下没有被使用的模块,并且把被重复依赖的模块移动到顶级目录下。

0 0