nodejs的模块化

NodeJs采用的是CommonJs规范,在NodeJs中,一般将代码合理拆分到不同的js文件中,每个文件就是一个模块,而文件路径就是模块名;在编写每个模块时,均有require、exports、module三个预订好的变量可供使用
NodeJs中模块分为三类:
1.核心模块(已经封装好的内置模块)
2.自己定义的模块
3.第三方的模块(通过npm下载的)

require函数用于在一个模块中引入另外一个模块,传入一个模块名,返回一个模块导出对象,用法:require("模块名"),该函数有两个作用:
1.执行导入的模块中的代码
2.返回导入模块中的接口对象
require既可以引入系统模块,也可以引入自定义模块,为便于区分,即使在当前目录下,也需要使用require("./XXX"),其中.js后缀可以省略

require加载模块:
1.如果有路径: 直接从当前目录寻找
2.没有路径:先从系统模块寻找,再从node_modules中寻找(优先在加载该包的模块的同级目录node_modules中查找第三方包,在node_modules中可以找到该第三方包中的package.json文件,并且找到里面的main属性对应的入口模块,该入口模块即为加载的第三方模块,如果没有main属性,则默认加载第三方包的index.js文件;如果在加载第三方包的同级目录没有找到node_modules文件夹,或者以上所有情况都没有找到,则会向上一级父级目录下查找node_modules文件,查找规则如上一致,如果一直找到该磁盘的根路径都没有找到,则会报错)

module.exports与exports

如果想向外输出,须加上exports,如:

// main.js:
exports.a = 123;

// 1.js:
const mod1=require('./mod.js');
console.log(mod1.a);

注:nodejs没有全局变量

module用于同时输出多个:

module.exports = {
    a: 12, b: 15
};

当然也可以使用:

exports.a=12;
exports.b=15;

注意:系统实际上是获取module.exports定义的对象
每个模块都会自动创建一个module对象,对象有一个exports的属性,初始值是个空对象{},module的公开接口就是这个属性——module.exports。
module的结构如下:

模块中有一个exports对象,和module.exports指向同一个变量(exports是module.exports的别名——地址引用关系,最终导出对象以module.exports为准),所以当修改exports对象的时候也会修改module.exports对象;但是module.exports对象不为空的时候应该自动忽略exports对象,因为module.exports通过赋值方式已经和exports对象指向的变量不同了,exports对象与module.exports对象已经无关。

console.log(module.exports == exports); // 结果为true
module.exports = {
    a: 1
}
console.log(module.exports == exports); // 结果为false

同理,当直接给exports对象赋值(注意不是给exports添加属性,而是直接重新赋值)的时候,由于没有改变module.exports,因此得到的是一个空对象

// test1.js模块
let a = 123;
let b = 456;
exports = {
    a: a,
    b: b
}

// test.js模块
let obj = require("./test1");
console.log(obj);    // 结果为{}

当模块没有任何内容导出时,通过require引入该模块将得到一个空对象

模块的初始化

模块中的js代码仅仅在模块第一次被使用时执行一次,并且在使用的过程中进行初始化,之后缓存起来便于后续继续使用

posted @ 2020-03-15 10:01  kanaliya  阅读(187)  评论(0)    收藏  举报