当前位置:编程学习 > JS >>

一起读nodejs(三)----模块(Modules)

模块(Modules)

    stability:5 -locked

    node有一个简单的模块加载机制.在node里面文件和模块是 一对一 对应的.例如,foo.js加载在同一文件夹下的circle.js模块.

    foo.js的内容:

[javascript] 
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">var circle = require('./circle.js'); 
console.log( 'The area of a circle of radius 4 is ' 
           + circle.area(4));</SPAN> 

var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));    circle.js的内容:[javascript] view plaincopyprint?
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">var PI = Math.PI; 
 
exports.area = function (r) { 
  return PI * r * r; 
}; 
 
exports.circumference = function (r) { 
  return 2 * PI * r; 
};</SPAN> 

var PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};    circle.js模块以导出了area()方法和circumference()方法.为了导出一个对象,需要加上指定的exports对象.

    属于模块的变量是私有的.在这个例子中变量PI就是私有于circle.js.

    模块机制是在require('module')模块中实现的.

 


      环形加载(Cycles)

 


    当存在环形的require()调用时,当一个模块被返回被执行的时候,可能还没有加载完成,考虑下面这种情景:
    a.js:
[javascript] 
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">console.log('a starting'); 
exports.done = false; 
var b = require('./b.js'); 
console.log('in a, b.done = %j', b.done); 
exports.done = true; 
console.log('a done');</SPAN> 

console.log('a starting');
exports.done = false;
var b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');    b.js:[javascript] view plaincopyprint?
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">console.log('b starting'); 
exports.done = false; 
var a = require('./a.js'); 
console.log('in b, a.done = %j', a.done); 
exports.done = true; 
console.log('b done');</SPAN> 

console.log('b starting');
exports.done = false;
var a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');    main.js:[javascript] view plaincopyprint?
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">console.log('main starting'); 
var a = require('./a.js'); 
var b = require('./b.js'); 
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);</SPAN> 

console.log('main starting');
var a = require('./a.js');
var b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);    当main.js加载a.js的时候,a.js依次需要加载b.js.在这时,b.js试着去加载a.js.为了防止一个无穷的循环(loop),一个未完成的a.js的副本的exports导出对象被返回到b.js模块.然后b.js完成加载,然后他的exports导出对象被提供给a.js模块.


    当main.js加载完这两个模块的时候,他们都已经加载完.这个程序的输出应该这样子:[javascript] view plaincopyprint?
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">$ node main.js 
main starting 
a starting 
b starting 
in b, a.done = false 
b done 
in a, b.done = true 
a done 
in main, a.done=true, b.done=true</SPAN> 

$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true    如果你的程序里面有环形的模块依赖,确保制定相应的计划(意思是,确保在所有依赖的模块都加载完时在调用,避免在模块未加载完时,调用导致程序不可预期的结果).


(循环加载,require()方法有对应的机制,上面例子中b.js返回时,b.js加载的a.js没有加载完,但是当b.js加载完时,a.js就加载完了,这时候b.js里面保存的a.js也会被更新成完成的对象,其实我觉得保存的可能就是类似于a.js的引用.)
      核心模块(Core modules)


    node中有一些模块被编译成二进制. 这些模块在文档的其他地方有更详细的描述.


    核心模块被定义在node的源码中的lib文件夹下.


    如果核心模块的标识符被传入require()方法时,总是被优先加载.例如,require('http')将总是返回内置的http模块,即使当前有一个同名的模块文件夹.


      文件模块加载机制(File modules)


    如果准确的文件名字没有找到,node将会试图依次加载添加了.js,.json,.node等后缀名的文件.
    .js文件被当作javascript文本文件解读,.json文件被转换成json文本文件. .node文件被当做已经编译好的插件模块,使用dloopen加载.(在dlopen()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。)


    当一个模块的前缀是"/"时,表示一个模块文件的绝对路径.例如:require('/home/marco/foo.js')将会使用'/home/marco/foo.js'作为路径加载.


    当一个模块的前缀是"./"时,表示一个模块文件的相对路径调用require().例如:为了让foo.js中的require('./circle.js')能被找到,circle.js必须和foo.js在同一目录下.


    如果没有"./"或者"/"当文件前缀,这个模块不是一个核心模块,就是一个需要从node_modules文件夹中加载的模块.


    如果给定的加载路径不存在,requier()方法将会抛出一个Error错误对象,并且Error的code属性被设置成:'MODULE_NOT_FOUND'.   
    
      从node_modules文件夹加载模块(loading from node_mudoles folders)


    如果传入到require()方法中的模块标识符不是本地模块,并且也不是"/","../",或者"./"开头,node则会在当前模块的父目录路径上追加/node_modules,以这个路径试图加载模块.


    如果这里也没有找到,node会继续移动到更上一层的父目录,等等...直到到达根目录.


    例如,文件'/home/ry/project/foo.js'中调用require('bar.js'),node会查找以下列出的路径,依次是:
/home/ry/projects/node_modules/bar.js
/home/ry/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
    这将允许程序本地化他们的依赖,以便不产生冲突.


      文件夹就是模块(Floder as modules)


    组织程序和类库放进自己包含的目录下是很方便的,然后提供一个单独的入口指定这个类库,有三种方法把一个文件夹作为一个参数传进require()方法.


    第一种方法是在根目录创建一个package.json文件,指定一个主模块.一个paceage.json的例子看起来像这样子:

[javascript] 
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: FangSong_GB2312">{ "name" : "some-library", 
  "main" : "./l

补充:web前端 , JavaScript ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,