介紹
Node.js 中的一個重要概念是您想知道依賴管理的處理方式。這種依賴管理是 Node.js 核心體驗的一部分。在這篇文章中,我們將學(xué)習(xí)依賴管理的各種模式以及 Nodejs 如何加載依賴。
因此,我們可以為所有內(nèi)容使用單個js 文件編寫我們的應(yīng)用程序,但這不是模塊化的。Node.js 使編寫模塊化代碼變得非常簡單。
在我們深入研究細(xì)節(jié)之前,首先要回答的問題是模塊。它是什么?我們?yōu)槭裁匆P(guān)心它?
簡單來說,一個模塊就是一段代碼,我們將它們組合在一起,以便共享和重用。因此,模塊允許我們將應(yīng)用程序中的復(fù)雜性分解為小塊。這有助于理解代碼直至查找和修復(fù)錯誤。如果你想了解更多關(guān)于 JavaScript 模塊系統(tǒng)的信息,你可以查看這篇 文章。
Node 使用一種工具來要求 某些行為。這是基于 CommonJS 的。簡而言之,為了引入 JavaScript 文件,我們使用關(guān)鍵字require。
我假設(shè)您已經(jīng)了解 Nodejs 的一些基礎(chǔ)知識。如果您是 Nodejs 新手,您還可以查看我之前的文章Node.js – Introduction了解一些背景信息。
設(shè)置應(yīng)用程序
讓我們從簡單的開始。我為項目創(chuàng)建了一個目錄,使用npm init 對其進(jìn)行初始化,并創(chuàng)建了兩個 JavaScript 文件(app.js 和 appMsg.js)。這就是投影的樣子,我們將以此作為演示的起點。此外,您可以從文章后面提到的 git repo 鏈接下載最終代碼。
此時,兩個 .js 文件都是空的。讓我們用以下更改更新appMsgs.js文件:
我們可以看到module.exports關(guān)鍵字的使用。此語法用于公開給定文件 (appMsgs.js) 中的屬性或?qū)ο?,然后可以在另一個文件中使用這些屬性或?qū)ο?,在我們的示例中為app.js。
在這個系統(tǒng)中,每個文件都可以訪問稱為module.exports. 因此,我們在 appMsgs.js 文件中公開了一些項目,現(xiàn)在讓我們看看app.js如何使用(需要)這些屬性:
現(xiàn)在要引用文件,我們使用require關(guān)鍵字。當(dāng)我們 時require,它將返回一個將表示該模塊化代碼的對象,因此我們將其分配給一個變量appMsgs變量,然后在console.log語句中簡單地使用屬性。當(dāng)我們執(zhí)行代碼時,我們可以看到以下輸出:
所以,這 require是在執(zhí)行 JavaScript,允許它構(gòu)造一個返回給我們的具有一些功能的對象。
這可能是一個類構(gòu)造函數(shù)或一個對象,其中包含許多元素或一些簡單的屬性。這有不同的模式,我們可以導(dǎo)出不止一件東西,甚至導(dǎo)出復(fù)雜的對象。
因此,通過管理require和module.exports,我們可以創(chuàng)建這些模塊化應(yīng)用程序。
所需的功能加載代碼并加載一次。因此,無論在這里執(zhí)行什么代碼,都不會第二次執(zhí)行。因此,如果其他人通過 請求此對象require,它將獲得此對象的緩存版本。讓我們看看其他一些方法。
我已經(jīng)更改了代碼,現(xiàn)在不是公開對象,而是導(dǎo)出function. 每次作為函數(shù)調(diào)用時都會執(zhí)行此代碼。
接下來我們看看它在app.js文件中是如何使用的:
我們可以像執(zhí)行函數(shù)一樣執(zhí)行它,而不是調(diào)用屬性。所以,這里的區(qū)別在于,每次我們執(zhí)行這段代碼時,都會重新執(zhí)行函數(shù)內(nèi)部的代碼。
這是我們運行代碼時的輸出:
所以,我們已經(jīng)看到了兩種模式module.exports 和它們的區(qū)別。另一個常見的模式,你會想知道使用 this 作為構(gòu)造函數(shù) 方法。讓我們看一個例子:
這是更新后的app.js文件:
因此,這與在 JavaScript 中創(chuàng)建偽類 并允許創(chuàng)建它的實例 時本質(zhì)上是相同的。
這是此更改的輸出:
現(xiàn)在,讓我們看看這些模式的另一個例子:
我創(chuàng)建了一個名為userRepo.js的新文件,如下所示:
這是此更改的app.js和執(zhí)行結(jié)果:
對單個文件使用require并不少見,但您還應(yīng)該注意另一種模式。接下來讓我們看看文件夾的依賴關(guān)系。
文件夾依賴
我們將退后一步,了解 Nodejs 如何查找依賴項。記住前面例子中的那句話:
JavaScript:
var appMsgs = require ( "./appMsgs" )
Node 仍然會尋找appMsgs.js文件,但它也會尋找appMsgs 作為目錄 ,無論先找到哪個,它都會將其拉入。
現(xiàn)在讓我們看看代碼:
我創(chuàng)建了一個文件夾, 名為記錄器 和文件夾內(nèi),我創(chuàng)建了一個文件index.js。
這是index.js文件中的代碼:
這是需要此模塊的 app.js文件:
所以,在我們的例子中,我們可以說:
JavaScript:
var logger = require ( "./logger/index.js" )
這將是完全有效的。但相反,只需說以下內(nèi)容:
JavaScript:
var logger = require ( "./logger" )
由于沒有l(wèi)ogger.js,有一個 logger directory,默認(rèn)情況下它會加載index.js作為我們記錄器的起點。這就是我給index.js命名的原因,讓我們看看執(zhí)行這段代碼的結(jié)果是什么:
因此,就其本身而言,您可能會想,為什么要費心進(jìn)行創(chuàng)建文件夾和 inex.js 的額外步驟?
原因是您可能將一個復(fù)雜的依賴放在一起,而這個依賴可能有它所依賴的其他部分。需要記錄器的調(diào)用者不需要知道有一堆這些其他依賴項。
這是一種封裝形式,因此當(dāng)我們構(gòu)建更復(fù)雜的部分時,我們可以從多個文件中構(gòu)建它們。然后在消費者端,使用單個文件。它只是暗示文件夾是管理這些依賴項的好方法。
節(jié)點包管理器 (NPM)
我們還想簡要討論的另一件事是 NPM。您可能已經(jīng)知道它的用途。這帶來了額外的功能,它的使用非常簡單。
我們可以使用npm安裝依賴項:
npm install underscore;
然后可以簡單地在app.js 中使用它,如下所示:
可以看到我們?nèi)绾问褂孟聞澗€包提供的功能。此外,當(dāng)我們需要這個模塊時,我們沒有指定文件路徑,我們只是使用它的名稱,Nodejs 將從您應(yīng)用程序的node_modules文件夾中加載這個模塊。
這是執(zhí)行的輸出:
概括
在這篇文章中,我們學(xué)習(xí)了 Nodejs 如何管理其依賴項,并且我們看到了在我們的應(yīng)用程序中使用的一些模式。您可以從此Git 存儲庫下載源代碼。