码迷,mamicode.com
首页 > 其他好文 > 详细

Node中的包和模块

时间:2016-05-13 04:35:03      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

一、模块和包

概念:模块(Module)和包(Package)是Node.js最重要的支柱。开发一个具有一定规模的程序不可能只用一个文件,通常需要把各个功能拆分、分装、然后组合起来。模块正式为了实现这种方式而诞生,在浏览器JavaScript中,脚本模块的拆分和组合通常使用HTML的script标签来实现,Node.js提供了require函数来调用其他模块,而且模块都是基于文件,机制非常简单,模块和包的区别是透明的,因此经常不作区分。

模块

1.什么是模块

模块和文件是一一对应的。一个Node.js文件就是一个模块,这个文件可能是JavaScript代码、JSON或者编译过的C/C++扩展。
var http=require(‘http’),其中http是Node.js的一个核心模块,通过require函数获取这个模块,然后使用其中的对象.

2.创建和加载模块

(1)创建模块

Node.js提供了exports和require两个对象,其中exports是模块的公开接口,require()是从外部获取一个模块的接口,下面提供了一个例子:
下面是module.js代码:

var name;
exports.setName=function(getName){
    name = getName;
}
exports.setHello=function(){
    console.log(‘hello‘+name);
}

下面的是getModule.js代码:

var myModule = require(‘./module‘);
myModule.setName(‘helios‘);
myModule.setHello();

输出是hellohelios

(2)单次加载

通过require函数得到的这个文件里面有暴露属性的对象(exports),因为require不会重复加载模块无论重复加载多少次,获取的模块都是第一个require的,看下面改动后的getModule.js代码

var myModule1 = require(‘./module‘);
// 设置myModule1对象的name
myModule1.setName(‘helios‘);
var myModule2 = require(‘./module‘);
// 设置myModule2对象的name
myModule2.setName(‘newName‘);
//调用myModule1的方法setHello
myModule1.setHello();   //输出的是hellonewName
//这就说明了无论怎么改动都是改动了第一次引用的require

(3)覆盖exports

要理解这个问题就先要理解exportsmodule.exports分别是什么意思;
其实在一开始的时候exportsmodule.exports就是一个东西,这里说他们是一个东西其实并不确切,更应该说exportsmodule.exports指向的是同一块内存,为什么这么说呢请看下面这个例子:

console.log(exports  === module.exports);//true
console.log(exports);//{}
console.log(exports == {});//false
console.log(module.exports);//{}
console.log(module.exports  ==  {});//false

exports赋值就相当于给module.exports添加属性,如下面代码:

var name = ‘helios‘;
exports  = name;
exports.setName = function(){}  

上面的代码就相当于下面的代码:

var name = ‘helios‘;
module.exports  = name;
module.exports.setName = function(){}  

我们通过require的到的其实是一个module.exports方法,为什么这么说呢!请看下面的这几个例子:
1.下面是modul.js

exports.name=function(){
    console.log("this is name method");
}

下面这个是getModule.js

var myModule1 = require(‘./module‘);
myModule1.name();

2.下面对module这个文件改动了一下:

module.exports=function(){
    console.log("this is name method");
}

下面是对getModule.js的稍稍改动

var myModule1 = require(‘./module‘);
myModule1();

2.exportsmodule.exports指向的是同一块内存那么为什么不用下面这样方法写呢?
下面是对module.js的改动

exports=function(){
    console.log("this is name method");
}

如果写成了这样不论geyModule.js写为什么样子都会报错,这就引出了下面的结论:require返回的其实是module.exports这个方法,exports其实是指向module.exports的一个引用
换一种说法就是这样写法是对exports进行了覆盖,也就是说exports指向了一块新的内存(因为对他重新赋值了),也就是说无论exports怎么变化module.exports内存都是没有的不会变化,我们在getModule.js引入了一个空对象肯定会报myModule1 is not a function这样的错误。
所以我们会经常看到这样的写法:

exports = module.exports = somethings

上面的代码就等价于:

module.exports = somethings//对module.exports进行覆盖
exports = module.exports  //对exports进行覆盖

这就是为了保证exportsmodule.exports还是指向的是同一块内存;
有的时候为了方便我们会把所有的方法或者属性都放在构造函数里面,然后在对方暴露这个构造函数:
下面是module.js

 function hello(){
    var name;
    this.setName=function(thyName){
        name=thyName;
    }
    this.sayHello=function(){
        console.log(‘hello ‘+name);
    }
}
//exports.hello=hello;
module.exports=hello;

下面是getModule.js

var hello=require(‘./module‘);
var he=new hello();//helloundefined
he.setName(‘shangyilong‘);
he.sayHello();//helloshangyilong
var he2=new hello();
he2.setName(‘helios‘);
he2.sayHello();//hellohelios

这样就能克服require单次加载的弊端了。

1.包的概念

包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的函数库或者java的类库,它讲某个独立的功能封装起来,用于发布、更新、依赖管理的版本控制。开发了npm来解决包的发布和获取需求。
包是由package.json定义的文件或目录
我们通过npm install XX 后面的XX就是包
我们可以通过npn init初始化一个包。我们可以把这个包做大然后上传到nodejs给别人使用

这是Node的一个系列,可以在本栏目下看其他关于Node文章,会 一直更新,有问题请在下方留言

Node中的包和模块

标签:

原文地址:http://blog.csdn.net/woshinannan741/article/details/51339495

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!