众所周知,Node.js是一个基于<em>Chrome</em> V8引擎的服务器端JavaScript运行环境。它采用了一种事件驱动的、非阻塞式的I/O模式,运行起来既轻量级又高效。诚然,我们可以使用单个js文件,来编写出应用程序所涉及到的全部内
2021-05-26 12:00:56
眾所周知,Node.js是一個基於Chrome V8引擎的伺服器端JavaScript運行環境。它採用了一種事件驅動的、非阻塞式的I/O模式,運行起來既輕量級又高效。誠然,我們可以使用單個js檔案,來編寫出應用程式所涉及到的全部內容,但這樣既不靈活,又不夠模組化。而Node.js的出現,讓模組化程式碼的編寫變得非常簡便。因此,對於Node.js的核心,我們需要理解和掌握的一個重要概念便是:依賴關係的管理。本文將和您一起探討依賴項管理的各種模式,以及Nodejs是如何載入依賴項的。
在深入探討細節之前,讓我們首先弄清楚什麼是模組。簡而言之,模組是一段程式碼。為了共享和重用,我們需要將程式碼進行分組放置。通過模組,我們可以將複雜的應用程式分解到小塊程式碼中。同時,模組也能夠幫助我們理解程式程式碼的意圖,並發現或修復各種錯誤。
自2009年以來,CommonJS便實現了Javascript的模組化規範。它規範了模組的特性和各個模組之間的相互依賴性。由於每個檔案都被當做一個模組(通常,module變數代表了當前模組),而且有自己的作用域,因此每個檔案裡面的變數、函數、以及類,都是私有的,且對於其他模組是不可見的。而模組的exports屬性便是對外的介面。只有通過exports匯出的屬性,才能被其他模組識別和載入。而Node是基於CommonJs規範來實現模組的同步與載入。也就是說,我們可以通過在模組中呼叫require()方法,來接收模組的標識,並根據node的模組引入規則,引入其他模組,進而呼叫對應的屬性和方法。
在此,我假設您已經掌握了Nodejs的上述基礎知識。當然,如果您是一名Node.js的新手,則可以通過檢視Node.js的相關簡介來了解更多背景資訊。
設定應用
讓我們從最簡單的開始。假設我已經為某個項目創建了一個目錄。通過運用npm init命令對其初始化後,我們將創建app.js和appMsg.js,兩個JavaScript檔案。下圖展示了本項目的目錄結構,我們將其作為管理的起點。如果您感興趣的話,可以從文末給出的git儲存庫連結中,下載該項目的最終原始碼。
預設情況下,這兩個.js檔案均為空。讓我們通過如下更改,來更新appMsgs.js檔案。
上面的程式碼段展示了module.exports關鍵字的用法。此語法用於公開給定檔案(此處為appMsgs.js)中的屬性或物件,以便能夠在另一個檔案(如本例中的app.js)中被直接使用到。
在該系統中,每個檔案都可以訪問到名為module.exports的檔案。因此,我們在appMsgs.js檔案中公開了一些項目,以方便觀察app.js是如何使用(require)某些屬性的。
顯然,require關鍵字可以方便我們引用某個檔案。也就是說,當我們執行require時,它將返回一個代表著模組化程式碼段的物件。因此,我們可以將其分配給一個appMsgs變數,然後在console.log的語句中簡單地使用該屬性。當代碼被執行時,我們將看到如下輸出:
該require通過執行JavaScript,構造出一個具有某種功能函數的物件,作為返回。它們既可能是一個類建構函式,又可以是其中包含了許多元素、或一些簡單屬性的物件。針對不同的模式,我們既可以匯出多個物件,又可以只匯出那些複雜的物件。可見,通過require和module.exports,我們可以創建出模組化的應用程式。
值得注意的是,應用程式所需的功能函數只會僅載入程式碼一次。也就是說,無論執行了什麼程式碼,它們都不會被執行第二次。那麼,如果別的程式也要通過require來獲取物件的話,它將只能獲得該物件的快取版本。
下面,讓我們來看看匯出的方式。
如上面程式碼段所示,我對前面的程式碼進行了更改。現在,我不再公佈物件了,而是匯出了一個功能函數(function)。該函數在每次被呼叫時,都需要執行該程式碼。
下面,讓我們來看看如何在app.js檔案中使用它:
更新app.js檔案
除了呼叫某個屬性,我們還可以像執行函數一樣去執行它。因此,這裡的區別主要是,每當我們執行該程式碼時,函數內部的程式碼都會被重新執行(re-executed)。
下面是我們重新運行該程式碼段的輸出:
至此,我們已經看到了module.exports的兩種模式,及其兩者的區別。還有一個常見的模式是,將其用作構造器方法(constructor method)。下面,讓我們再來看一個例子:
下面是更改過的app.js檔案:
從本質上講,這與您在JavaScript中創建偽類(pseudo-class),並且創建它的各種例項(instances)是一致的。
下面是更改後的輸出:
接著,讓我們接著討論此類模式的另一個示例。如下程式碼段所示,我創建了一個名為userRepo.js的新檔案。
下面是更改後的app.js檔案。
下圖是該更改被執行後的結果:
當然,針對單個檔案都去使用require的情況並不常見。接下來,讓我們再討論另一種模式--資料夾的依賴性。
資料夾依賴性
為了弄清Node.js是如何查詢依賴性的,讓我們重溫一下前面例子中的JavaScript程式碼:
var appMsgs = require(「 ./appMsgs」)
Node不但會查詢appMsgs.js檔案,而且會查詢作為目錄的appMsgs,並取出它的值。
我創建了一個名為logger的資料夾,並在其中創建了一個index.js檔案,其內容如下面的程式碼段所示:
下面是require此模組的app.js檔案:
可見,在本例中,我們可以寫出這樣的JavaScript程式碼:
var logger = require(「./logger/index.js」)
上述較長的路徑形式肯定是正確的。但是,我們其實只需寫出如下的JavaScript程式碼即可:
var logger = require(「./logger」)
由於沒有logger.js,而只有logger目錄,因此在預設情況下,Node將載入index.js作為logger的起點。我們可以通過如下命令,來驗證其輸出結果:
在此,您可能心生疑慮:我們為什麼如此費盡周折地創建資料夾和index.js呢?其背後的原因在於:您可能會將一些複雜的依賴項放在一起,而這些依賴項也可能還有其他的依賴項。而對於需要logger的呼叫者(caller)而言,它們不需要知道其他依賴項的存在。
這便是一種封裝形式(encapsulation)。我們完全可以在多個檔案中,構建更為複雜的程式碼段;而在使用者(consumer)角度,它們只需使用一個檔案足矣。可見,資料夾是管理此類依賴性關係的更好方法。
Node程式包管理器(NPM)
第三類值得我們探討的依賴性管理是NPM。顧名思義,NPM是Node.js程式包的管理和分發工具,它相當於後端的Maven。它可以讓Javascript開發者更加輕鬆的共享和共用程式碼段。
通常,我們可以使用如下npm命令,來安裝依賴項:
npm install underscore;
如下程式碼段所示,我們也可以簡單地在app.js中require它:
如您所見,我們可以通過underscore的軟體包來使用各項功能。同理,當需要用到此類模組時,我們並沒有指定檔案的路徑,而只需使用其名稱即可。Node.js將會從您的應用程式的node_modules資料夾中,自動載入到其對應的模組。
下面是程式碼執行後的輸出結果:
小結
綜上所述,我們討論了Node.js是如何管理其依賴性關係的。您可以從Git儲存庫下載上述示例的原始碼。
相關文章
众所周知,Node.js是一个基于<em>Chrome</em> V8引擎的服务器端JavaScript运行环境。它采用了一种事件驱动的、非阻塞式的I/O模式,运行起来既轻量级又高效。诚然,我们可以使用单个js文件,来编写出应用程序所涉及到的全部内
2021-05-26 12:00:56
项思醒出轨,其男友做了65页PPT揭露其行为,让全国网友大吃一惊。 女海王很厉害,没想到,男海王还有更猛的。 厦门一人离婚,其前妻气不过,将他曾经约会过的女人并制成的<em>excel</em>表格公布出来,竟然有千人之多。 时
2021-05-26 12:00:31
大家好,我们接着讲表格办公软件,我们这一节课讲如何调整单元格式大小,在很多时候我们制作的表格会有一些偏大,就如图所示,这种表格显然和软件里的表格大小不一样,接下来我们就讲如何制作!当我们输入文字时,我们看到文字超出单
2021-05-26 12:00:26
在财务工作中,,<em>Excel</em>用得好,其实可以为我们省下很多时间和精力去做别的事情。最近突然想提升一下自己,但是工作也比较多,很难抽出多余的时间。为了给自己图省事儿,就编制了一套全自动财务记账系统,本来是为了给自己
2021-05-26 12:00:04
「来源: |东岳客 ID:rmrb<em>ssd</em>」新朋友点上方蓝字“东岳客”快速关注 我与一座城 在日照经山历海 赵德发 图为日照市风光。影像中国 1989年,山东日照升格为地级市。那时候,我正在山东大学作家班学习。后来,机缘巧
2021-05-26 11:33:32
显示屏:分辨率为1080P,游戏中画质也均为1080P;<em>CPU</em>:是最新的i7-11800H,8核16线程,稳超R7-5800H一头;内存:单根8GB,DDR4 -3200M赫兹;测试的第一款游戏、Days Gone, 或者叫《人生尽头》 画质设置为中,如视频所
2021-05-26 11:33:24