# 此页面贡献者:年轻的铲屎
CommonJS
CommonJS
规范,为 JavaScript
制定了一个美好的愿景——希望 JavaScript
能够在任何地方运行。
Node
中,模块分为 2 类:
在 Node
提供的模块,称为核心模块核心模块在
Node
源代码的编译过程中已经编译为二进制代码。在Node
进程启动时,部分核心模块就直接被加载进内存中。用户编写的模块,称为文件模块
在运行中动态加载。
CommonJS
的模块规范,主要分为 3 部分:
模块定义
在
Node
中,一个文件就是一个module
对象,该对象含有exports
属性。通过exports
导出当前模块的方法或变量。模块引用
通过
require()
方法接受模块标识
来引入模块的API
到当前上下文。模块标识
即传递给
require()
的参数。小骆峰命名字符串。可以没有文件后缀名。主要分为 4 类:- 核心模块 e.g.
http
fs
path
- 以
.
或..
开始的相对路径文件模块 - 以
/
开始的绝对路径文件模块 - 非路径形式的文件模块,如自定义的
connect
模块
- 核心模块 e.g.
Node
通过 require()
引入模块,需要经历 3 个步骤:
路径分析
- 查找优先级 & 加载速度:核心模块 > 文件模块 > 自定义模块
文件定位
- 文件扩展名分析,按以下次序补足扩展名: .js > .json > .node
- 上一步扩展名分析没有查找到对应文件,则模块标识为目录,将目录视为包进行分析(自定义模块常见场景):
- 查找目录下
package.json
的main
字段,进行文件定位 - 如果上一步失败,则默认
index
为文件名,并为其匹配查找扩展名 - 如果上一步失败 again ,自定义模块进入下一个模块路径进行查找
- 如果上一步失败 again ,抛出查找失败异常
- 查找目录下
编译执行
- 定位到具体文件后,
Node
新建模块对象,根据路径载入并编译。对不同文件扩展名,载入方法不同。如.js
文件,通过fs
模块同步读取文件后编译执行。成功编译的模块都会将其文件路径作为所以缓存在模块对象中。
- 定位到具体文件后,
相同模块的第二次加载都一律采用缓存优先的方式。不需要再次经历以上 3 个步骤
学习资料
深入浅出Node.js