采用了 Commonjs 规范,经过 module.exports、require
来导出和导入模块。模块加载机制中,采用了延迟加载的策略。就是说在用到的状况下,系统模块才会被加载,等加载完成后会放到 binding_cache 中。javascript
http、buffer、fs
等,底层调用的内建模块 (C/C++);express、koa、moment.js
等;.
、..
、/
开头的;module.js
;module.json
;module.node
;经历 路径分析
、文件定位
和编译执行
。java
路径分析、文件定位
,会直接被加载到了内存中,其中系统模块定义在源码的 lib 目录下;.、..、/
开头的,会依次按照 .js、.json、.node
进行扩展名补足尝试(文件没有加上扩展名),最好仍是加上文件的扩展名。package.json
中查找;模块缓存后,能够经过 require.cache
查看已缓存的模块。node
// 模块文件 require.module.js
module.exports = {
name: 'pr',
say(){ }
}
复制代码
// 引用模块文件 require.cache.js
require('./require.module');
console.log('require.cache ----- ');
console.log(require.cache);
复制代码
1.exports 与 module.exports 关系git
const exports = module.exports;
复制代码
因此就不能改变 exports 的指向,能够这样github
exports.info = {
name: 'pr',
age: 30
}
module.exports = {
name: 'pr',
age: 30
}
复制代码
模块 moduleA.js
和 moduleB.js
两个模块互相引用,会怎样?express
// moduleA.js
console.log('模块 moduleA');
exports.name = 'moduleA name';
age = 27;
const moduleB = require('./moduleB.js');
console.log('moduleA require moduleB =>', moduleB.name);
复制代码
// moduleB.js
console.log('模块 moduleB');
exports.name = 'moduleB name';
const moduleA = require('./moduleA.js');
console.log('moduleB require moduleA =>', moduleA.name);
复制代码
node moduleA.js
,会打印 模块 moduleA
;moduleA.js
中加载 moduleB.js
,打印 模块 moduleB
;moduleB.js
中又加载 moduleA.js
,此时模块 moduleA.js
尚未执行完,返回模块 moduleA.js
的 exports
对象给到模块 moduleB.js
;moduleB.js
加载完后,其中有个 moduleA.js
中挂载了全局的变量 age
,因此能打印出来,最后将模块 moduleB.js
的 exports
对象给到模块 moduleA.js
;颇有意思的是,在代码执行前,会用一个封装器将执行代码段封装起来json
(function(exports, require, module, __filename, __dirname) {
// something
});
复制代码