包和模块

nodejs和npm对包和模块都有特别的定义,他们两种很容易混淆。在这篇文章中,我们将具体讨论他们,区分两者,同时也解释为什么


快速总结

  • 包是一个文件或者一个目录,它在package.json中被描述。有多种情况能构建成一个包。更多信息请看下面。
  • 模块是能被nodejs的require加载的任何文件或者目录。同样,也有多种情况能构建成一个模块。更多信息请看下面。


包是什么?

包是下面任意的一种:

  • a)一个包含程序的目录,这个目录在package.json中所描述
  • b)某个压缩包包含(a)中的情况
  • c)某个指向(b)中压缩包的网址
  • d)(c)中发布到registry上的某个版本(<name>@<version>)
  • e)(d)版本中的某个标签(<name>@<tag>)
  • f)(e)中带有latest标签的包(<name>)
  • g)一个git的地址,当克隆下来的时候,会生生(a)

即使你不将你的包发布到公有的registry上,你依然可以享受到使用npm所带来的便利:

  • 如果你只是想写一个node程序,并且(或)
  • 你将其打包之后,很容易在其他地方安装它

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可以是任何的标签,或者是任何可以被git checkout的分支名。默认情况下commit-ish是master。


什么是模块

模块是可以是任何能够被nodejs加载的东西。下面是一些能够被nodesjs加载的一些例子:

  • 一个带有package.json的目录,并且package.json带有main字段
  • 一个带有index.js的目录
  • 一个js文件


绝大多数的npm包都是模块

一般来说,npm的包都能够被nodejs程序使用require加载,也就是说通常npm的包都是模块。不过,并没有强制要求npm的包一定是node模块。

一些包,比如cli包,只带有一个可执行的命令行接口,并且并没有提供main字段供node程序使用。这个时候,这些包就不是node模块了。

几乎所有的npm包中都包含有大量的模块。

在node程序的上下文中,module也通常表示从文件中加载的东西。例如,在下面的代码中:

var req = require('request')

我们可能会说,便利reg他是指向一个request模块的。


在nodejs和npm生态中的文件和目录的命名

  • 为什么叫做node_modules目录,为什么叫做package.json?
  • 而不叫做node_packages或者是module.json?

package.json文件定义了某个包。

node_modules目录保存了供nodejs查找的模块。

例如,如果你再node_modules中创建一个文件foo.js(node_modules/foo.js)。然后某个程序使用了var f = require('foo.js'),那么程序将会加载这个模块。然而,在这种情况下foo.js并不是一个包,因为它没有包含package.json文件。

相应的,如果你创建一个包,它并没有包含index.js,并且在package.json中也没有main这个字段的话,那么它也不是一个模块。即使它被安装在node_modules中,它也不能成为被require所加载。


链接: https://www.fly63.com/course/21_1002