概述
Node 应用是有模块组成的,一个文件就是一个模块,有单独的作用域,文件中声明的变量、方法和类都是私有的,如果需要在外部能访问,则需要使用 module.exports
或则 exports
暴露出去
module 对象
Node 内部提供一个 Module 构建函数。模块是Module的实例。
function Module(id, parent) {
this.id = id;
this.exports = {};
this.parent = parent;
// ...
每个模块内部都有一个 module 对象,module 代表模块本身,module 的 exports 属性(即 module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
module.id 模块的识别符,通常是带有绝对路径的模块文件名。
module.filename 模块的文件名,带有绝对路径。
module.loaded 返回一个布尔值,表示模块是否已经完成加载。
module.parent 返回一个对象,表示调用该模块的模块。
module.children 返回一个数组,表示该模块要用到的其他模块。
module.exports 表示模块对外输出的值。
require 方法用于加载模块,即加载的是 module.exports 对象
示例
可以结合下面的例子进行理解
// example.js
let baseNum = 1;
let addOne = function (num) {
return baseNum + num;
}
module.exports.baseNum = baseNum;
module.exports.addOne = addOne;
console.log('example', module)
// main.js
let example = require('./example.js')
console.log(example)
console.log(example.baseNum);
console.log(example.addOne(5));
example.js 和 main.js 是两个单独的文件,可以看做是两个模块,正常情况下在 main.js 文件中是访问不到 example.js 文件里的 baseNum 和 addOne 的,但是 example 文件里使用了 module.exports, 所以 main 里可以访问到。
example 里的 module 可以看做是 example.js 这个模块本身的实例, 执行 node example.js
输出 module 结果:
// console.log('example', module)
example Module {
id: '.',
exports: { baseNum: 1, addOne: [Function: addOne] },
parent: null,
filename: '/home/user/Desktop/nodetest/example.js',
loaded: false,
children: [],
paths:
[ '/home/user/Desktop/nodetest/node_modules',
'/home/user/Desktop/node_modules',
'/home/user/node_modules',
'/home/node_modules',
'/node_modules' ] }
main 文件中引入了 example 文件,相当于引入了 main 模块的 module.exports,执行 node main.js
输出结果如下:
// example.js 的 console 输出结果
Module {
id: '/home/user/Desktop/nodetest/example.js',
exports: { baseNum: 1, addOne: [Function: addOne] },
parent:
Module {
id: '.',
exports: {},
parent: null,
filename: '/home/user/Desktop/nodetest/main.js',
loaded: false,
children: [ [Circular] ],
paths:
[ '/home/user/Desktop/nodetest/node_modules',
'/home/user/Desktop/node_modules',
'/home/user/node_modules',
'/home/node_modules',
'/node_modules' ] },
filename: '/home/user/Desktop/nodetest/example.js',
loaded: false,
children: [],
paths:
[ '/home/user/Desktop/nodetest/node_modules',
'/home/user/Desktop/node_modules',
'/home/user/node_modules',
'/home/node_modules',
'/node_modules' ] }
// main.js console.log(example) 输出结果
{ baseNum: 1, addOne: [Function: addOne] }
1
6
exports 变量
为了方便,Node为每个模块提供一个 exports 变量,指向 module.exports。这等同在每个模块头部,有一行这样的命令: var exports = module.exports;
,所以上面的example.js 可以改成:
// example.js
let baseNum = 1;
let addOne = function (num) {
return baseNum + num;
}
exports.baseNum = baseNum;
exports.addOne = addOne;
console.log('example', module)
需要注意的是下面两种方式是错误的
exports = addOne; // exports 被重新赋值了,不在指向module.exports
exports.addOne = addOne;
module.exports = 'hello'; // exports 指向 module.exports, module.exports 指向了一个字符串,所以addOne不能被外部访问了