Node.js 模块加载导出
Galloping_Leo 2020-01-17 node基础模块
# 模块的加载导出
在node.js中每一的JavaScript文件就是一个文件作用域,文件之间的数据不可相互调用。
若某一文件要使用另一文件的某一数据,那么该文件就必须将要求的数据暴露出来。使用module.exports 或者exports
假定a.js与b.js在同一根目录下
a.js文件
const add = (a,b) => a+b
module.exports = {
"add": add
}
//也可写成
module.exports.add = add
//或者
exports.add = add
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
b.js文件
const a = require('./a')
console.log(a.add(1,3))
//结果4
1
2
3
2
3
a.js 将 其中的add方法通过挂载到module.exports上供 b.js调用
疑问
既然module.exports.add = add与exports.add = add都可以满足向外暴露数据的要求,为什么还并存?
module.exports和 exports联系,以及应该 注意些什么 ?
# exports 与 module.exports 的联系
- 早期使用
module.exports来向外部暴露文件内部数据,module.exports太长写起来不方便,于是就催生了exports - 实际上初始状态下
exports和module.exports指向同一对象,exports就相当属于module.exports的别名 - 最终文件暴露出去的数据以
module.exports为准
# 使用注意
- 避免在同一文件中同时使用这两种方式(容易引起混淆)
const b = 12
const add = a => a+=1
module.exports.b = b
exports.add = add
1
2
3
4
5
2
3
4
5
- 最好不要直接给
exports,module.exports赋值
二者指向同一对象,如果其中一个重新赋值,那么exports 与module.exports之间的联系就会被切断,容易出错
const b = 12
const add = a => a+=1
//重新赋值后 与 exports 指向了不同的对象
module.exports = add
//exports任然指着原来的对象,只是在原来的对象上添加了一个属性
exports.b = b
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
这时exports 再添加属性就不再起作用(因为最后向外暴露的值以module.exports所指对象为准)除非重新建立 exports与module.exports之间的联系
exports = module.exports
1
总的来说就单一使用exports就好
# 模块加载机制
# 查找规则
# 当模块拥有路径但没有后缀时
require('./find.js');
1
require('./find');
1
require方法根据模块路径查找模块,如果是完整路径,直接引入模块。- 如果模块后缀省略,先找同名JS文件再找同名
JS文件夹 - 如果找到了同名文件夹,找文件夹中的
index.js - 如果文件夹中没有
index.js就会去当前文件夹中的package.json件中查找main选项中的入口文件 - 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到
# 当模块没有路径且没有后缀时
require('find');
1
Node.js会假设它是系统模块Node.js会去node_modules文件夹中- 首先看是否有该名字的
JS文件 - 再看是否有该名字的文件夹
- 如果是文件夹看里面是否有
index.js - 如果没有
index.js查看该文件夹中的package.json中的main选项确定模块入口文件 - 否则找不到报错
