首頁  >  文章  >  web前端  >  跟我學Nodejs--- Node.js模組

跟我學Nodejs--- Node.js模組

高洛峰
高洛峰原創
2016-12-26 09:25:131416瀏覽

簡介及資料

    透過Node.js的官方API可以看到Node.js本身提供了很多核心模組http://nodejs.org/api/ ,這些核心模組被編譯成二進位文件,可以require('模組名')去取得;核心模組具有最高的載入優先權(有模組與核心模組同名時會體現)

    (本次主要說自訂模組)

    Node.js也有一個類別模組為檔案模組,可以是JavaScript程式碼檔案(.js作為檔案後綴)、也可以是JSON格式文字檔案(.json作為檔案字尾)、還可以是編輯過的C/C++檔案(.node作為檔案字尾);

    檔案模組存取方式透過require('/文件名.後綴')    require('./文件名.後綴')    requrie('../文件名.後綴') 去訪問,文件後綴可以省略;以"/"開頭是以"/"開頭是以絕對路徑去加載,以"./"開頭和以"../"開頭表示以相對路徑加載,而以"./"開頭表示同級目錄下文件,

    前面提到文件後綴可以省略,Nodejs嘗試載入的優先權js檔案> json檔> node檔

建立一個自訂模組

   以一個計數器為例

 跟我學Nodejs--- Node.js模組

var outputVal  = 0;     //输出值
var increment = 1;    //增量
/* 设置输出值 */
function seOutputVal (val) {
    outputVal = val;
}
/* 设置增量 */
function setIncrement(incrementVal){
    increment = incrementVal;
}
/* 输出 */
function printNextCount()
{    
    outputVal += increment;
    console.log(outputVal) ;
}
function printOutputVal() {
    console.log(outputVal);
}
exports.seOutputVal = seOutputVal;
exports.setIncrement = setIncrement;
module.exports.printNextCount = printNextCount;
自定义模块 示例源码

範例中重點在於exports和

/*
    一个Node.js文件就是一个模块,这个文件可能是Javascript代码、JSON或者编译过的C/C++扩展。
    重要的两个对象:
    require是从外部获取模块
    exports是把模块接口公开    
*/
var counter = require('./1_modules_custom_counter');
console.log('第一次调用模块[1_modules_custom_counter]');
counter.seOutputVal(10);               //设置从10开始计数
counter.setIncrement (10);             //设置增量为10
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
/*
    require多次调用同一模块不会重复加载
*/
var counter = require('./1_modules_custom_counter');
console.log('第二次调用模块[1_modules_custom_counter]');
counter.printNextCount();
自定义模式调用 源码

範例中重點在於exports和Hmodule.exports和module.下面呼叫看看效果吧 跟我學Nodejs--- Node.js模組

呼叫自訂模組

var counter  = 0;     
exports.printNextCount = function (){    
    counter += 2;
    console.log(counter);
}
var isEq = (exports === module.exports);
console.log(isEq);
2_modules_diff_exports.js 文件源码

    運作可以發現透過exports和module.exports對外公開的方法都可以存取!

    範例中可以看到,我兩次透過require('./1_modules_custom_counter')取得模組,但是第二次引用後呼叫printNextCount()方法確從60開始~~~

  多次呼叫相同模組不會重複加載,Node.js會根據檔案名稱快取所有載入過的檔案模組,所以不會重新載入了

    注意:透過檔案名稱快取是指實際檔案名,不會因為傳入的路徑形式不同而認會是不同的檔案    

    在我建立的1_modules_custom_counter檔案中有一個printOutputVal()方法,它並沒有透過exports或module.exports提供對外公開存取方法,🠎直接存取運行會出現什麼樣的情況呢?

    答案是:TypeError: Object # has no method 'printOutputVal'

exports和module.exports 區別

經過上面的例子,透過exports和module.exports 區別跟我學Nodejs--- Node.js模組

經過上面的例子,透過exports和module.exports對外公開的方法都可以存取!那既然兩種都能達到效果,但總得有點差別的吧~~~用個例子看看吧!

跟我學Nodejs--- Node.js模組

var Counter = require('./2_modules_diff_exports');
Counter.printNextCount();

下面再新建個2_modules_diff_exports_load.js檔案呼叫

//修改后的2_modules_diff_exports.js源码如下
var counter  = 0;     
module.exports = function(){    
    counter += 10;
    this.printNextCount = function()
    {
        console.log(counter);    
    }
}
var isEq = (exports === module.exports);
console.log(isEq);

    呼叫後,執行結果如同在圖上圖了的值  ( var isEq = (exports = == module.exports); ),回傳的true

    PS:注意是三個等號,如果不清楚自已查查資料吧!

不用急著下結論,把這兩個JS檔案分別改成module.exports對應的程式碼跟我學Nodejs--- Node.js模組

//修改后的2_modules_diff_exports_load.js文件源码如下
var Counter = require('./2_modules_diff_exports');
var counterObj = new Counter();
counterObj.printNextCount();
rrreee

    呼叫後,執行結果如上圖

  ( var isEq = (exports === module.exports); ),傳回的false,這與先前得到的結果不一致!

    PS:不要用Counter.printNextCount();去訪問,你只會得到一個錯誤的提示

    API提供了解釋

   a reference to module.exports making it suitable for augmentation only. If you are exporting a single item such as a constructor you will want to use module.exports directly instead
  nodejs只會導出module.exports的指向,如果exports指向變了,那就只是exports不在指向module.exports,於是不會再被導出

    module.exports才是真正的接口,exports只不過是它的一個輔助工具。 最終回傳給呼叫的是module.exports而不是exports。
    所有的exports所收集到的屬性和方法,都賦值給了Module.exports。當然,這有個前提,就是module.exports本身不具備任何屬性和方法。
    如果,module.exports已經具備一些屬性和方法,那麼exports收集來的資訊將被忽略。

exports和module.exports 覆蓋

上面也也基本上明白了exports和module.exports的關係和區別,但如果同時針對printNextCount()方法存在exports和module.exports,結果如何?

跟我學Nodejs--- Node.js模組

調用結果

跟我學Nodejs--- Node.js模組

    從結果可以看出,並沒有報錯,表示可以這麼定義,但最終module.exports覆蓋了exports

🠎有一些問題存在,所以

    1.最好別分別定義module.exports和exports

    2.NodeJs開發者建議導出對像用module.exports,導出多個方法和變量用exports

其它...

   API中還提供了其它的方法,就不細講了,在上面例子的基礎上自已動手一輸出就知道了

  module.id

  返回string類型的模組,一般為完全解析後的文件,一般為完全解析名

  module.filename

  回傳一個string類型的完全解析後檔名

  module.loaded

 『引用本模組的模組

  module .children

  傳回該模組所引用的所有模組物件的陣列

更多Node.js模組相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn