当前位置:嗨网首页>书籍在线阅读

09-准备发布一个模块

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

[toc]

3.3.3 准备发布一个模块

如果你要发布一个模块,你可以在自己的网站上进行推广,但其实这样做无法让更多的用户看到。将模块发布到npm模块库才是正确的发布方式。

前面我提到过package.json文件。大家可以在网上找到npm的JSON文档。它是基于CommonJS模块系统制订的。

推荐将以下字段添加到package.json文件中。

  • name,模块名称——必需。
  • description,模块描述。
  • version,符合语义化版本定义规范的当前版本——必需。
  • keywords,搜索关键字列表。
  • maintainers,模块维护者列表(包括名字、Email和网站)。
  • contributors,模块贡献者列表(包括名字、Email和网站)。
  • bugs,用于提交bug的URL。
  • licenses,协议列表。
  • repository,模块的代码库。
  • dependencies,依赖模块以及它们的版本号。

所有的字段都应该赋值,但只有name和version这两个字段是必需的。好在npm使得创建这个文件的过程简化了许多。如果你在命令行中运行这条命令:

npm init

这个工具就会根据所有的必需和推荐的字段,向你询问应该填入的值。完成之后,程序就会自动生成一个package.json文件。

在第2章的例2-7中,我创建了一个名为InputChecker的对象,用来检查传入命令的数据并进行处理。这个例子还说明了如何集成EventEmitter。现在让我们来修改一下这个简单的对象,让它可以被其他程序和模块使用。

首先,我们要在node_modules目录中创建一个子目录,将其命名为inputcheck,然后将InputChecker的代码放入目录中,并将代码文件重命名为index.js。下一步,我们需要修改代码,将创建新对象的那部分代码抽离出来。这一步是为了方便以后添加测试文件。我们要做的最后一个修改是添加exports对象,修改之后的代码如例3-2所示。

例3-2 将例2-7中的程序修改为模块对象

var util = require('util');
var eventEmitter = require('events').EventEmitter;
var fs = require('fs');
exports.InputChecker = InputChecker;
function InputChecker(name, file) {
   this.name = name;
   this.writeStream = fs.createWriteStream('./' + file + '.txt',
      {'flags' : 'a',
       'encoding' : 'utf8',
       'mode' : 0666});
}; 
util.inherits(InputChecker,eventEmitter);
InputChecker.prototype.check = function (input) {
  var command = input.toString().trim().substr(0,3);
  if (command == 'wr:') {
     this.emit('write',input.substr(3,input.length));
  } else if (command == 'en:') {
     this.emit('end');
  } else {
     this.emit('echo',input);
  }
};

我们不能直接导出对象函数,因为util.inherits要求在文件中必须有一个名为InputChecker的对象。随后我们修改了文件中InputChecker对象的原型。我们也可以直接在需要的地方引用exports.InputChecker,但那太麻烦了,实际上只需要添加一条赋值语句就可以了。

要创建package.json文件,我运行了npm init命令,然后填写了命令所要求的每一条内容。生成的结果如例3-3所示。

例3-3 为inputChecker模块生成的package.json

{
  "name": "inputcheck",
  "version": "1.0.0",
  "description": "Looks for and implements commands from input",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "command",
    "check"
  ],
  "author": "Shelley Powers",
  "license": "ISC"
}

npm init这个命令并没有询问模块的依赖,所以我们需要手动添加。更好的添加依赖的办法是,在安装模块时使用npm install--save命令,这条命令会自动将依赖信息加入文件中。但是InputChecker模块并不依赖任何外部模块,所以这个字段可以为空。

现在我们就测试一下新模块,以确保它可以正常工作了。例3-4是之前Input Checker代码的一部分,用于测试新的对象,现在我们将它抽取出来形成了独立的测试程序。

例3-4 InputChecker测试程序

var inputChecker = require('inputcheck').InputChecker;
// testing new object and event handling
var ic = new inputChecker('Shelley','output');
ic.on('write', function(data) {
   this.writeStream.write(data, 'utf8');
}); 
ic.addListener('echo', function( data) {
   console.log(this.name + ' wrote ' + data);
}); 
ic.on('end', function() {
   process.exit();
}); 
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(input) {
    ic.check(input);
});

现在我们可以将测试程序移动到模块目录下的一个叫test的子目录中,将其作为一个模块使用范例。最佳实践是提供一个test目录,该目录包含几个测试程序,再提供一个doc目录,用来存放文档。但是我们的模块太小,一个README文件就足够了。

既然我们已经有了一个测试程序,那么就需要在package.json中引用它:

"scripts": {
   "test": "node test/test.js"
},

这个测试相当简单,也并没有使用稳定的Node测试环境,但是它展示了如何让测试运行起来。要运行这个测试,请输入以下命令:

npm test

最后,我们可以再创建一个模块的压缩包,你也可以跳过这一步。该压缩包我们会在3.3.4节详细讲解。

**什么是Tarball** 我在之前的内容中也用过Tarball这个术语。没用过UNIX的同学可能对这个名词并不熟悉。Tarball指的是一个或者多个文件被tar命令打包成为一个文件。

一旦我们有了发布所需的所有东西,就可以发布这个模块了。

**除了模块本身之外,还有很多事情要做** 对于简单如inputchek的模块而言,你可以提供最少的内容,但是如果要真正发布一个模块的话,要做的事情还有很多:你需要提供一个代码库、一个用于提交bug的URL、还有这个模块的网页等。还是那句话,快速上手,逐步扩充。