相關推薦:《nodejs 教程》
大多數人都知道Node.js中require()函數做什麼的,但有多少人知道它的運作原理呢?我們每天使用它來載入庫包和模組,但是它的內部行為原理很神秘。
我們追尋Node模組系統的核心: module.js,這個檔案包含一個令人驚訝的神奇功能,它負責載入編譯和快取每個用過的文件,讓我們揭開它的神秘面紗。
function Module(id, parent) { this.id = id; this.exports = {}; this.parent = parent; // ...
在module.js中可以發現這個Module類型,扮演兩個主要角色:首先,它提供一個所有Node.js模組從其文件被加載時構建一個實例的基礎功能,甚至在文件運行時持久,這就是為什麼我們能夠將一些屬性加入module.exports,並在需要時返回它們。
module的第二件事是處理Node模組的載入機制,標準的require函數其實是基於module.require的抽象,後者只是一個對Module._load的簡單包裝,載入方法處理每個文件的實際載入。看看它的程式碼大概如下:
Module._load = function(request, parent, isMain) { // 1.在Module._cache中检查模块是否被缓存 // 2.如果缓存中为空,创建一个新的模块实例。 // 3. 保存到缓存 // 4. 使用指定的名称调用module.load() // 在读取了文件内容后将调用module.compile() // 5.如果加载和分析文件时有错误 // 从缓存中删除坏的模块 // 6. 返回 module.exports };
Module._load負責載入新的模組並且管理模組緩存,快取每個模組能夠降低檔案的讀取頻率,從而提高效能,共享模組實例允許像單例模組那樣跨應用保存狀態。
如果一個模組在快取中不存在,Module._load將讀取檔案建立一個新的,讀取檔案內容成功後會呼叫module._compile
如果你注意上面第六步,你會看到返回的是module.exports,這就是為什麼當你定義公共介面時,可以使用exports和module.exports,因為它們確實是Model._load和require返回的。
下面看看module._compile:
Module.prototype._compile = function(content, filename) { // 1. 创建调用模块需要的require标准函数 // 2.将其他帮助方法加入require. // 3.包装JS代码到一个函数,这个函数提供我们的require // 模块, 比如变量本地化到模块的作用域 // 4.返回这个函数 };
這裡有魔術發生,首先,一個特殊的標準require函數將被創建,這就是我們熟悉的require()函數,當函數自己包裝了Module.require,它也包含一些很少人知道的幫助屬性和方法,如:
require():載入一個外部模組
(function (exports, require, module, __filename, __dirname) { // YOUR CODE INJECTED HERE! 你的代码在这里 });最後,這個包裝了模組的函數將運行,整個Module._compile方法同步執行,這樣原來對Module._load方法呼叫將會等待這個程式碼運行,然後才會完成,回傳module.exports給用戶。 現在,我們已經知道require('模組')是如何透過模組系統載入你定義的模組的, module.js source code包含更多程式碼原理,如果你有興趣可以發現更多。
程式設計教學! !
以上是Node.js中require()是如何運作的?工作原理介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!