NPM的做用: Node.js程序依賴包的發佈、管理和安裝。javascript
require是一個函數,參數是模塊標識符,返回值是所引用模塊暴露給外部使用者的內容。前端
直白一點講:java
一個模塊定義文件module1.jsnode
module.exports={ a:1, f: function(){ console.log('f'); } }
一個引用模塊module1.js的文件python
let m1 = require('module1.js'); console.log(m1); // {a: 1, f: ƒ}
在每一個模塊中,都有以下一些事物:git
![module對象實例]()數據庫
Note: exports 對象實際上指向 module.exports的引用,若是隨意替換module.exports
的引用,則會致使兩者的實際引用不相同。不瞭解這個問題的話,在世紀城使用中,可能會遇到一些難以預料的問題。npm
模塊標識是一個字符串,理論上應該是小駝峯式的命名方式,或者以「.」 , 「..」及「/」開頭的路徑。
若是模塊標識是文件路徑,理論上不須要在文件名後面加後綴「.js」。json
在符合CommonJS規範的狀況下,有一些機制能夠隨意實現。之因此這麼說,是由於實際上這些東西也是構建完整模塊所必須的,但CommonJS並未嚴格定義這些東西,理論上只要可以完成既定目標就能夠。後端
Node程序一般就是由一個個的模塊拼裝起來的。這些模塊可能的形式: js文件、json文件、C++模塊的二進制文件.node
。
這些模塊都是經過 require函數 引入。
Node中的模塊分爲兩類: 核心模塊 和 文件模塊。
核心模塊存在於Node源碼,屬於Node自帶模塊。主要是一些基礎性的模塊,例如:fs
, http
等。它們查找很是簡單,若是require中的模塊標誌符與這些核心模塊的名字吻合,則直接返回這些核心模塊export出的內容。
文件模塊是須要經過查找文件來得到的模塊。這些模塊都是第三方開發者編寫的程序,並不屬於Node自己的一部分。它們是你在編寫Node程序(基於Node.js運行的程序, Not Node.js self)時,引入的文件。
文件模塊又能夠分紅 第三方模塊和 項目模塊。
若是傳入require函數是一個文件路徑,通常能夠看做是項目模塊。對於項目模塊,若是路徑中指定了具體文件,則直接引入。若是路徑是一個目錄,則首先查找是否存在package.json
文件,若是存在且在package.json中定義了main
屬性,則根據main屬性的值查找模塊的入口文件,若是沒有,則依次查找目錄下的index.js
, index.json
以及index.node
。
若是傳入require函數的是一個非路徑的值,則能夠看做 第三方模塊。Node查找第三方模塊也有一套規則存在。
找到對應的模塊後,實際上也就等於獲取到了模塊的文件PATH,而後就會查找模塊的入口文件(查找規則跟項目模塊同樣),獲取模塊export的內容。
Node會緩存require的模塊,也就是說若是某個模塊被加載過,當在有其餘模塊引用該模塊的時候,Node會直接讀取緩存中的內容返回。
主要內容以前有寫過。
NPM(Node.js Package Manager)。
在NPM中存在一個包信息描述文件————package.json。這個文件會記錄這個包的其它依賴。並且它的第三方模塊會被放到node_modules目錄中,這就致使有些開發者會把這個目錄也做爲項目的一部分提交到git倉庫,但咱們實際並不推崇這麼作。由於node_modules提供的文件是項目運行時所需,且一般狀況下,它的內容會比較多。咱們能夠根據pacakge.json文件的描述,在運行項目以前安裝這些依賴(通常經過npm命令npm install
)。
若是你對第三方模塊的源碼有所改動,推薦的作法是在項目初始化時或者其餘比較合適的時機進行hack。
NPM下的package.json文件是基於CommonJS定義的包描述文件來實現的。但它有一些地方是與其不一樣的。這一點須要咱們明確。
在NPM中,NPM2與NPM3是有區別的,NPM2的依賴安裝路徑是嵌套式的,適合Node.js進行工具、後端的開發。在NPM2中,不一樣的的包若是使用名稱相同但版本不一樣的的第三方模塊,那麼這個模塊的兩個版本分別被放在各自引用者的node_modules目錄中,互不干擾。
node_modules ---- bar ---- node_modules ---- foo@1.0.0 ---- baz ---- node_modules ---- foo@2.0.0
而在NPM3中,依賴的安裝路徑變成了扁平式的。全部的第三方依賴包都被放倒根目錄下的node_modules中。這種方式適合前端項目:須要優化到很小代碼空間佔用量、以及打包分析等,同時順帶解決了Windows中文件路徑不容許過長的問題。
只有在遇到存在衝突的狀況下,纔會出現嵌套。
NPM3的思想:儘量的扁平化你的依賴。
CNPM是阿里巴巴集團的Node.js團隊研發的一套更快的NPM工具。它比NPM快不只僅是依靠使用國內的鏡像,還有就是在安裝過程當中,將一些包緩存到node_modules/.npminstall 目錄下,再以符號連接(Symbol Link)的形式將依賴目錄鏈接到對應的路徑。也就是說,在實際安裝過程當中,相同版本的包只有一份實體,相似於NPM3。
Node.js使用Chrome V8做爲Javascript的解釋器。
V8是一個高效的JavaScript引擎,不一樣於其餘JS引擎的地方:
JIT編譯,Just-In-Time編譯,即時編譯。編譯輸出結果是機器語言,而不是字節碼。
V8的垃圾回收器借鑑了Java VM的精確垃圾回收管理,其垃圾回收機制的效率是至關高的。
若是訪問過a.b,那麼當再次訪問a.b時,不會再對哈希表進行一次尋址,由於V8已經緩存過這個屬性的偏移量,不用再次計算尋址的偏移量。
TODO: 隱藏類的具體機制還有待進一步查詢資料。
V8引擎比較高效的機制主要是 內聯緩存和 隱藏類。
V8引擎遵循ECMA Script標準。Node.js會隨着V8的更新升級本身的代碼。
libuv 是一個專一於異步I/O的跨平臺類庫。最初是由Node的創始人Ryan Dahl爲Node寫的。只要是爲Node開發,可是也能夠支持其餘項目。
libuv中一個重要的概念是 事件循環。
PS:不一樣的平臺有不一樣的異步機制(如epoll、IOCP等),libuv 基於此實現來跨平臺的事件循環。
另外libuv接口簡潔明瞭,靈活性好,便於使用。Node中事件循環直接使用libuv的事件循環。
一個C實現的HTTP消息解析器,能解析HTTP協議的請求數據和返回數據。
安全套接字層協議庫。
SSL(Secure Socket Layer),能夠在網絡上提供祕密性的傳輸。用於對HTTP協議進行加密。
zlib是一個提供數據壓縮功能的庫。
神的編輯器和編輯器之神
node-gyp 是 Node.js下的C++擴展構建工具。基於GYP(General Your Projects)進行工做,GYP時Google的一套構建工具。
node-gyp進行工做須要一些依賴。
在UNIX系列平臺下:
在macOS下:
在 Windows中
也或者使用Visual C++ Build Tools(比較輕量級)。