today, 我们的话题作文是nodejs,我尝试对它的描述是:似曾相似,但它又不一样的存在着。百花齐放的it世界里,以独特身姿绽放的美丽更容易吸引人。也许只是不了解,也许时间会给出答案,nodejs你值得拥有。

在1篇中聊了一点NodeJs的模块,在本篇会聊一点和模块联系非常紧密的package(NodeJS的包)

1.包

包是在模块的基础上更深一步的抽象,NodeJS的包类似于C/C++的函数库或者.Net的类库。它将某个功能封装起来,用于发布,更新,依赖管理和版本控制.NodeJS根据CommonJS规范实现了包机制,开发了npm来解决包的发布和获取需求.下一篇会聊一下npm。

包就是一个文件夹,文件夹下lib放着js文件被充当为模块,包是包装的一个模块,包对模块进行封装以及解释(类库形式表现出来)

符合CommonJS规范的包具备的东西:

package.json文件。

bin文件夹。存放二进制文件。

lib文件夹,存放模块文件,其实就是javascript文件。

doc文件夹,存放文档。

test文件夹,存放单元测试。

比如有一个myPackage文件夹,文件夹下有index.js模块和defualt.js模块,那么这个文件夹myPackage包就是这两个文件的index,defualt模块的封装.

2.package.json

CommonJS为package.json文件定义了一些必须的字段:(我们并不一定需要全部按照规范)

符合CommonJS规范的package.json包描述文件如下:

name:包的名称,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含空格。(必须)
description:包的简要说明。(可选)
version:版本字符串。(必须)
keywords:关键字数组,通常用于搜索。npm search的时候会用到. (可选)
maintainers:维护者数组,每个元素要包含name、email(可选)、web(可选)字段。
contributors:贡献者数组,格式与maintainers相同。包的作者应该是贡献者数组的第一个元素。
Author, contributors(都是可选字段。author是一个人,contributors是一组人。)
bugs:提交bug的地址,可以是网址或者电子邮件地址。(可选)
licenses:许可证数组,每个元素要包含type(许可证的名称)和url(链接到许可证文本的地址)字段。(可选)
repositories:仓库托管地址数组。每个元素要包含type(许可证的名称)和url(链接到许可证文本的地址)字段。可选字段。用于指示代码存放的位置。
dependencies:包的依赖,一个关联数组,由包名称和版本组成。可选字段,指示当前包所依赖的其他包。

package.json文件的内容是js对象,所以要注意格式(json格式)

EXample:

问题1:如果包里面没有package.json文件的情况,那么require("包名")函数将会尝试加载包名目录下的index.js或者index.node,如果没有找到就报错.

首先创建包myPackage(文件夹),再次确认在myPackage包下是不存在package.json文件的条件下,我们在myPackage包下直接创建index.js(index.node)文件。

在index.js文件编写如下内容:

exports.sayHello=function(){
    console.log("hello YZR");
}

然后在myPackage包的同级目录下创建callMyPackage.txt文件,内容如下:

var package=require("./myPackage");//指定包路径
package.sayHello();

在命令行执行:

E:\NodeJS>node callMyPackage.txt
hello YZR

 

问题2:虽然能顺利找到index.js,但这并不是规范的,我们假设包目录下还是没有package.json文件的同时,包目录下也不存在index.js或者index.node。我们把我们的文件index.js放到包目录下的lib文件夹下。

index.js文件内容不变,需要修改一下callMyPackage.txt中的require()函数。如下:

var package=require("./myPackage/lib");
package.sayHello();

最后再来调试一下:

E:\NodeJS>node callMyPackage.txt
hello YZR (lib)

问题3:当我们的文件不止一个呢,除了index.js,还有default.js文件的话,那么default.js怎样才能找到?而且,默认情况下想让require能找到我们的文件,在问题1和问题2的条件下只能命名为index.js或者index.node,处于这些不理想的原因,我们假设依旧不存在Package.json文件,在包下的lib文件夹下创建多一个default.js文件,文件内容如下:

exports.click=function(){
console.log(" default Click");
}

这样我们若想得到default.js模块,需要修改一下callMyPackage.txt中的require()函数。如下:

var package=require("./myPackage/lib/default");
package.click();

最后再来调试一下:

E:\NodeJS>node callMyPackage.txt
default Click

问题4:上面的讨论看来,指定一个文件要非常注意路径的问题,那如果我们可以想JAVA那样提供一个程序入口那该多好,当我们写的模块提供出去,别人拿到我们的文件,我们还得提供一份说明文档,再者可能还需要以后的维护的工作,比如版本升级更新,卸载。出于这些问题,我们明白package.json文件的重要性。

接下来我们创建一个package.json文件,内容如下:

{

"name":"default",
"main":"./lib/default.js",
"version":"0.0.1"

}

现在,恢复callMyPackage.txt中的require()函数。如下:

var package=require("./myPackage");//指定包路径

package.click();

最后调试结果为:

 

E:\NodeJS>node callMyPackage.txt
default Click

 

由require的查找过程可以知道,Node.js在没有找到目标文件时,会将当前目录当作一个包来尝试加载,所以在package.json文件中最重要的一个字段就是main。而实际上,这一处是Node.js的扩展,标准定义中并不包含此字段,对于require,只需要main属性即可。但是在除此之外包需要接受安装、卸载、依赖管理,版本管理等流程,所以CommonJS为package.json文件定义了一些其他必须的字段。

 

 Next:npm包管理器

posted on 2016-03-09 12:31  巴夫巴夫  阅读(719)  评论(0编辑  收藏  举报