一个node js文件就相当于一个模块。
在客户端,通过script 标签引入 Js 文件,那么就可以访问其内容。但是这样会带来弊端很多,最大的就是作用域相同,产生冲突问题。nodejs 使用了 exports 对象和 require 对象来解决对外提供接口和引用模块问题。
Node 对外提供接口
可以把模块中希望被外界访问的内容定义到exports对象中。例如:
var name='';
function setName(n){
name=n;
}
function printName(){
console.log(name);
}
exports.setName=setName;
exports.printName=printName;
那么就可以这样使用:
var test=require('./test');
test.setName('Byron');
test.printName();
exports 对象
var Student=function(){
var name='';
this.setName=function(n){
name=n;
};
this.printName=function(){
console.log(name) ;
};
};
exports.Student=Student;
使用:
var Student=require('./test').Student;
var student=new Student();
student.setName('Byron');
student.printName();
同时,可以改成这个样子:
var Student=function(){
var name='';
this.setName=function(n){
name=n;
};
this.printName=function(){
console.log(name) ;
};
};
module.exports=Student;
使用的时候,就可以变成这个样子:
var Student=require('./test');
module.exports 与 exports 区别
首先,每个模块都会自动创建 一个 module 对象,对象有一个 modules 属性,初始值是个空对象。module 的公开接口 module.exports 就是公开这个属性。
为了方便,模块中也会有一个 exports对象,它和 module.exports指向的是同一个变量,所以我们修改exports对象的时候也会自动修改module.exports对象。
所以当module.exports对象不为空的时候, exports对象就自动忽略了,因为最后是返回 module.exports对象,而 module.exports对象 和exports对象指向已经不一样了。所以对exports对象的改动会失效。
require 搜索 module 方式
nodejs 模块有两种类型:核心模块和文件模块。核心模块直接使用名称获取。
- 核心模块优先级最高,当有命名冲突的时候,首先加载核心模块。文件模块只能按照路径加载。
- 查找node_modules 目录,当require 遇到一个既不是核心模块,又不是以路径表示的模块名称的时候,则会在当前目录下查找 node_modules 目录,如果没有,则会继续在当前目录的上一层的 node_modules 目录查找,以此循环到根目录。