如何實現 node module 模組匯入

2021-09-24 07:33:20 字數 2414 閱讀 6720

今天,我們來聊聊 node 的模組,主要內容分別有:

1.什麼是模組化?模組化都有哪些規範?

2.node 模組匯入具體是如何實現的?

var getsingle = function (fn) 

};複製**

形參 fn 是我們的建構函式,我們只要傳入任何自己需要的建構函式,就能生成乙個新的惰性單例。

requirejs主要解決兩個問題node 匯入模組的方式

const fs = require("fs");

複製**

我們通過這個入口,一步步的看下 node 是如何實現模組的匯入的,斷點除錯,走起!

首先我們看到,在 node 核心檔案 module.js 中,定義了乙個 module 類,並且在類的原型上定義了乙個 require 方法,而這個方法就是在給定的檔案路徑下載入模組,並且返回該模組的"exports"物件。

而 require 呼叫了 module 類上的靜態方法 _load,那我們進去看看這個 _load 方法是如何實現的吧:

很明顯,這裡就node module匯入的核心**,那麼這裡都做了些什麼事情呢,我們一一來分析:

步驟小結:

通過上面的分析我們不難發現:

根據上面的邏輯和分析,我們簡單的實現下模組的匯入:

首先,我們要讀取檔案並解析js檔案,所以需要使用node底層一些方法:

const fs = require("fs");

const path = require("path");

const vm = require("vm");

// 定義module類

function module(file) ;//模組必有屬性,模組匯出時屬性掛載在該物件上

}複製**

接下來的第二步,

module類中的靜態方法module._load:

function req(moduleid) 

// 快取中沒有載入過這個模組,則構建乙個模組

let module = new module(p);

// 載入模組

let content = module.load(p);

// 將建立出來的模組放入到快取中,下次呼叫時直接從快取中獲取

module._cachemodule[p] = module;

module.exports = content;

// 最後返回模組的exports物件

return module.exports;

}複製**

第三步:

我們需要解析檔案的具體路徑,讓我們一起看看 module._resolvefilename 方法的實現吧:

// 解析絕對路徑的方法,返回乙個絕對路徑

module._resolvefilename = function (moduleid) catch (error)

} } else

};複製**

第四步:

在拿到檔案的絕對路徑之後呢,我們將檢查模組快取中是否已經載入過這個模組,因此我們在類上定義了乙個模組快取物件:

// 模組快取物件,是以模組的絕對路徑作為key來進行快取

module._cachemodule = {};

複製**

如果快取中沒有要載入的模組物件,則構建乙個模組,並讀取模組的內容,在這裡要注意的是:

如上圖所示,對於json型別的檔案,我們需要將檔案的內容讀取出來並解析成json物件並掛載在module.exports物件身上即可

第五步:
而對於js檔案型別來說,有著獨特的解析方式,所以我們根據檔案的字尾來使用不同的載入方式:

// 根據不同檔案型別載入模組

module.prototype.load = function (filepath)

複製**

而 module._extensions 這個物件中則存放著真正解析檔案的具體方法:

// js模組包裹陣列

// 檔案模組載入策略物件,包括js檔案和json檔案

module._extensions = ,

".json": function (module)

}複製**

最後,我們通過一張gif圖來瀏覽下所有**,並跑下最終的結果:

gmat模考 GMAT備考如何進行模考練習

準備gmat考試的考生,大多會在備考中進行幾次模考練習。模考練習也的確給人回報高和真實度高的印象。老師喜歡模考,因為模考能幫助他們更好的了解學生的學習情況 學生參加模考,是因為模考能讓他們更清晰的認識到自己的優勢和不足。但如何正確使用模考材料,避免低效率浪費寶貴的學習資源和備考時間,讓每次模考都發揮...

sql 求模 實現 貪婪演算法

背景 最近在維護乙個專案,因新功能需求拓展.有乙個字段儲存 乙個星期中的幾天,可能是全部,也有可能只是其中的星期一,星期三,等.因為專案中有乙個列舉值,已作好初始化賦值工作,而且 客戶端開發時直接把組合值合併成乙個早已存入這個欄位到db.我在專案別的地方 動態批量生成月報表時,又需要得到這個具體的頻...

Java實現AES的ECB CBC CFB模式

public class aes key ge 5 key byte raw key.getbytes utf 8 secretkeyspec skeyspec new secretkeyspec raw,aes cipher cipher cipher.getinstance aes encryp...