Node.js 教程 04 - 模塊系統

 

前言:

  Node.js的模塊系統相似於C/C++的文件引用,能夠聲明對象,也能夠定義類 建立對象。html

  你們這麼理解,就簡單了。node

 


 

 

定義:

  爲了讓Node.js的文件能夠相互調用,Node.js提供了一個簡單的模塊系統。json

  模塊是Node.js應用程序的基本組成部分,文件和模塊是一一對應的。緩存

  換言之,一個Node.js文件就是一個模塊,這個文件多是Javascript代碼、JSON或者編譯過的C/C++擴展。服務器

 


 

 

實例一:

  這個實例演示的是,在hello.js中建立一個方法,而後在主程序main.js中調用這個方法。函數

  在Node.js中,建立一個模塊很是簡單,你們跟着作一下就OK了。步驟以下:post

 

  步驟1:在E:\NodejsDemo文件夾中,建立一個「hello.js」文件,代碼以下:ui

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

  上述代碼中,咱們使用exports對象,把welcome做爲當前hello.js模塊的訪問接口。this

  這樣,在其餘的模塊(js文件)中,使用require命令,引入當前js文件,便可直接訪問welcome了。url

 

  步驟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,非原生模塊的文件模塊。
相關文章
相關標籤/搜索