Node.js 教程 04 - 模块系统

前言:

  Node.js的模块系统类似于C/C++的文件引用,可以声明对象,也可以定义类 创建对象。

  大家这么理解,就简单了。


定义:

  为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

  模块是Node.js应用程序的基本组成部分,文件和模块是一一对应的。

  换言之,一个Node.js文件就是一个模块,这个文件可能是Javascript代码、JSON或者编译过的C/C++扩展。


实例一:

  这个实例演示的是,在hello.js中创建一个方法,然后在主程序main.js中调用这个方法。

  在Node.js中,创建一个模块非常简单,大家跟着做一下就OK了。步骤如下:

  步骤1:在E:\NodejsDemo文件夹中,创建一个“hello.js”文件,代码如下:

1 exports.welcome = function(){
2     console.log("Welcome to My Blog!");
3 }

  上述代码中,我们使用exports对象,把welcome作为当前hello.js模块的访问接口。

  这样,在其他的模块(js文件)中,使用require命令,引入当前js文件,即可直接访问welcome了。

  步骤2:同目录下,我们创建一个“main.js”文件,作为要执行的主程序,引入hello.js文件,执行welcome方法,代码如下:

1 var Hello = require(‘./hello‘); // 引入hello.js模块(文件)
2 Hello.welcome();  // 访问hello.js文件中的welcome函数

  上述代码中,我们使用require函数,引入hello.js文件。

  然后,我们把引入的hello.js模块,存入了一个本地变量“Hello”中。

  最后,我们使用本地变量“Hello”调用welcome函数,也就是访问了hello.js模块中的welcome对外接口函数。

  注意:这里引入hello.js模块的时候,我们并没有加后缀,“./”表示当前目录,Node.js默认后缀为“.js”。

  步骤3:启动DOS,进入目录,执行“node main.js”运行主程序:

  OK,大家发现,我们调用welcome方法之后,执行的是hello.js文件中创建的welcome函数。

  这个例子,大家想我开头所说的理解,其实非常简单。重点是exports和require。

  • hello.js中的声明 -  exports.welcome = function(){...}
  • main.js中的第一句话 - 引入hello.js:var Hello = require(‘./hello‘);

  require命令我们在之前“Node.js 教程 02 - 经典的Hello World”已经接触过了。

  Node.js 提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。

  有没有感觉,这个例子很像Java/.NET中的定义类、声明对象、调用方法?


实例二:

  Js大牛们知道,在Javascript中,我们可以“定义类、实例化对象”。

  那我们如果想把一个对象封装到模块中,应该怎么办呢?

  按照上面的实例一,我们照葫芦画瓢:定义一个person类,引入实例化,并赋值,最后调用函数。

  步骤1:创建一个“person.js”文件,作为要引入的模块文件,代码如下:

 1 function Person(){
 2     var name;
 3     this.setName = function(_name){
 4         name = _name;
 5     }
 6
 7     var url;
 8     this.setUrl = function(_url){
 9         url = _url;
10     }
11
12     this.sayHello = function(){
13         console.log("Welcome to my blog!\n" + url);
14         console.log("My name is " + name +". Nice to meet you!");
15     }
16 }
17
18 module.exports = Person;

  上述代码中,我们创建了一个Person对象,包含两个需赋值参数及一个输出函数。

  重点是最后一句: module.exports = Person;

  模块接口的唯一变化是使用  module.exports = Person  代替了 exports.world = function(){} 。

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

  步骤2:创建主程序“main.js”,引入person.js模块,实例初始化并调用,代码如下:

1 var Person = require(‘./person‘);
2
3 var person = new Person();
4 person.setName("GuYing");
5 person.setUrl("http://www.cnblogs.com/LonelyShadow");
6 person.sayHello();

  上述代码中,我们第1行先引入“person.js”模块文件,并存入本地的Person对象中。

  第3行,实例化这个Person对象,将实例存入本地的person对象中。

  第4-5行,为这个person对象赋值name和url参数。

  第6行,访问person对象的sayHello()函数,输出结果。

  Ps:到此为止,是不是觉得这个东西跟类和对象太相似了?O(∩_∩)O哈哈~



服务器的模块放在那里?

  也许你已经注意到,我们之前在“Node.js 教程 03 - 创建HTTP服务器”中已经在代码中使用了模块了。像这样:

1 var http = require("http");
2 ...
3 http.createServer(function(){});

  Node.js中自带了一个叫做"http"的模块,我们在我们的代码中请求它并把返回值赋给一个本地变量。

  这把我们的本地变量变成了一个拥有所有 http 模块所提供的公共方法的对象。

  Node.js 的 require方法中的文件查找策略如下:

  由于Node.js中存在4类模块(原生模块和3种文件模块),尽管require方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同。如下图所示:

  从文件模块缓存中加载

    尽管原生模块与文件模块的优先级不同,但是都不会优先于从文件模块的缓存中加载已经存在的模块。

  从原生模块加载

    原生模块的优先级仅次于文件模块缓存的优先级。

    require方法在解析文件名之后,优先检查模块是否在原生模块列表中。

    以http模块为例,尽管在目录 下存在一个http/http.js/http.node/http.json文件,require("http")都不会从这些文件中加载,而是从原生 模块中加载。

    原生模块也有一个缓存区,同样也是优先从缓存区加载。如果缓存区没有被加载过,则调用原生模块的加载方式进行加载和执行。

  从文件加载

    当文件模块缓存中不存在,而且不是原生模块的时候,Node.js会解析require方法传入的参数,并从文件系统中加载实际的文件。

    加载过程中的包装和编译细节在前一节中已经介绍过,这里我们将详细描述查找文件模块的过程,其中,也有一些细节值得知晓。

    require方法接受以下几种参数的传递:

  • http、fs、path等,原生模块。
  • ./mod或../mod,相对路径的文件模块。
  • /pathtomodule/mod,绝对路径的文件模块。
  • mod,非原生模块的文件模块。
时间: 2024-10-16 03:59:08

Node.js 教程 04 - 模块系统的相关文章

Node.js 教程 01 - 简介、安装及配置

目录: Node.js 教程 01 - 简介.安装及配置 Node.js 教程 02 - 经典的Hello World Node.js 教程 03 - 创建HTTP服务器 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好. 谁适合阅读本教程?

Node.js 教程

Node.js 教程nodejs简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好.谁适合阅读本教程?如果你是一个前端程序员,你不懂得像PHP.Python或Ruby等动态编程语言,然后你想创建自己的服务,那么Node.js是一个非常好的选择.No

[转载]Node入门 » 一本全面的Node.js教程

http://www.nodebeginner.org/index-zh-cn.html 作者: Manuel Kiessling 翻译: goddyzhao & GrayZhang & MondayChen 关于 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识.本书绝不是一本“Hello World”的教程. 状态 你正在阅读的已经是本书的最终版.因此,只有当进行错误更正以及针对新版本Node.js的改动进行对应的修正时,才会进行

Node.js的Formidable模块的使用

今天总结了下Node.js的Formidable模块的使用,下面做一些简要的说明. 1)     创建Formidable.IncomingForm对象 var form = new formidable.IncomingForm() 2)     form.encoding = 'utf-8' 设置表单域的编码 3)     form.uploadDir = "/my/dir"; 设置上传文件存放的文件夹,默认为系统的临时文件夹,可以使用fs.rename()来改变上传文件的存放位置

10+ 最佳的 Node.js 教程和实例

如果你正在找Node.js的学习资料及指南,那么请继续(阅读),我们的教程将会覆盖即时聊天应用.API服务编写.投票问卷应用.人物投票APP.社交授权. Node.js on Raspberry Pi等等. 以下是Node.js入门的简单介绍,如果你对Node.js略有了解可以直接跳过此部分. 那什么是Node.js呢? Node.js是迄今运用最多的服务端JavaScript运行时环境,使用JavaScript开发跨平台的实时WEB应用. Node.js基于Google的V8 JavaScri

Node.js入门:模块机制

CommonJS规范  早在Netscape诞生不久后,JavaScript就一直在探索本地编程的路,Rhino是其代表产物.无奈那时服务端JavaScript走的路均是参考众多服务器端语言来实现的,在这样的背景之下,一没有特色,二没有实用价值.但是随着JavaScript在前端的应用越来越广泛,以及服务端JavaScript的推动,JavaScript现有的规范十分薄弱,不利于JavaScript大规模的应用.那些以JavaScript为宿主语言的环境中,只有本身的基础原生对象和类型,更多的对

Node.js教程系列~目录

Node.js这个东西在近几年火起来了,而且会一直火下去,无论在infoq还是在cnblogs,csdn上,都可以到处看到它的样子,它主推的应该就是异步式I/O 吧,是的,设计的很完美,很吸引人,虽然它与正常思维是不同的,但是当你真正认识它后,也会足够的让你爱上它!Node.js确实改变了我的编程观念,改变了我对计算机系统的认识! 名人总结的话,我们应该回味个几百次 同步式I/O: 线程在执行中如果遇到磁盘读写或网络通信(统称为I/O操作),通常要耗费较长的时间,这时操作系统会剥夺这个线程的CP

[整理]Node入门 » 一本全面的Node.js教程 - Demo实践所遇到的问题

花了一个上午看完[转载]Node入门 » 一本全面的Node.js教程 根据里面的Demo自己手动实现过程中还是需到写问题,特整理在此. <1>.由于node.msi安装包已经自动添加了系统环境变量,所以可以在任意地方路径下运行node xxx.js.<2>.确定2个环境变量是否已添加(1)一个是PATH上增加node.exe的目录C:\Program Files\nodejs,(已自动添加)(2)一个是增加环境变量NODE_PATH,值为C:\Program Files\node

Node.js 初识 fs 模块

fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 Unix 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了 同步 和 异步 两个版本,比如读取文件内容的函数有 异步的 fs.readFile() 和 同步的 fs.readFileSync(). Node.js 导入文件系统模块的语法如下: var fs = require('fs'); 1.异步和同步读取文件 fs.readFile(file[, options], callback(err,