module对象
Node内部提供一个Module
构建函数。所有模块都是Module
的实例。
//a.js文件中输出module对象
console.log(module);
运行:
node a.js
输出结果:
Module {
//模块的识别符,通常是带有绝对路径的模块文件名。
id: '.',
//当前模块的路径
path: 'C:\Users\LiZhiTong\Desktop\webpack资料\test\01',
//表示模块对外输出的值。
exports: {},
//表示调用该模块的模块。
parent: null,
//模块的文件名,带有绝对路径。
filename: 'C:\Users\LiZhiTong\Desktop\webpack资料\test\01\a.js',
//返回一个布尔值,表示模块是否已经完成加载。
loaded: false,
//返回一个数组,表示该模块要用到的其他模块。
children: [],
//模块的搜索路径(依次向上级目录搜索)
paths: [
'C:\Users\LiZhiTong\Desktop\webpack资料\test\01\node_modules',
'C:\Users\LiZhiTong\Desktop\webpack资料\test\node_modules',
'C:\Users\LiZhiTong\Desktop\webpack资料\node_modules',
'C:\Users\LiZhiTong\Desktop\node_modules',
'C:\Users\LiZhiTong\node_modules',
'C:\Users\node_modules',
'C:\node_modules'
]
}
module.exports属性
module.exports
属性表示当前模块对外输出的接口,它是一个对象,其他文件加载该模块,实际上就是读取module.exports
变量。
//一般直接使module.exports指向一个新的对象,并向外提供资源
module.exports = {
num: 1,
msg: "hello",
getNum() {
return this.num;
},
setMsg(str) {
this.msg = str;
}
};
require命令
require()
: 加载外部模块
require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。
const info=require('./lib');//后缀名可以省略,默认为.js,
根据参数的不同格式,require命令去不同路径寻找模块文件,如果参数字符串不以“./“或”/“开头,则表示加载的是一个默认提供的核心模块(位于Node的系统安装目录中),或者一个位于各级node_modules目录的已安装模块(全局安装或局部安装)。
require.cache
指向所有缓存的模块
第一次加载某个模块时,Node会缓存该模块。以后再加载该模块,就直接从缓存取出该模块的module.exports
属性。
//lib.js 文件
console.log('开始加载模块');
//一般直接使module.exports指向一个新的对象,并向外提供资源
module.exports = {
num: 1,
msg: "hello",
getNum() {
return this.num;
},
setMsg(str) {
this.msg = str;
}
};
console.log('模块加载完成');
console.log('加载子模块之前');
let mod = require('./lib.js');
let mod1 = require('./lib.js');
let mod2 = require('./lib.js');
输出:
加载子模块之前
开始加载模块
模块加载完成
即相同模块只加载了一次。
如果想要多次执行某个模块,可以让该模块输出一个函数,然后每次require这个模块的时候,重新执行一下输出的函数。
注意,缓存是根据绝对路径识别模块的,如果同样的模块名,但是保存在不同的路径,require
命令还是会重新加载该模块。
所有缓存的模块保存在require.cache中。
// 删除所有模块的缓存
Object.keys(require.cache).forEach(function (key) {
// console.log(key);
delete require.cache[key];
});
require.main
可以用来判断模块是直接执行,还是被调用执行。 require.main
属性指向模块本身
require.main === module //true
调用执行的时候(通过require
加载该脚本执行),上面的表达式返回false。
commonJS的特点及总结
每个模块内部,module
变量代表当前模块。这个变量是一个对象,它的exports
属性(即module.exports
)是对外的接口。加载某个模块,其实是加载该模块的module.exports
属性。
1、所有代码都运行在模块作用域,不会污染全局作用域。
2、模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
3、模块加载的顺序,按照其在代码中出现的顺序。