node第二课 模块和包(模块和npm)
什么是模块
模块时构成Node应用的组件。实际上,我们已经看到过一些模块了——我们在Node中使用的每一个Javascript文件都是一个模块。
在上一篇文章中,我们用到了var http = require(‘http’),其中http是Node.js的一个核心模块,其内部是用C++实现的,外部用JavasScript封装。我们通过require来获取这个模块,然后使用其中的对象。
如何创建和调用模块
在Node里面,模块分为原生模块和文件模块(实际上只有一个都是文件模块只不过前者是Node自带的文件模块,后者是开发者自定义的模块)
如何创建并调用原生模块
原生模块是不需要开发者创建的
调用的时候可直接调用(常用的有)
var http = require('http') //创建服务器
var mysql = require('mysql')//创建数据驱动
var dns = require('dns'), //DNS查询
var fs = require('fs'), //文件操作
var url = require('url'), //url处理
如何创建文件模块
创建一个模块非常简单,因为一个文件就是一个模块,我们要关注的问题仅仅在于如何在其他文件中获取这个模块。Node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。
举个栗子,创建一个module.js的文件,内容是:
//module.js
var name;
exports.setName = function(thyName){
name = thyName;
};
exports.sayHello = function(){
console.log("Hello " + name);
};
在同一目录下创建一个getModule.js,为的是调用上面的模块文件
//getModule.js
var myModule = require('./module');
myModule.setName('minchao');
myModule.sayHello();
运行 node getModule.js,结果是
Hello minchao
代码解释:在getModule中,通过exports对象把setName和sayHello作为模块的访问接口,在getModule.sj中通过require(‘./module’)加载这个模块,然后就可以直接访问module.js中export对象的成员变量和函数了。
这种方式可以想象成java种的import xx.class;然后就可以在当前文件中使用这个类创建对象了,区别就是,require导入的只是export对象实例。而不是类。
这种接口封装方法比许多语言要简洁得多,同时也不失优雅,未引入违反语义的特性和符合传统的编程逻辑。
在这个基础上,我们可以构建大型的应用程序,npm提供的上万个模块都是通过这种简单的方式搭建起来的。
单次加载
上面的例子有点类似于在本文件中创建一个对象,但实际上和对象又有本质的区别,因为require不会重复加载模块,也就是说无论调用多少次require,获得的模块都是同一个。我们在getMdoule.js的基础上稍作修改
//loadModule.js
var hello1 = require('./module');
hello1.setName("minchao");
var hello2 = require("./module");
hello2.setName("micale");
hello1.sayHello();
运行 node getModule.js ,结果是
hello micale
代码解释:由此可以看出,无论在写多少次require(‘./module’);在代码中始终修改的都只是一个对象实例。因此的前面的操作都会被后面的操作覆盖。输出结果是由后者决定的。
覆盖exports
有时候,我们只想把一个对象封装到模块中,例如:(重新创建一个singleObject.js)
//singleObject.js
function Hello(){
var name;
this.setName = function(thyName){
name = thyName;
};
this.sayHello = function(){
console.log("hello " + name);
};
};
exports.Hello = Hello;
此时,我们在其他文件中同样需要通过require(‘./singleObject’).Hello来获取Hello对象,
//getSingleObject.js
var Hello = require('./singleObject').Hello;
hello = new Hello();
hello.setName("minchao");
hello.sayHello();
hello2 = new Hello();
hello2.setName("micale");
hello2.sayHello();
运行 node getSingleObject.js
hello minchao
hello micale
这样就略显冗余,可以使用下面的方法微简化:
//hello.js
function Hello(){
var name;
this.setName = function(thyName){
name = thyName;
};
this.sayHello = function(){
console.log("hello " + name);
};
};
module.exports = Hello;
创建getHello.js
var Hello = require('./hello');
hello = new Hello();
hello.setName("minchao");
hello.sayHello();
hello2 = new Hello();
hello2.setName("micale");
hello2.sayHello(); 运行结果是:
hello minchao
hello micale
注意
模块接口的唯一变化是使用module.exports = Hello代替了 exports.Hello=Hello
在外部引用该模块时,其接口对象就是要输出的Hello对象本身,而不是原先的exports。
事实上,exports本身是一个普通的空对象,即{},它专门用来声明接口,本质上是通过它为模块闭包的内部建立了一个有限的访问接口。
因为它没有任何特殊的地方,所以可以用其他东西来代替,譬如我们上面例子中的Hello对象。
总结
-
如果报错 “can not find xx module”说明你的路径是错的或者你文件不存在
比如,var test = require(‘/path/../test.js’) //也可以写成 var test = require(‘/path/../test’)
代表的绝对路径,如果要使用相对路径,需要在最前面加上一个”./”,require(“./test”)
- 顶级目录的模块标识符不可以是”.”、”..”或”./”开头,这些模块存储在摸个目录中mode_modules目录。
- 模块引入的时候,可以省略模块js的后缀名
- test返回值:require加载模块成功后返回的同样也是一个对象
以上就是模块的创建和调用的全部内容。
包和包管理器(npm)
Node Packaged Modules(简称NPM)的概述,以及NPM的安装配置。同时介绍开发和运营的一些重要Node.js模块,其中包括express框架、require模块、socket.io模块、forever模块,以及jade模板。
下面我会简单的讲解Node.js的重要模块的安装配置。以及如何自我开发和发布一个Node.js模块到NPM是重点。
NPM配置
Windows系统下使用msi安装Node.js时会默认安装NPM模块。
只需 输入npm -v 能查出你的npm版本即可。
最常用的npm命令是 npm install xx安装模块和npm uninstall xx卸载模块
无论是install还是uninstall,你都可以在node_modules文件夹中发现变化,添加或减少文件夹
Node包管理器
npm是一个Node包管理和分发工具。它已经成为了非官方的发布Node模块(包)的标准。从概念上理解,它和apt-get(Debian)、rpm/yum、MacPorts、CPAN或者PEAR(PHP)这些工具类似。存在的目的就是在因特网上通过简单的命令行界面发布和管理Node包。有了npm,就可以很快的找到特定服务要使用的包,进行下载、安装以及管理已经安装的包。
npm包的格式
一个npm包是包含了package.json的文件夹。package.json描述了这个文件夹的结构,除了npm所识别的package.json标签比Node能识别的多得多。CommonJS Packages/1.0规范是npm的package.json的起点。
可以通过
$ npm help json 来访问package.json文件是这样的:
{
name:"packageName",
author:"minchao",
description:"test",
version:"1.0",
main:"mainModuleName",
modules:{
"mod1":"lib/mod1",
"mod2":"lib/mod2"
}
}
依赖关系文件packag.json,执行命令同步库文件
npm install 一次输入配置的值按回车