CommonJS规范的起因:
1.JavaScript没有模块系统。没有原生的支持密闭作用域或依赖管理。
2.JavaScript没有标准库。除了一些核心库外,没有文件系统的API,没有IO流API等。
3.JavaScript没有标准接口。没有如Web Server或者数据库的统一接口。
4.JavaScript没有包管理系统。不能自动加载和安装依赖。
在node中引入模块需要经历3个步骤:
1.路径分析
2.文件定位
3.编译执行
CommonJS对模块的定义十分简单,主要分为模块引用、模块定义和模块标识3个部分。
1.模块引用
require('xxx')
2.模块定义
exports.xxx
module.exports = {}
3.模块标识
模块标识其实就是传递给require()方法的参数,
它必须是符合小驼峰命名的字符串,
或者以.、..开头的相对路径,
或者绝对路径。它可以没有文件名后缀.js。
Nodejs模块分类Node.js的模块分为两类,一类是node提供的模块,称为核心模块;另一类是用户自己编写的模块,称为文件模块。核心模块在Node.js源代码编译的时候编译进了二进制执行文件,在nodejs启动过程中,部分核心模块直接加载进了内存中,所以这部分模块引入时可以省略文件定位和编译执行两个步骤,所以加载的速度最快。另一类文件模块是动态加载的,加载速度比核心模块慢。但是Node.js对核心模块和文件模块都进行了缓存,于是在第二次require时,是不会有重复开销的。其中原生模块都被定义在lib这个目录下面,文件模块则不定性。
ps:核心模块又分为两部分,C/C++编写的和Javascript编写的,前者在源码的src目录下,后者则在lib目录下。(lib/*.js)(其中lib/internal部分不提供给文件模块)
注:通过process.moduleLoadList可以查看已经加载的核心模块。 核心模块 = 原生模块
加载过程如下图:

CommonJS模块规范允许在标识符中不包含文件扩展名,这种情况下,Node会按.js、.node、.json的次序补足扩展名,依次尝试
小诀窍是:如果是.mode和.json文件,在传递给require() 的标识符中带上扩展名,会加快一点速度。另一个诀窍是:同步配合缓存,可以大幅度缓解Node 单线程中阻塞式调用的缺陷。
编译和执行是引入文件模块的最后一个阶段。定位到具体的文件后,Node会新建一个模块对象,然后根据路径载入并编译。对于不同的文件扩展名,其载人方法也有所不同,具体如下所示。
.js文件。通过fs模块同步读取文件后编译执行。
.node文件。这是用C/C++编写的扩展文件,通过dlopen()方法加载最后编译生成的文件。
.json文件。通过fs模块同步读取文件后,用JSON.parse()解析返回结果。
其余扩展名文件。它们都被当做.js文件载人。
每一个编译成功的模块都会将其文件路径作为索引缓存在Module._cache对象上,以提高二次引入的性能。
内置模块
原生模型的引入:

* GYP项目生成工具
* V8引擎C++库
* Iibuv库
* Node内部库
* 其他库
包组织模块示意图:

发布包的流程:
1.编写包程序(编写代码)
2.初始化包描数文件(package.json)--npm install
3.注册包仓库账号
npm adduser
Username:(XXXXX)
Email:(***@XX.com)
4.上传包
npm publish <folder>
在刚刚创建的package.json文件所在的目录下,执行 npm pulish . 开始上传包
这个过程中,NPM会将目录打包成为一个文档文件,然后上传到官方源仓库中。
5.安装包
npm install 包名
6.管理包权限
npm owner ls eventproxy
添加包的拥有者,删除一个包的拥有者:
npm owner ls <package name>
npm owner add <user> <package name>
npm owner rm <user> <package name>
浙公网安备 33010602011771号