Node.js模块、包的学习笔记

时间:2024-01-19 13:39:14

什么是模块

模块是node应用程序的基本组成部分,文件和模块是一一对应的,就是说,一个node文件就是一个模块,这个文件可能是javascript代码、json或者是编译过的c++扩展等,如:

	var http = require('http');

其中http是node的一个核心模块,内部是c++实现的,外部是javascript封装起来的。我们通过require函数获取这个模块,然后才能使用其中的对象。

  • 创建模块

    在node中,一个文件就是一个模块,所以我们应该关注的问题是如何在其他的文件中获得这个模块。nodeJs提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。

    例子:

      //name.js
    var name; exports.setName = function(thyName){
    name = thyName;
    }; exports.sayHello = function(){
    console.log('Hello' + name);
    };
    //getname.js
    var myName = require('./hellonode');
    myName.setName('yehui');
    myName.sayHello();

运行getname结果为:hello yehui

  • 单次加载

    require不会重复加载模块,无论调用多少次require,获得的模块都是同一个。

      var hello1 = require('./hellonode');
    hello1.setName('byyehui'); var hello2 = require('./hellonode');
    hello2.setName('byyehui 2'); hello1.sayHello();
    //by yehui 2

这是因为hello1 和hello2 都指向同一个函数,后面的结果就覆盖了前面一个。

  • 覆盖exports

      function Hello(){
    var name; this.setName = function(thyname){
    name = thyname;
    }; this.sayHello = function(){
    console.log('hello' + name);
    };
    };
    exports.Hello = Hello;
    //调用
    var Hello = require('./singleObject').Hello;
    hello = new Hello();
    hello.setName('yehui');
    hello.sayHello();

这样的话,我们在其他文件里面就需要通过require('').Hello来获取Hello对象。

但是如果我们把

exports.Hello = Hello;
//换成
module.exports = Hello;

就可以直接用了

var Hello = require('./singleObject');
hello = new Hello();
hello.setName('yehui');
hello.sayHello();

在外部引用模板时,其接口对象就是要输出Hello对象本身,而不是原先的exports。

创建包

包是在模块基础上更深一步的抽象,他将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制,node根据common JS规范实现了包机制,开发了npm来解决包的发布和获取需求。

  • node.js的包是一个目录,其中包含一个JSON格式的包说明文件package.json。严格符合commonJS的包规范应该具备以下特征:
  1. package.json必须在包的顶层目录;
  2. 二进制文件应该在bin目录下;
  3. javascript代码应该在lib目录下;
  4. 文档应该在doc目录下
  5. 单元测试应该在test目录下。

但是node对包没那么严格,只需要package.json在顶层目录,并符合一些规则就行了。但是为了提高兼容性,还是严格一点较好。

  • 作为文件夹的模块

    模块和文件是一一对应的,文件不仅可以是javascript代码、二进制代码,还可以是一个文件夹。最简单的包就是一个作为文件夹的模块。如:我们先建一个nodelianxi的文件夹,在其中创建一个index.js:

      exports.hello = function(){
    console.log('hello .');
    };

然后在文件夹外面建立一个getpackage.js

	var nodelianxi = require('./nodelianxi');
nodelianxi.hello();
//hello .

在这里我们可以把文件夹封装成模块,即所谓的包。包通常是一些模块的集合,在模块的基础上提供了更高曾的抽象,相当于提供了一个固定接口的函数库。

  • package.json

    package.json文件大概:

      {
    "main" : "./lib/inter.js"
    }

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

  • Node.js包管理器

    即npm,是node官方提供的包管理工具,用于node包的发布、传播、依赖控制。npm提供了命令行工具,可以方便的下载、安装、升级、删除包,也可以维护包等。
  1. 获取一个包

    命令格式为:

     	npm [install/i] [package_name]

如果你想安装express,可以这样:

		$ npm install express
//或者
$ npm i express
  1. 本地模式和全局模式

    在使用npm包的时候,用两种模式:本地和全局

    全局语法格式:

     	npm [install/i] -g [package_name]
  2. 创建全局链接

    npm提供了一个npm link命令,他的功能是在本地包和全局包之间创建链接。我们知道使用全局模式安装的包不能直接通过require使用,但是这个命令打破了这个限制。

  3. 包的发布

    运行:

     	npm init

在发布前,你还可以创建一个账号以后好管理你的包,使用npm adduser 根据提示就输入用户名、密码等就可以。完成后,使用npm whoami检测你是否已经获得账号。接下来,在package.json目录下运行nmp publish,就可以发布了,打开浏览器访问:http://search.npmjs.org/就可以看到自己发布的包了。如果你想更新你的包,只需要修改version字段,然后重新使用npm publish 就行了,还可以通过 npm unpublish来取消发布。

调试

  • 单步调试
  1. 命令行调试

    执行:node debug xxxx.js,将启动调试工具。

  2. 远程调试

    在命令行中执行下面两个语句之一可以打开调试服务器:

     	node --debug[=port] script.js
    node --debug-brk[=port] script.js
  • 使用eclipse调试node