Node.js 模块 包

包是实现了某个功能模块的集合,用于发布和维护。一个Node.js是一个模块。

Node.js的模块分为核心模块和文件模块。核心模块是Node.js标准API中提供的,像fs、http、net等。核心模块拥有最高的加载优先级,如果有模块与其存在命名冲突,Node.js总会加载核心模块;文件模块则是存储为单独文件的模块,可以是javascript代码、JSON或编译好的C/C++代码。

Node.js用exports公开模块的接口,用require从外部获得模块的接口,及模块的exports对象。

脚本模块文件不只是.js文件,所以在创建模块脚本文件时,若是非.js文件,在被其他模块require时,需要加上文件的扩展名。如自定义模块module1.txt,在其他文件中require时,需要require('./module1.txt')。在不显示指定加载模块文件扩展名时,Node.js会分别试图加上.js、.json(JSON格式的文本)和.node(编译好的C/C++代码)扩展名。文件模块也存在加载顺序,如.js>.json>.node,但是比核心模块优先级低。

文件模块有两种加载方式:按路径加载和查找node_modules文件夹。若require参数以"/"开始,Node.js将以绝对路径方式查找模块名称,如require('/home/xxx/yyy'),将会按照优先级以此尝试加载/home/xxx/yyy.js、/home/xxx/yyy.json、和/home/xxx/yyy.node模块。如果require参数以"./"或"../"开始,Node.js将会以相对路径的方式查找模块,即在用require引用模块(同一目录下)时,模块前需加上“./”。如果require参数不以"/"、"./"、"../"开头,而该模块又不是核心模块,则Node.js就会查找node_modules加载模块了。使用npm获取的包通常就是用这种方式加载的。

Node.js通过实际文件名缓存所有加载过的文件模块,所以require加载模块时不会重复加载,无论调用多少次require,获得的模块都是同一个。假设模块有如下代码:

var name;
exports.setName = function(n){
	name = n;
};
exports.sayHello = function(){
	console.log("hello,"+name);
};
外部调用代码如下:

var hello1 = require('./module');
hello1.setName("name1");
var hello2 = require('./module');
hello1.setName("name2");
hello1.sayHello();
执行node,则将会输出:hello,name2。因为hello1和hello2都指向同一个实例,所以setName被覆盖。

exports是一个普通的空对象,即{},专门用来声明对外的接口,收集属性。在模块中exports的同名方法,后面的会覆盖前面的定义。而exports只是引用module.exports的值,在require模块时最终返回的是module.exports,真正执行的也是module.exports。在模块中若没有module.exports的话,exports会把属性赋予module.exports,若模块中包含module.exports,则对exports赋予属性将会失效,外部调用模块也只是返回module.exports中定义的对象。如在module.js中,有如下定义:

function sayHello2() {
	console.log("module.exports sayHello1");
};
exports.sayHello1=function sayHello1() {
	console.log("exports.sayHello1");
};
module.exports = sayHello2;
外部require模块的代码如下:

var module = require('./modulevsexports');
module.sayHello1();
var hello2 = module();
此时,在命令行中执行时,会报出没有sayHello1()这个方法的错误。

还有一点在使用时需要注意,在外部引用模块时,exports返回仅仅是exports对象,可直接使用模块中赋予exports的属性(如上代码中标红的地方);而module.exports返回的却是赋予的对象,需要new(如上代码中标绿的地方),继而使用对象中的方法。

不可以通过对exports直接赋值代替对module.exports赋值。exports实际上只是一个和module.exports指向同一个对象的变量,它本身会在模块执行结束后释放,但module不会,只能通过指定module.exports改变访问接口。

Node.js的包是一个目录,通常是一些模块的集合,每个包下都有一个package.json文件,用于指定包的接口模块。

Node.js在调用某个包时,会先检查包中package.json文件中的main字段,将其作为包的接口模块,如果package.json或main字段不存在,会尝试寻找index.js或index.node作为包的接口。

使用npm安装包时,有两种模式:本地模式和全局模式,默认情况下使用nmp install命令为本地模式,即把包安装到当前目录的node_modules子目录下,在require加载模块时会尝试搜寻node_modules子目录。使用本地模式安装的包可以被直接引用。

而全局模式的命令为:nmp [install/i] -g [package name]。这种模式会将包安装到系统目录,并注册PATH环境变量,直接能在命令行中调用,这也是使用全面模式的原因。另外,使用这种模式安装的包不能在模块代码中直接使用require获得,因为require是从当前目录的node_modules中搜寻,而非系统目录。


模式

Require能否调用

是否注册PATH

本地模式

全局模式

两种模式比较


包的目录下运行npm init命令,将会以问答的形式在此目录下创建一个符合npm规范的package.json文件。

npm publish:发布包;npm unpublish:删除发布

Node.js的调试分为两种:命令行调试(node debug xxxx.js)和远程调试(node --debug[=port] xxxx.js或node --debug-brk[=port] xxxx.js)。

使用node debug --help可以查看调试命令;远程调试的默认端口为5858

使用node-inspector也可以进行node.js的调试工作。需要使用npm进行全局模式的安装。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值