初學Node(三)模塊系統

模塊系統node

  Node根據CommonJS規範實現了一套本身的模塊機制,可使用require()導入一個模塊,使用module.exports導出一個模塊。json

require使用緩存

  在Node中咱們可使用require()導入一個模塊,此時咱們就會得到一個被導入模塊的對象,咱們就能夠利用這個對象來完成一些操做,例如:函數

var fs = require("fs");
fs.readFile("content.txt",function(err,data){
    if(err){
        return console.log("讀取文件錯誤!");
    }
    console.log(data.toString());
})

  咱們經過require()將fs模塊導入,此時咱們就經過得到的fs模塊的對象來實現對文件的操做。ui

  在Node中模塊分爲核心模塊和文件模塊,核心模塊即被被編譯成二進制代碼的模塊,是Node自帶的一些模塊。文件模塊即咱們本身編寫的模塊,不管哪一種模塊均可以經過require()函數來引入。spa

  require()的參數有四種不一樣的形式,分別爲:命令行

  核心模塊:require("fs")code

  相對文件路徑:require("../xxx")對象

  絕對文件路徑:require("/xxx")blog

  非核心模塊的文件模塊:require("xxx")

  加載模塊的過程以下圖所示:

require按照路徑加載模塊

  例如咱們經過require("X")加載一個模塊,首先會去文件模塊緩存區中查找有沒有該模塊的緩存,若是緩存區中存在該模塊,則直接返回。若是不存在該模塊就會判斷X的類型,若是是加載一個原生模塊,就會按原生模塊緩存區,原生模塊這樣的順序去查找該模塊,若是在原生模塊緩存區中找到就會直接返回模塊對象,若是在原生模塊中找到就會在原生模塊緩存區中加入該模塊以方便下一次的使用,而後返回模塊。

  若是X是一個路徑類型首先把X當作文件按照X、X.js、X.json、X.node來查找該模塊,找到以後加入到文件模塊緩存區中而後返回該模塊。若是沒有找到,則把X當作是一個目錄,在X裏面按照index.js、index.json、index.node的順序依次查找,若是目錄中存在package.json則優先加載main屬性對應的文件,在找到以後將模塊加入到文件模塊緩存區中而後返回該模塊。

  咱們在桌面上新建兩個文件夾,分別爲first和second,在first中新建first.js文件,first.js內容以下:

var name = "zt"
module.exports.show = function(){
    console.log(name);
}

  在sencond中新建main.js文件,main.js文件內容以下:

var first = require("../first");
first.show();

  在命令行中進入sencond文件node main.js執行,會報Error,不能找到first。咱們按照上面的過程來排除錯誤,第一次加載文件緩存區中沒有,也不是原生模塊,此時就會按照路徑的方式來加載first模塊,首先把它當成一個文件,即在桌面中按照first、first.js、first.json、first.node的順序來查找,都不存在,而後把first看錯一個目錄,而後在first文件內去查找,首先查看有沒有package.json文件,存在就會加載main屬性對應的文件,不存在就按照index.js、index.json、index.node的順序來查找,仍然找不到最終就會報錯。

  按照上面的流程咱們能夠經過三種方式來修改:

  1:在桌面上新建一個first.js,這時當按照文件來查找時就能夠找到first.js,而後載入模塊。

  2:在first文件夾中將first.js更名爲index.js,這樣在按照文件不能查找到,按照目錄查找時就能夠找到index.js,而後載入模塊。

  3:在first文件夾中初始化一個package.json文件,main屬性值爲first.js,這樣在按照目錄查找時在目錄中存在package.json文件就會加載main屬性對應的文件。

require按照模塊去查找

  例如在second的main.js中經過require("first")這種方式來加載first模塊,使用這種方式來加載模塊優先在當前文件夾(second文件夾)中查找node_modules文件夾,在node_modules文件夾中去查找first模塊(在node_modules文件夾中也是按照路徑的那個套路來查找),而後在sencond的父級下的node_modules文件下去查找first模塊,按照這種方式一直查找下去,咱們能夠經過module.paths來查看查找的路徑:

console.log(module.paths);

  在sencond文件夾中新建node_modules文件夾,而後把first文件夾放入到node_modules文件夾中,這樣main.js中的require("first")就能夠找到first模塊了。

module.exports導出模塊

  能夠在一個文件中使用module.exports導出一個模塊,這樣在require()時就可使用導出的屬性或者方法。以上面的first.js爲例咱們在first.js中使用module.exports導出了show方法,這樣咱們在使用require()以後獲取到的對象就可使用show方法了。

  Node對module.exports的使用作了一些簡化處理讓咱們在導出時可使用exports:

module.exports = exports = {};

  module.exports和exports共用一個引用,這樣就能夠經過exports來收集屬性:

var name = "zt"
exports.show = function(){
    console.log(name);
}

  經過module.exports = exports = {},這樣在使用require()函數時得到的module.exports對象也就有了exports收集的屬性。

  若是module.exports從新賦值module.exports和exports的引用關係也就斷開了,而require()函數返回的是module.exports對象,也就不能獲得exports收集的屬性了,因此在使用時不要混用。

相關文章
相關標籤/搜索