通过Node.js官方API可以看到Node.js本身提供了很多核心模块http://nodejs.org/api/,而这些核心模块编译成二进制文件可以通过require('模块名');获取核心模块加载优先级最高(当存在与核心模块同名的模块时会体现),如:varfs=require('fs');varhttp=require('http')文件模块访问方式通过require('/filename.suffix')require('./filename.suffix')requrie('../filename.suffix')访问,文件后缀可以省略;以“/”开头表示以绝对路径加载,以“./”和“../”开头表示以相对路径加载,以“./”开头表示同一目录下的文件,如:varmyadd=require('./add');//在此目录下添加.jsexports和module.exports;提供对外访问接口(本文讲的是exports和module.exports,都是对外暴露的文件,然后引用,属于文件模块核心模块是node写的,直接引用就行)说说他们的区别1.模块导入将被缓存。如果你写了多个导入,它只会被导入一次。即使导入的路径不同。它的缓存是指实际的文件名,不会因为传入的路径格式不同而被识别为不同的文件。varoutputVal=0;//输出值varincrement=1;//增量/*设置输出值*/functionseOutputVal(val){outputVal=val;}/*设置增量*/functionsetIncrement(incrementVal){increment=incrementVal;}/*输出*/functionprintNextCount(){outputVal+=增量;console.log(outputVal);}functionprintOutputVal(){console.log(outputVal);}exports.seOutputVal=seOutputVal;exports.setIncrement=setIncrement;module.exports.printNextCount=printNextCount;一个Node.js文件是一个模块,这个文件可以是Javascript代码,JSON,或者编译后的C/C++扩展。两个重要的对象:require是从外部获取模块,exports是暴露模块接口varcounter=require('./1_modules_custom_counter');console.log('第一次调用模块[1_modules_custom_counter]');counter.seOutputVal(10);//设置从10开始计数counter.setIncrement(10);//设置增量为10counter.printNextCount();counter.printNextCount();counter.printNextCount();counter.printNextCount();//require多次调用同一个模块不会重复加载varcounter=require('./1_modules_custom_counter');console.log('第二次调用模块[1_modules_custom_counter]');counter.printNextCount();2.通过exports和module.exports的公共方法可以访问,但是有区别。module.exports才是真正的接口,exports只是它的一个辅助工具。 最后返回给调用的是module.exports,而不是exports。exports收集的所有属性和方法都分配给Module.exports。当然有个前提,module.exports本身是没有任何属性和方法的。如果module.exports已经有一些属性和方法,则exports收集的信息将被忽略。我把exports和module.exports都打印出来看看发生了什么①(虽然这样在导入模块的时候会报错,但是这一步可以说明问题,后面会解释原因)varcounter=0;exports.temp=function(){计数器+=10;this.printNextCount=function(){console.log(计数器);}}varisEq=(exports===module.exports);console.log(exports);console.log(module.exports);console.log(isEq);结果:通过exports导出的方法会传递给module.exports。两者没有区别varcounter=0;module.exports=function(){counter+=10;this.printNextCount=function(){console.log(计数器);}}varisEq=(exports===module.exports);console.log(exports);console.log(module.exports);console.log(isEq);result:直接传给module.exports,然后exports意思是没有,两者不相等。③:注意导入时是有区别的。与上面第一大点不同的是,如②varCounter=require('./');varcounterObj=newCounter();counterObj.printNextCount();而第一个要点可以直接这样:varcounter=require('./1_modules_custom_counter');console.log('第二次调用模块[1_modules_custom_counter]');counter.printNextCount();只想要一个新对象!因为导出文件中的函数变成了成员方法,所以需要new一个对象,然后调用成员方法。解释①不可行的原因:我在其他文件中调用的时候,不管是直接调用还是用新的对象调用,都会报错!因此,遵循以下两点:1、最好不要单独定义module.exports和exports。2、NodeJs开发者推荐用module.exports导出对象,用exports3、exports、module.exports导出多个方法和变量,直接上传代码。看看谁留下来谁消失了varcounter=0;exports.printNextCount=function(){counter+=2;控制台日志(计数器);}module.exports=function(){counter+=10;this.printNextCount=function(){console.log(counter)}}varisEq=(exports===module.exports);console.log(exports);console.log(module.exports);console.log(isEq);想想谁厉害。引用本模块:①报错,说明exports消失了varcounter=require('./test3');counter.printNextCount();②依然存在。varcounter=require('./test3');varcounterObj=newcounter()counterObj.printNextCount();结果,它输出它成功导出的对象函数的值;前两个是两个接口收集的东西,最后一个exports是coveredexports只是引用module.exports的地址。nodejs只会导出module.exports的指向。如果exports的指向发生变化,只是exports不再指向module.exports,所以不会再导出。相当于:a和b指向同一块内存,b是a的地址引用vara=newObject();//a相当于module.exportsvarb=a;//b相当于exportscoverage,即a已经被赋值,但是b被赋了另外一个值。此时b是叛徒,指向一个新的地址。modulereference是要被module.exports引用的,所以指向新地址的exports将不起作用。
