NodeJS采用CommonJS规范实现了模块系统
CommonJS规范规定了如何定义一个模块, 如何暴露(导出)模块中的变量函数, 以及如何使用定义好的模块
- 在CommonJS规范中一个文件就是一个模块
- 在CommonJS规范中每个文件中的变量函数都是私有的,对其他文件不可见的
- 在CommonJS规范中每个文件中的变量函数必须通过exports暴露(导出)之后其它文件才可以使用
- 在CommonJS规范中想要使用其它文件暴露的变量函数必须通过require()导入模块才可以使用
例如,在exp.js中定义
let name ='jiaody';
function add(a,b){
return a+b;
}
exports.name = name;
exports.func = add;
如果想在exp.js中引用exp.js中定义的函数和变量:
let modu = require('./exp.js');
console.log(modu);
console.log(modu.name);
console.log(modu.func(1,2));
运行结果为:
{ name: 'jiaody', func: [Function: add] }
jiaody
3
模块导出:
1.通过exports.xxx = xxx导出
2.通过module.exports.xxx = xxx导出
exports只能通过 exports.xxx方式导出数据, 不能直接赋值
module.exports既可以通过module.exports.xxx方式导出数据, 也可以直接赋值
exports === modules.export
当一个模块需要导出单个成员时 不能直接使用exports
exports 和 modules.export 指向同一个对象
如果对exports 重新赋值
那么 exports 就指向了新的对象
而代码执行的最后一句,默认返回的是 modules.export 所以不能使用 exports对单个成员赋值
(如exports = 123)
给 exports 赋值会断开和 module.exports 之间的引用
同理,给 module.exports 重新赋值也会断开 (如modules.export = 'hello')
谁来require当前模块,谁就得到 module.exports
默认在代码最后有一句: return module.exports
在使用时:
导出多个成员:exports.xxx = xxx
导出多个成员也可以:module.exports = {
}
导出单个成员:module.exports
//练习
exports.foo = 'bar' // {foo: bar}
module.exports.a = 123 // {foo: bar, a: 123}
exports = {a: 456 } // exports !== module.exports 最终 return 的是 module.exports
// 所以无论你 exports 中的成员是什么都没用
module.exports.foo = 'haha' // {foo: 'haha', a: 123}
exports.c = 456 // 混淆你的
// 重新建立了和 module.exports 之间的引用关系了
exports = module.exports
exports.a = 789 // {foo: 'haha', a: 789}
module.exports = function () {
console.log('hello')
} // 最终得到的是 Function
// 如果实在分不清楚 exports 和 module.exports
// 忘记 exports
// 而只使用 module.exports
// module.exports.xxx = xxx
// moudle.exports = {}
require
1. 使用require导入时可以不添加导入模块的类型
如果没有指定导入模块的类型, 那么会依次查找.js .json .node文件
无论是三种类型中的哪一种, 导入之后都会转换成JS对象返回
2. 导入自定义模块时必须指定路径
require可以导入"自定义模块(文件模块)"、"系统模块(核心模块)"、"第三方模块"
导入"自定义模块"模块时前面必须加上路径
导入"系统模块"和"第三方模块"是不用添加路径