node中内置了简单的模块加载系统,所有的功能都依赖于此加载系统。所以学习node先从了解它的模块加载系统开始
-
1. 每个模块中都能访问module对象,它包含如下几个属性
id: 模块的标识符,通常是模块完全解析后的名字, exports: 模块最终导出的对象,也就是我们经常显示指定的module.exports={} parents: 最先引用该模块的模块 filename: 模块完全解析后的文件名 children: 子模块
-
2. require.main
第一种:require.main === module判断当前文件是否被直接运行。如果是直接通过
node filename这种方式,为true。如果是被引用则为false第二种:require.main.filename访问应用程序的主入口
require.main可以访问主模块
- 3.模块的缓存机制,加载的模块可以通过require.cache访问
相同的模块在同一文件中如果被require多次,那么仅仅在第一次require的时候加载并返回一个对象,之后的require都会指向该对象
// 访问require.cache可以获取一个对象表示当前已加载的模块如果删除其中的键值对那么下一次require该模块的时候就会重新加载,不能重载核心模块否则会出错!!!!
如果想要多次执行一个模块,可以在该模块中导出一个方法来实现这个功能
【缓存注意事项】:模块缓存是基于require的文件位置以及文件名进行的。所以当功能相同的模块处在不同的位置或者是文件名不同时,那么require返回的对象都是不同的。
var a = require('../../server.js')
var b = require('../../../server.js') // 文件位置不同
var c = require('../../SERVER.js') //文件名不同
以上三种require会返回三个不同的require对象
-
4.核心模块优先加载
当有模块的名字与核心模块相同时,会先加载核心模块。 -
5.模块加载位置
需要'./','../'之类的位置表示文件加载的位置。如果没有则必须是核心模块或者是处在node_modules中,否则会报错 - 6.模块包装器
所有的模块代码在执行之前,node会用如下一个函数对它进行包装
(function(exports, require, module, __filename, __dirname) {
// 模块的代码实际上在这里
有如下三种好处
1.保证了var、let、const声明的变量处在当前作用域而不是全局变量
2.提供了一些看似是全局的变量进行使用,module以及exports
3.提供了变量快捷访问文件名称以及当前路径,__filename,__dirname
});