# npm 包和模块的了解
Node.js 和 npm 对包和模块有非常具体的定义,很容易混淆。我们将在这里讨论它们的定义以及他们之间的不同,并解释为什么某些默认文件以它们的方式命名。
# 快速总结
- 包是通过
package.json
描述的一个文件或目录。这可能以多种不同的方式发生!有关更多信息,请参阅下面的。 - 模块是可以通过Node.js的
require()
加载任何文件或目录。同样,有几种配置允许这种情况发生。有关详细信息,请参阅下面的 。
# 什么是包(package)?
包是以下任何一种:
- a) 包含由
package.json
文件描述的程序的文件夹 - b) 包含(a)的gzip压缩包。
- c) 解析为(b)的url
- d) 使用(c)在注册表上发布的
<name>@<version>
。 - e) 指向(d)的
<name>@<tag>
- f) 具有
latest
满足(e)的标签<name>
。 - g) 一个
git
url, 当克隆时,结果为 (a).
注意到所有这些 package
可能性,即使你从未将包发布到公共注册表,你仍然可以从使用 npm 中获得很多好处:
- 如果只想编写一个节点程序,和/或,
- 如果还希望能够在将其打包成 tarball 后轻松地将其安装到其他地方。
Git 网址可以采用以下形式:
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
可以是任何标签,sha,或分支可以作为参数被供给 git checkout
。默认值为 master
.
# 什么是模块(module)?
模块是可以 require()
在 Node.js 程序中加载的任何东西。以下是可以作为模块加载的所有示例:
package.json
包包含main
字段的文件的文件夹。- 一个文件夹,里面有一个
index.js
文件。 - 一个 JavaScript 文件。
# 大多数 npm 包都是模块
通常,在 Node.js 程序中使用的 npm 包通过 加载 require
,使它们成为模块。然而,没有要求 npm 包是一个模块!
一些包,例如 cli
包,只包含一个可执行的命令行界面,不提供 main
在 Node.js 程序中使用的字段。这些包不是模块。
几乎所有的 npm 包(至少,那些是 Node 程序的包) 都包含许多模块(因为它们加载的每个文件 require()
都是一个模块)。
在 Node 程序的上下文中, module
也是从文件加载的东西。例如,在以下程序中:
var req = require('request')
我们可能会说“变量 req
是指 request
模块”。
# Node.js 和 npm 生态系统中的文件和目录名称
那么,为什么是 node_modules
文件夹,而不是 package.json
文件?为什么不是 node_packages
或者 module.json
?
package.json
文件定义了包。(参见上面的 “什么是包? ”
)
node_modules
文件夹是 Node.js 查找模块的地方。(参见上面的 “什么是模块?”
)
例如,如果你在 node_modules/foo.js
创建一个文件,然后有一个执行 var f = require('foo.js')
的程序,它将加载该模块。但是, foo.js
在这种情况下不是“包”,因为它没有 package.json
。
或者,如果你创建的包在文件中没有 index.js
或 "main"
字段 package.json
,则它不是模块。即使它安装在 中 node_modules
,也不能成为 require()
。