如何使用 Browserify 在瀏覽器中使用 npm 套件

最後更新: 03/16/2026
作者: C 源追蹤
  • 瀏覽器缺乏對 Node 的 require 函數的原生支持,因此 CommonJS 風格的 npm 模組無法直接在客戶端 JavaScript 中運行。
  • Browserify 會分析類似 main.js 的入口文件,追蹤所有 require 調用,並將每個依賴項打包到一個可在瀏覽器中使用的 JavaScript 檔案中。
  • 使用諸如 npm install uniq 之類的命令安裝模組可以讓 Browserify 從 node_modules 拉取套件並將其嵌入到生成的 bundle.js 中。
  • 在 HTML 中使用標準 script 標籤引入 bundle.js,可以使基於 npm 的模組化程式碼在瀏覽器中作為一個最佳化的資源流暢地執行。

npm 套件 browser

當你開始使用 JavaScript 模組時,遇到的第一個摩擦點是 Node.js 載入程式碼的方式與瀏覽器載入程式碼的方式之間的差距。 在Node中,你只需要調用 require() 一切都神奇地連結在一起。但如果你直接在瀏覽器中嘗試同樣的操作,你會很快發現這個功能在瀏覽器中根本不存在。這時,圍繞著 npm 套件瀏覽器和 Browserify 等打包工具、工作流程和概念就派上了用場,它們可以解決這個問題。

本文將帶您了解 npm 作為套件生態系統如何與瀏覽、發現並最終打包這些套件以便它們能夠在 Web 瀏覽器中實際運行的概念相結合。 我們將重新審視一個基於 Browserify 的經典案例,並解釋原因。 require 它能在 Node 環境下運行,但無法在瀏覽器中運行。本文將逐步展示如何將一個小型腳本檔案打包成一個可以直接放入網頁的資源包,只需一個簡單的 script 標籤。在此過程中,我們還會提供相關的背景資訊、實用技巧以及一些現代替代方案,確保整個工作流程能夠應用於實際專案。

了解 Node.js 和瀏覽器之間的差距

Node.js npm 瀏覽器集成

關鍵的出發點是,Web 瀏覽器和 Node.js 提供的模組系統開箱即用,卻截然不同。 Node.js 歷來使用 CommonJS 模組格式,您可以透過該格式載入相依性。 require('package-name') 並公開功能 module.exports這種模式已經深度整合到 Node 執行階段中,但傳統瀏覽器對此一無所知。

在普通的瀏覽器環境中,沒有內建的 require 此功能不支援大多數 npm 套件所依賴的 CommonJS 風格模組。 瀏覽器能夠理解用於全域載入 JavaScript 檔案的傳統 script 標籤,並且在更現代的環境中,它還支援 ES 模組。 type="module" 雖然它具有屬性,但它本身仍然無法理解 Node 的 CommonJS 語義。

當你嘗試在客戶端 JavaScript 中直接重複使用 Node 風格的程式碼或 npm 套件時,這種差異就會成為一個問題。 你可能會有這樣一段簡單的程式碼片段: var unique = require('uniq') 這段程式碼在 Node 腳本中運行完美,但如果你把同一行程式碼貼到瀏覽器中載入的檔案中,就會立即出現引用錯誤,因為 require 未定義。

因此,開發者需要某種“橋樑”,使他們能夠繼續編寫熟悉的類似 Node 的程式碼,同時也能發布與瀏覽器相容的資源。 這個橋樑通常是一個打包器:一個從入口檔案開始遍歷依賴關係圖的工具,收集所有必要的內容,並輸出一個瀏覽器無需了解 Node 或 npm 即可執行的單一 JavaScript 套件。

Browserify 在 npm 生態系中的作用

Browserify 是早期解決 JavaScript 開發人員面臨的這一難題的重要工具之一。 它的目標很簡單:讓你用Node寫程式碼 require 按照這種模式,從 npm 拉取模組,然後將所有這些打包到一個單獨的檔案中,該檔案可以在瀏覽器中運行,就像 CommonJS 原生支援一樣。

從 npm 套件瀏覽的角度來看,Browserify 有效地將龐大的 Node 套件生態系統變成了一個潛在的客戶端相依性函式庫。 無需手動複製腳本,只需從 npm 安裝模組即可。 require() 就像在伺服器端程式碼中一樣,依靠 Browserify 將其轉換為使用者瀏覽器可以理解的內容。

在內部,Browserify 會遍歷所有透過以下方式引用的模組: require從給定的入口文件開始,建立依賴關係圖。 對於圖中的每個模組,它會將程式碼重寫成一種模擬瀏覽器中 CommonJS 環境的形式,包括局部作用域和瀏覽器友善的格式。 require 實現。最終產物是一個單獨的捆綁文件,通常名為 bundle.js它將所有這些模組封裝在一起。

最終實現的工作流程是,前端開發人員可以依賴 npm 上的軟體包,而無需擔心瀏覽器缺乏對 Node 模組的原生支援。 您可以存取龐大的庫目錄,用於執行資料操作、實用程式或 UI 助理等任務,但仍只需向客戶端提供一個腳本文件,即可無縫整合到傳統的 HTML 頁面中。

重寫經典的 Browserify 教學範例

為了具體說明,假設你有一個名為 `<script_name>` 的 JavaScript 檔案。 main.js 在你的專案中,你想使用一個名為 npm 的套件 uniq 從數組中過濾掉重複值。 在 Node 環境中,您需要以類似這樣的行開始檔案: var unique = require('uniq')這行程式碼從以下位置匯入導出的函數: uniq 將其儲存在名為 unique.

這裡面 main.js 然後,您可以建立一個包含重複條目的簡單數字陣列。 例如,您可以設定 var data = 其中某些數字出現不只一次。目標是產生一個新的數組,其中每個數字只出現一次,並按排序順序排列。

使用導入的函數後,其餘程式碼就變得非常簡單了。 你可以調用 console.log(unique(data)) 將傳回的陣列列印到控制台。 uniq 該軟體包會刪除清單中的重複值。如果在 Node.js 中執行此軟體包,您將看到一個輸出數組,其中每個數字只出現一次。

所有這些邏輯都基於以下假設: uniq 該模組已在您的環境中可用,並且 require 函數已定義且能夠解決問題。 在Node中,這是由運行時處理的。 節點模組解析演算法它會找到名為 node_modules 然後對於一個名為“ uniq 在裡面。

從 npm 安裝 uniq 套件

在你的程式碼可以呼叫之前 require('uniq')實際上,您需要從 npm 註冊表中安裝該軟體包。 這是透過命令列使用 Node.js 自帶的 npm 用戶端完成的。在專案資料夾中,您可以執行以下命令: npm install uniq 這樣,npm 就會下載該模組並將其儲存在…之下。 node_modules 目錄。

npm install uniq 該指令獲取已發布的版本 uniq 打包並將其新增至本機專案依賴項。 取決於你的 npm 配置以及你是否使用 package.json 如果產生該文件,它還可能將軟體包記錄到依賴項清單中,從而確保團隊中其他開發人員在不同環境中進行一致的安裝。

軟體包安裝完成後,專案的目錄結構中將包含一個新的目錄。 node_modules/uniq 包含該軟體包程式碼的資料夾。 這正是Node.js得以運作的原因。 require 系統在解析時定位模組 'uniq'Browserify 在開始建立你的 bundle 的依賴關係圖時,也會檢查同一個資料夾。

此時,你的 main.js 該檔案是完全有效的 Node 程式碼,可以在伺服器上執行,也可以使用標準 Node 解釋器從終端執行。 但是,如果你就此放棄這個 main.js 即使使用 script 標籤將檔案匯入網頁中,瀏覽器仍然無法理解 CommonJS 風格的匯入,因此需要額外的步驟才能使其在瀏覽器中可用。

將 main.js 及其相依性打包到 bundle.js 中

讓這段 Node 風格的程式碼能夠在瀏覽器中運作的關鍵步驟是讓 Browserify 進行處理。 main.js 及其所有必需模組,然後產生一個通常名為 JavaScript 的單一檔案。 bundle.js. 在專案中全域或本機安裝 Browserify 後,您可以透過命令列執行此操作。

觸發此過程的典型命令可能如下所示: browserify main.js -o bundle.js. 在這裡, browserify 是啟動打包過程的可執行文件, main.js 是 Browserify 視為依賴關係圖根目錄的入口文件, -o bundle.js 指示工具將產生的捆綁包寫入名為 bundle.js 在目前目錄中。

在後台,Browserify 會進行分析。 main.js緊隨其後 require 稱之為查找,並遞歸地探索每個導入的模組。 這包括您自己本地的文件(如果您使用相對路徑引入它們),以及位於以下位置的第三方模組: node_modules, 如那個 uniq 您剛從 npm 安裝的軟體包。

Browserify 遇到的每個依賴項都會轉換,以便它可以在瀏覽器中運行,而無需原生 Node 環境。 它將每個模組封裝在各自的作用域中,模擬 CommonJS 接口,並將所有這些轉換後的模組打包成一個腳本。最終結果 bundle.js 該檔案包含模仿以下程式碼 require 功能並允許您的原始 var unique = require('uniq') 在客戶端執行時,該行程式碼應能正常運作。

Browserify 完成後,您將只剩下一個 JavaScript 文件,其中包含您的原始應用程式邏輯以及使其正常工作所需的所有傳遞依賴關係樹。 現在,該文件可以像其他腳本一樣在 HTML 頁面中引用,無需在瀏覽器端進行任何額外的配置。

在 HTML 頁面中載入 Browserify 套件

bundle.js 將生成的所有內容整合到常規網站中就像在 HTML 中添加腳本標籤一樣簡單。 而不是嘗試加載 main.js 直接引用 Browserify 產生的編譯後的套件,該套件已經包含 uniq 以及你可能需要的任何其他 npm 模組。

一個基本的 HTML 程式碼片段可能包含類似這樣的內容: <script src="bundle.js"></script> 在關門前的某個時候 </body> 標籤。 此腳本標籤指示瀏覽器下載並執行 bundle.js 文件。因為該捆綁包在其內部模擬了 CommonJS 環境,所以您對該檔案的呼叫會受到影響。 require 即使全域瀏覽器環境仍然不知道函數是什麼,它仍然會在內部運作。

從頁面角度來看,這個套件與你可以包含的任何其他單一 JavaScript 檔案之間沒有任何明顯的區別。 模組的複雜性、內部依賴關係以及模擬 require 邏輯全部封裝在內部 bundle.js瀏覽器只需要載入並運行一個資源,與載入許多單獨的小檔案相比,這也具有效能優勢。

正因如此,即使在使用靜態 HTML 檔案或伺服器渲染模板的較舊的前端技術堆疊中,該工作流程也能很好地適應。 您無需徹底改變頁面結構;只需改變準備 JavaScript 的方式,將多個分散的資源和僅限 Node 的模組替換為 Browserify 產生的精簡套件即可。

為什麼使用 Browserify 打包對 npm 套件瀏覽至關重要

當人們談論「npm 套件瀏覽器」或瀏覽用於前端的 npm 套件時,其根本問題通常是:如何在基於瀏覽器的專案中實際使用此模組? Browserify 等工具的出現,將伺服器端程式庫的理論目錄變成了可以直接在 Web 應用程式中應用的實用工具箱。

實際上,這意味著在 npm 上尋找有用的模組不再局限於 Node 或後端開發。 如果你找到一個完全基於 JavaScript 資料結構且不依賴 Node 特定 API 的小型實用程式庫,那麼你很可能可以透過 Browserify 或類似工具將其打包,從而在瀏覽器中使用它。這大大擴展了你在解決諸如數組去重、數據轉換或實現小型演算法等問題時的選擇範圍。

此外,打包還可以減少網頁載入時需要執行的網路請求數量。 不再為每個本機檔案或遠端程式庫添加單獨的腳本標籤,而是將所有內容整合到一個單獨的腳本標籤中。 bundle.js 資產。它與 HTTP 快取配合良好,可以簡化部署流程,尤其是在處理依賴許多 npm 模組的複雜應用程式時。

從維護角度來看,能夠持續依賴 require 使用 npm 的依賴管理功能,可以讓你的前端程式庫感覺更可預測、更模組化。 您可以使用 npm 命令安裝、更新和刪除模組,集中審核依賴項,並讓 Browserify 處理瀏覽器相容性所需的轉換,而不是手動複製檔案或以臨時方式嵌入第三方程式碼。

與現代 JavaScript 工具的關係

雖然我們討論的經典例子主要集中在 Browserify 上,但它所展示的基本模式仍然是許多現代前端建構工具的基礎。 像 Webpack、Rollup、Parcel 或 Vite 這樣的新型打包工具也解決了將以風格編寫的模組轉換為瀏覽器可以高效執行的套件的問題。

現代瀏覽器現在原生支援 ES 模組 <script type="module">這改變了部分情況,但並不能消除對 npm 感知建置步驟的需求。 npm 生態系統中的許多軟體包仍然暴露 CommonJS 入口點或依賴 Node 風格的解析,即使 ES 模組構建可用,打包對於優化、搖樹和一致的加載行為仍然很有價值。

在這個更廣泛的背景下,使用的小例子 require('uniq'), npm install uniq 配備 browserify main.js -o bundle.js 該命令不僅僅是一個簡單的教程。 它展示了「編寫模組化程式碼,從 npm 安裝依賴項,然後產生瀏覽器友善的套件」的核心流程,這是當今幾乎所有嚴肅的前端設定所共有的模式,即使具體工具有所不同。

因此,了解 Browserify 的工作原理也有助於理解更新的技術堆疊。 與其將現代打包工具視為黑盒,不如看看它們的相似之處:它們都會讀取入口文件,跟踪導入或依賴項,收集依賴項,轉換代碼,並輸出瀏覽器通過簡單的腳本標籤加載的包。 npm 套件生態系統、模組系統和打包工具共同打造了日常開發中流暢無縫的體驗。

將所有內容整合到實用的工作流程中

回顧原範例中體現的實際工作流程,首先需要在類似這樣的文件中編寫應用程式程式碼: main.js 使用 require 導入任何你想使用的 npm 模組。 在該檔案中你可以調用 var unique = require('uniq')定義數組如下: 並將結果記錄到控制台。從概念上講,你的工作方式就好像所有這些操作都將在 Node.js 環境下運行一樣。

下一步是確保這些模組實際存在於你的專案中,例如透過 npm 安裝它們。 npm install uniq. 此操作會填入以下內容: node_modules 目錄,讓 Node 和 Browserify 都能存取模組的程式碼,以便在需要的地方解析和包含該模組。

程式碼和相依性就位後,您可以透過執行類似這樣的命令,指示 Browserify 從入口檔案開始遞歸地收集所有內容。 browserify main.js -o bundle.js. 這個過程遍歷依賴關係樹,包裝每個模組以在瀏覽器中模擬 CommonJS 環境,最後輸出結果。 bundle.js 作為包含所有必要程式碼的單一捆綁檔案。

最後,切換到 HTML 程式碼,並使用常規的 script 標籤來引用這一個輸出文件,例如: <script src="bundle.js"></script>. 頁面本身不需要任何特殊語法;所有複雜性都存在於套件內部。瀏覽器會下載並執行該套件。 bundle.js而其中的程式碼運行起來就好像 require 這些機制是內建在瀏覽器本身。

透過遵循這種模式,您可以有效地彌合 Node 的模組系統和瀏覽器環境之間的差距,同時繼續受益於龐大的 npm 套件生態系統。 您可以瀏覽軟體包、安裝它們、引入它們,然後將優化的文件發送給您的用戶,從而保持開發體驗和運行時環境的可管理性和高效性。

從更高層次來看,npm、Node 風格的模組和 Browserify 等打包工具的結合,將分散的 JavaScript 檔案集合轉換為連貫的、瀏覽器可用的資源管道。 開發者可以編寫模組化程式碼,依賴社群維護的軟體包,並且仍然可以向他們的網頁提供單一腳本,這使得現代 JavaScript 開發在各種工具和環境中都具有可擴展性和可訪問性。

ataque Shai-Hulud 與 npm suministro 的 cadena
相關文章:
Shai-Hulud: el ataque que sacude la cadena de suministro de npm
相關文章: