Node.js学习记录四:Node的模块开发
一、什么是模块化开发
js在一开始使用时,存在多个js引用先后问题,执行顺序是按引入的顺序,
但有可能先引入的js文件依赖后引入的js文件,会出现问题。而且多个js文件中可能会有同名的全局变量,后引入的文件中的同名变量会覆盖前面引入js文件中的同名变量,会发生错误。
在模块化开发中,文件之间的关系不需要认为来维护,且模块之间,同名的全局变量不会互相影响,只暴露需要使用的变量。
node.js规定一个js文件就是一个模块,模块内部定义的变量和函数在外部无法得到的。
node使用的是CommonJS规范
二、Node.js 中模块的分类
Node.js 中根据模块来源的不同,将模块分为了 3 大类,分别是:
- 内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http 等)
- 自定义模块(用户创建的每个 .js 文件,都是自定义模块)
- 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
三、 Node.js 中的模块作用域
和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。
模块作用域的好处就是防止了全局变量污染的问题。
三、引入模块require()
使用强大的 require() 方法,可以加载需要的内置模块、用户自定义模块
一个文件的引入,引入的是一个模块对象,方法都在这个对象上。
//1.加载内置的 fs 模块
const fs = require('fs')
//.2.加载用户的自定义模块
const custom = require('./custom.js')
//3.加载第三方模块
const moment = require('moment')
注意:使用 require() 方法加载其它模块时,会执行被加载模块中的代码。
四、导出模块
1.exports
使用exports对象导出模块,可以看成导出的方法都在这个exports对象实例上。
function test(){
console.log('test')
}
let demo = function(){
console.log('demo')
}
exports.test = test
exports.demo = demo
2.module.exports
在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象
module.exports和exports使用方法一致
exports是module.exports的别名,他们就是两个不同名的变量,但地址都是引用的同一个模块对象,同一个文件的多个方法,既可以使用exports点方法的形式导出也能使用module.exports点方法的形式导出。但要是module.exports直接等于一个对象时,最终的导出按这个对象为准。
let a = 'test';
let b = 'demo';
exports.a = a;
module.exports.b = b;
//到这为止都能成功导出a和b,在另一个文件中可以得到
//接下来,要是写上
module.exports = {
a : 'change'
}
//此时其他文件引入的模块对象就是这个对象了,上面的a和b被覆盖掉了。可以看作重新赋值了一个模块对象。
//要是同时写module.exports = {
//a : 'change'
//}和下面的exports
exports = {
b: 'test'
}
//其他文件引用的还是module.exports 导出的对象。
使用 require() 方法导入模块时,导入的结果,永远以 module.exports 指向的对象为准。
五、使用es6的模块化规范
Node.js 遵循了 CommonJS 模块化规范,CommonJS 规定了模块的特性和各模块之间如何相互依赖。
CommonJS 规定:
① 每个模块内部,module 变量代表当前模块。
② module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
③ 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。