Node中的包和模块

一、模块和包

概念:模块(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文章,会 一直更新,有问题请在下方留言

时间: 2024-08-23 15:01:51

Node中的包和模块的相关文章

node中的常用核心模块及方法

常用的5个核心模块 http url querystring fs events 1. http http.createServer 创建服务器, 回调函数中有2个参数 1.req:request() 请求,只能在服务端看到 2.res:response() 给客户端的回复,在客户端看到 req参数: req.url 获取请求的地址 eg:http://www.baidu.com/api/list?a=23&b=f,则req.url为/api/list req.method 请求的方式get/p

Node中http模块详解(服务端篇)

Node中的Http Node中提供了http模块,其中封装了高效的http服务器和http客户端 http.server是一个基于事件的HTTP服务器,内部是由c++实现的,接口由JavaScript封装 http.request是一个HTTP客户端工具.用户向服务器发送数据. 下面就来分别得介绍一下http的服务端和客户端 一.HTTP服务器 http.Server实现的,它提供了一套封装级别很低的API,仅仅是流控制和简单的解析,所有的高层功能都需要通过它的接口,就像在前面的文章<Node

简单剖析Node中的事件监听机制(一)

使用js的class类简单的实现一个事件监听机制,不同于浏览器中的时间绑定与监听,类似于node中的时间监听,并且会在接下来的文章中去根据自己的理解去写一下Event模块中的原理. Node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高效.并且Node中的大量模块都使用了Event机制,因此可以说是整个Node中最重要的模块之一. 实例: let event = new eventEmitter(); event.on('someType',function(){ }); even

Node.js权威指南 (4) - 模块与npm包管理工具

4.1 核心模块与文件模块 / 574.2 从模块外部访问模块内的成员 / 58 4.2.1 使用exports对象 / 58 4.2.2 将模块定义为类 / 58 4.2.3 为模块类定义类变量或类函数 / 614.3 组织与管理模块 / 61 4.3.1 从node_modules目录中加载模块 / 61 4.3.2 使用目录来管理模块 / 62 4.3.3 从全局目录中加载模块 / 624.4 模块对象的属性 / 634.5 包与npm包管理工具 / 65 4.5.1 Node.js中的包

Node中require第三方模块的规则

Node.js中使用CommonJs模块化机制,通过npm下载的第三方包,我们在项目中引入第三方包都是:let xx = require('第三方包名'),究竟require方法加载第三方包的原理机制是什么,今天我们来探讨下. require('第三方包名')优先在加载该包的模块的同级目录node_modules中查找第三方包. let template = require('art-template') //加载第三方包 找到该第三方包中的package.json文件,并且找到里面的main属

node中的require是如何加载模块的

在使用node引入模块的时候,我发现node自带的模块或是npm安装的第三方模块,只需要require个名字就可以加载到了,像是 require('fs') require('http') require('express') 但是自己写的模块就必须要加上路径,比如 require('./a') require('a')//这样就不行, 为什么第三方模块就不需要加路径呢?express的路径明明是node_modules/express/index.js 那是不是我把自己写的模块放到node_m

log4js-Node.js中的日志管理模块使用与封装

开发过程中,日志记录是必不可少的事情,尤其是生产系统中经常无法调试,因此日志就成了重要的调试信息来源. Node.js,已经有现成的开源日志模块,就是log4js,源码地址:点击打开链接 项目引用方法: npm install log4js 1.配置说明(仅以常用的dateFile日志类型举例,更多说明参考log4js-wiki): { "appenders": [ // 下面一行应该是用于跟express配合输出web请求url日志的 {"type": "

node中的模块

模块 编写稍大一点的程序时一般都会将代码模块化.在NodeJS中,一般将代码合理拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名. 在编写每个模块时,都有require.exports.module三个预先定义好的变量可供使用. require require函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象.模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头).另外,模块名中的.js扩展名可以省略.以下是一个例子. var

Node中的模块引入机制

1.如果模块在当前目录下,可以通过下面语句将模块引入进来,注意需要使用 "./"表示当前路径 const currency = require('./currency'); ←---- 用路径./表明模块跟程序脚本放在同一目录下 2.如果模块在当前目录的子目录下,可以加上子目录的名称,如下. const currency = require('./lib/currency'); 3.要求模块在文件系统中使用相对路径存放,对于组织程序特定的代码很有帮助,但对于想要在程序间共享或跟其他人共