node.js 学习 之 模块化
一. 模块的分类
- 内置模块:Node.js 官方自带的模块。
- 自定义模块:用户自己编辑的JS文件。
- 第三方模块:其他人发布在NPM上的包。
二. 模块的加载机制
-
缓存加载
- 优先从缓存加载
- 多次调用
require()
不会使模块中的代码重复执行
-
内置模块加载
- 内置模块的加载优先级最高
-
自定义模块加载
- 加载自定义模块时,路径必须以
./
或者../
开头 - 加载顺序如下:
- 确切文件名
- 补全
.js
拓展名 - 补全
.json
拓展名 - 补全
.node
拓展名 - 加载失败
- 加载自定义模块时,路径必须以
-
第三方模块加载
- 会从当前模块的父目录开始,尝试从
/node_modules
文件夹中加载第三方模块 - 如果没有找到对应的第三方模块,则会移动到再上一层父目录中进行加载,直到文件系统的根目录
- 会从当前模块的父目录开始,尝试从
-
目录加载
- 在加载的目录下找到
package.json
文件,并找到main
属性做为require()的加载入口 - 如果目录里没有
package.json
文件,或者没有main
属性或无法解析,则会尝试解析index.js
文件 - 以上都失败了,控制台报错打印
cannot find modules xxxx
- 在加载的目录下找到
三. 模块化向外共享模块作用域中的成员
Module.exports
//初始时,module.exports 是一个空对象。
module.exports.username = '小白';
module.exports.sayHello = function(){
console.log('Hello');
};
//使用require0方法导入模块时,导入的结果,永远以module.exports指向的对象为准。
module.exports = {
name:'小黑',
sayHi:function(){
console.log("Hi");
}
}
//外部引入结果:对象是小黑
exports
由于
module.exports
单词写起来比较复杂,为了简化向外共享成员的代码, Node提供了exports
对象。默认情况下,exports
和module.exports
指向同一个对象。最终共享的结果,还是以module.exports指向的对象为准。
//可以单独挂载各个属性
exports.username = '小白';
exports.sayHello = function(){
console.log('Hello');
};
//但是不可以使用整个对象赋值
//这样相当于修改了exports的引用
exports = {
name:'小黑',
sayHi:function(){
console.log('Hi');
}
}
//外部引入结果:对象是小白
下方是黑马视频中通过值修改两者的结果示例:
四. CommonJS模块化规范
Node.js 遵循CommonJS模块化规范,规定了模块的特性以及各个模块的相互依赖关系。
- 每个模块内部,
module
变量代表当前模块。 - module变量是一个对象,它的
exports
属性(即module.exports
)是对外的接口。 - 加载某个模块,其实是加载该模块的
module.exports
属性。require
方法用于加载模块。