Node.js之模塊機制

来源:https://www.cnblogs.com/niyueling/archive/2019/09/21/11562990.html
-Advertisement-
Play Games

文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關註我的微信公眾號。 其實在JavaScript的發展中,它主要是在瀏覽器前端中被應用廣泛。因為在實際應用中, JavaScript的表現能力主要取決於宿主環境的API支持程度, 在最早期,只有對BOM, DOM的支持,隨著HTML ...


文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關註我的微信公眾號。
file

其實在JavaScript的發展中,它主要是在瀏覽器前端中被應用廣泛。因為在實際應用中, JavaScript的表現能力主要取決於宿主環境的API支持程度, 在最早期,只有對BOM, DOM的支持,隨著HTML5的出現,在瀏覽器中出現了更多,更強大的API供JavaScript調用,但是這些都是發生在前端,後端JavaScript的規範卻遠遠落後。Java有class文件,Phthon有import機制,PHP有include和require,但是JavaScript通過script標簽引入代碼的方式顯得雜亂無章,為我們的後期維護增加了難度。對於JavaScript來說,還有四大主要缺點:

  •     1.沒有模塊系統。
  •     2.標準庫比較少。
  •     3.沒有標準,統一的介面。
  •     4.缺乏包管理系統。

Node.js實現了一套非常易用的模塊系統,而Node的包管理系統NPM對包規範的完好支持使得Node應用在開發過程事半功倍。這一篇文章,主要針對Node的模塊以及包的實現進行說明。

Node的模塊規範

其實模塊的定義非常簡單,主要分為模塊引用,模塊定義和模塊標識三個部分。

1)模塊引用

Node.js中存在require()方法,這個方法接受模塊標識,以此引入一個模塊的API到當前的上下文中。

2)模塊定義

既然我們可以用require()來引入模塊,那自然也可以引出模塊。Node.js提供了exports對象用於導出當前模塊的方法和變數,並且exports是唯一導出的出口。在每個模塊中,存在一個module對象,表示模塊本身,exports其實就是module的一個屬性。在Node.js中,一個文件其實就是一個模塊,將我們需要導出的方法和屬性綁定在exports對象上作為屬性就可以將該方法或屬性導出。

在另一個模塊,可以通過require()引入模塊,就可以使用導出的方法sum()。

3)模塊標識

模塊標識其實傳遞給require()方法的參數,模塊標識必須是符合駝峰命名的字元串或者以./,../開頭的路徑,引入模塊模塊標識可以省略.js尾碼。

模塊的好處是將特定的方法和變數限定在特定的作用域中,使得開發者完全不必去考慮變數污染的問題。

Node.js的模塊實現

在Node.js中,有三類模塊,其中一類是Node.js提供的核心模塊,就比如上一篇說過的fs文件模塊,database資料庫模塊,還有一類是開發者自行編寫的文件模塊,就比如剛纔示例的test.js模塊,第三類就是自定義模塊,這是一種特殊的文件模塊,一般是一個文件或包的形式,比如引入mysql所需的jar包。

在Node.js中引入模塊,需要經歷三步:

(1)路徑分析

對於文件模塊來說,引入時模塊標識指明瞭確切的文件位置,所以在路徑分析中可以省略大量時間,載入速度僅次於核心模塊。

自定義模塊則是會從項目根目錄逐個比較路徑,直到找到目標模塊為止。所以,自定義模塊的路徑越深,路徑分析的耗時越多,所以自定義模塊的載入速度是最慢的。

(2)文件定位

剛纔其實說過了,模塊標識可以不包含尾碼名,所以Node.js在文件定位時會依次補充.js,.json,.node尾碼名,然後去進行文件定位,因為Node.js是單線程,所以文件定位時會發生堵塞,所以如果引入的模塊尾碼是.json或者.node,可以在引入的時候加上尾碼,可以提高查找速度。

(3)編譯執行

定義到具體文件後,Node.js會創建一個模塊對象,然後將模塊引入並且編譯。每一個編譯成功的模塊其文件路徑都會作為索引緩存在緩存對象上,以提高二次引入模塊的性能。

核心模塊在Node.js源代碼的編譯過程中,直接被編譯成二進位文件,然後被直接載入到記憶體中,所以核心模塊引入時,文件定位和編譯執行這兩個步驟可以直接跳過,並且核心模塊在路徑分析中會被優先判斷,所以核心模塊的載入速度是最快的。

文件模塊則是在執行時動態載入,所以路徑分析,文件定位以及編譯執行這三個步驟都不可省略,所以載入速度比核心模塊慢。

Node.js對引入過的模塊會進行緩存,以減少二次引入模塊的性能開銷二次載入模塊一律採用緩存優先方式。核心模塊的緩存檢查優先於文件模塊。

包管理工具NPM

剛纔說到Node模塊,但是雖然我們可以引用模塊,但是模塊與模塊之間仍然是散列在各地的,相互之間並不能直接引用。而Node的包管理工具NPM則將模塊相互聯繫起來。包其實是在模塊的基礎上進一步組織JavaScript代碼。

其實NPM會有一個包描述文件package.json,一般位於包的根目錄, NPM的所有行為都與包描述文件息息相關。前面幾篇有講過NPM作為預設包管理工具,會作為Node環境被一起安裝。

NPM常用功能

NPM幫助Node完成了第三方模塊的發佈,安裝和依賴。因為有NPM的存在,Node和第三方模塊之間形成了很好的一個生態系統,而且逐漸越來越強大。接下來大致講解下幾個NPM常見命令

  • npm --version 查看當前NPM的版本

  • npm 查看幫助說明

  • npm help 查看具體命令說明

  • 執行命令會在瀏覽器中打開對應命令的說明文檔

  • npm install 安裝依賴包,預設使用–-save參數,即預設添加到package.json中

  • 執行該命令,NPM會在當前目錄創建node_modules目錄,然後再node_modules創建對應依賴包的目錄,然後將依賴包解壓到該目錄。

  • npm init 在此目錄初始化生成package.json文件

  • npm uninstall 卸載依賴包, 預設使用-–save參數,即從package.json中移除

  • npm ls查看當前目錄的依賴包

  • npm root -g 查看全局安裝地址

  • npm list 查看依賴的當前版本

NPM存在的問題

在NPM平臺,每個人都可以分享包,所以包質量沒有辦法保證,而且Node.js運行在服務端,所以需要考慮安全問題。所以一個優秀的模塊需要符合幾大模塊:

  1. 具備良好的測試

  2. 具備良好的文檔

  3. 具備良好的測試覆蓋率

  4. 具備良好的代碼規範

今天內容就到這裡了,其實這篇文章並沒有涉及到代碼的編寫,而是從模塊的角度去理解Node.js,Node.js通過模塊規範,彌補了JavaSCript沒有結構性的不足,而NPM通過對包的統一管理,使得項目開發中的依賴問題得到有效解決。

下一篇將從非同步編程的角度帶大家繼續瞭解Node.js,下一篇再見!
歡迎關註我個人公眾號:程式猿周先森
file


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習前端以來,一直很好奇像京東,淘寶這種大型網站的購物車是怎麼做到統一的,就去搜索了一些資料吧!大致的看了一下,自己實戰了下,俗話說的好,讀萬卷書不如行萬里路!購物車只是一個很小的案例,但也可以去動手做一做,感受下過程!積少成多! 這案例主要是通過本地儲存來實現的,我用了兩種方法,一種是cookie ...
  • jQuery -動畫 jQuery動畫分為三個部分,非自定義動畫,自定義動畫,和全局動畫設置。 一、非自定義動畫: 1.顯示、隱藏: show( ) 、hide( )、toggle() 兩種用法:1)不傳參數,代表直接顯示隱藏。 2) 向方法中傳遞一個參數,這個參數為number類型,代表動畫的執行 ...
  • 今天給大家分享一下js中常用的基礎演算法,廢話不多說,直接上代碼; 1、兩個數字調換順序 2、對象排序,安裝對象中的id排序對象的位置; 3、冒泡排序 4、隨機出現不同的數字 5、字元串大小寫互換 6、數組隨機打亂 7、數組扁平化-把多維數組轉為一維數組 8、數組去重 9、數組尾部刪除,增加到前面; ...
  • 0921自我總結 CSS3動畫的使用 一.動畫的創建 @keyframes規則是創建動畫 瀏覽器相容 根據狀態的百分比來設置 上面如果有首碼下麵使用的時候必須加上首碼 二.css3動畫的屬性 animation設置動畫 :animation: name duration timing functio ...
  • 0921自我總結 css3如何解決動畫的播放、暫停和重新開始 一.解決的本質思路 播放的解決思路 先定義好動畫效果通過類名的增加達到樣式的出現 暫停的解決思路 我們播放動畫時,如要暫停動畫,就要用到 這個屬性。 屬性有兩個值: 當然去掉 ,也可以繼續播放動畫。 重新開始解決思路 播放與重新開始的解決 ...
  • JavaScript 變數 概述 把一個具體的值存入到變數中。那麼此時這個變數就代表著我們這個具體的值。我們如果想要重新的使用這個值,不再需要重新的計算或者其他操作,直接使用變數就可以得到之前存儲的這個值。 簡單的說,變數就是一個保存數據的容器,調用變數就是調用保存在這個容器中的值。 變數之所以叫做 ...
  • <input type="file" id='file'> <div> <img src="" alt="" id='preview'> </div> <script> let file = document.querySelector('#file'); let preview = documen ...
  • 工作中遇到需要根據不同數據來處理模板word的情況,網上搜索了一番之後,找到了一個叫做docxtemplater的庫,使用起來非常便攜,也十分滿足此次的需求。 這次就來記錄一下docxtemplater的使用。 docxtemplater官網:https://docxtemplater.readth ...
一周排行
    -Advertisement-
    Play Games
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...
  • 1. JUnit 最佳實踐指南 原文: https://howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/ 我假設您瞭解 JUnit 的基礎知識。 如果您沒有基礎知識,請首先閱讀(已針 ...