Node進階學習
能夠完整寫出一個簡單的Node Web應用,就算是已經入門了。那麼接下來的任務呢?是否要接下來學習框架進行開發了呢,我卻不這麼認為,在前面有好多的內容不是特別的明瞭,希望這個階段可以強化前面的知識。
該階段主要任務:
- 強化前面的一些內容(如:模組載入機制)
- 進階學習一些模組(如:程式管理模組)
(1)-模組載入
在Node基礎學習中,已經瞭解到了模組的一些知識點。如,匯出和匯入,模組載入的路徑以及模組的初始化,但是還是有些疑問。
1、模組到底如何呼叫程式載入到程式裡的?
2、為什麼只有定義在exports
物件上的方法才能被外部呼叫?
3、為什麼能夠直接使用require
方法,而沒有引入某個模組?
之前瞭解,Node的模組分為兩類,一類為原生(核心)模組,一類為檔案模組。但是他們的載入有什麼不一樣的嗎?下面簡要了解一下。
原生模組在Node原始碼編譯的時候編譯進了二進位制執行檔案,載入的速度最快。另一類檔案模組是動態載入的,載入速度比原生模組慢。但是Node對原生模組和檔案模組都進行了快取,於是在第二次require
時,是不會有重複開銷的(這個在之前學習過)。其中原生模組都被定義在lib
這個目錄下面,檔案模組則不定性。
由於通過命令列載入啟動的檔案幾乎都為檔案模組。這裡介紹一下Node如何載入檔案模組的。載入檔案模組的工作,主要由原生模組module
來實現和完成,該原生模組在啟動時已經被載入,程式直接呼叫runMain
靜態方法。
// bootstrap main module.
Module.runMain = function () {
// Load the main module--the command line argument.
Module._load(process.argv[1], null, true);
};
_load靜態方法在分析檔名之後執行var module = new Module(id, parent);
,並根據檔案路徑快取當前模組物件,該模組例項物件則根據檔名載入。module.load(filename);
實際上在檔案模組中,又分為3類模組,這三類檔案模組以字尾來區分,Node會根據字尾名來決定載入方法。
.js
通過fs模組同步讀取js檔案並編譯執行。.node
通過C/C++進行編寫的Addon。通過dlopen方法進行載入。.json
讀取檔案,呼叫JSON.parse解析載入。
這裡重點了解.js
字尾的檔案模組的編譯過程。Node在編譯js檔案的過程中實際完 成的步驟有對js檔案內容進行頭尾包裝。以官方介紹模組的文件中app.js為例,包裝之後的app.js將會變成如下格式。
(function (exports, require, module, __filename, __dirname) {
var circle = require('./circle.js');
console.log('The area of a circle of radius 4 is ' + circle.area(4);
});
這段程式碼會通過vm原生模組的runInThisContext方法執行(類似eval,只是具有明確上下文,不汙染全域性),返回為一個具體的function物件。最後傳入 module物件的exports
,require方法
,module
,檔名
,目錄名
作為實參並執行。
這就是為什麼require
並沒有定義在app.js檔案中,但是這個方法卻存在的原因。
從Node的API文件中可以看到還有__filename
、__dirname
、module
、 exports
幾個沒有定義但是卻存在的變數。其中__filename
和__dirname
在查詢檔案路徑的過程中分析得到後傳入的。module變數是這個模組物件自身,exports
是在module的建構函式中初始化的一個空物件({},而不是 null)。
在這個主檔案中,可以通過require方法去引入其餘的模組。而其實這個require方法實際呼叫的就是load方法。
load方法在載入、編譯、快取了module後,返回module的exports
物件。這就是circle.js檔案中只有定義在exports
物件上的方法才能被外部呼叫的原因。以上所描述的模組載入機制均定義在lib/module.js中。
本文主要內容參考取自此處。
相關文章
- Java進階容器學習Java
- Java學習路線·進階Java
- Python學習路線·進階Python
- Go 進階學習筆記Go筆記
- linux進階命令學習一Linux
- Swift進階學習筆記Swift筆記
- 讀懂深度學習,走進“深度學習+”階段深度學習
- U-Net學習與進階
- python進階學習筆記(一)Python筆記
- Rust build.rs進階學習RustUI
- 學習NEO開發如何進階
- 會計進階學習路線圖
- 線段樹進階 學習筆記筆記
- HTTP協議學習---(三)進階篇HTTP協議
- Java進階學習之事件響應Java事件
- Koa2進階學習筆記筆記
- Java列舉類學習到進階Java
- node Buffer 學習
- 圖論進階學習筆記(四)(2024.10.4)圖論筆記
- (一)《SQL進階教程》學習記錄--CASESQL
- Go 語言進階學習路線圖Go
- 機器學習30天進階實戰機器學習
- Python進階學習之程式碼閱讀Python
- spark學習筆記--進階程式設計Spark筆記程式設計
- Java進階學習之Java架構師的學習路線Java架構
- 《大前端進階 Node.js》系列 雙十一秒殺系統(進階必看)前端Node.js
- 極客大學java進階訓練營學習分享Java
- node學習歷程
- Python進階學習分享之迴圈設計Python
- (二)《SQL進階教程》學習記錄--GROUP BY、PARTITION BYSQL
- Go 學習、Go 進階、Go 實用工具類Go
- rodert單排學習redis進階【白銀一】Redis
- 笨辦法學C 練習28:Makefile 進階
- Java進階學習之集合與泛型(1)Java泛型
- Redux 進階 – react 全家桶學習筆記(二)ReduxReact筆記
- Redux 進階 - react 全家桶學習筆記(二)ReduxReact筆記
- 線段樹進階應用學習筆記(二)+普通資料結構進階應用學習筆記(一)(2024.10.1)筆記資料結構
- 大模型學習進階 5-大模型測評大模型
- nginx進階-3(32-34天)學習筆記Nginx筆記