在前端歷史演變中已經提到,Nodejs的爆發從2009年開始。Nodejs的出現,基於做者Ryan Dahl 對Web開發高性能的追求,要達到高性能,異步IO/事件驅動是基本原則。對比一些高級語言,最終選擇Javascript做爲開發語言,因爲Javascript天生的事件驅動和單線程,奠基了Nodejs編寫高性能Web服務垂手可得。
javascript
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。
Node.js 使用了一個 事件驅動、 非阻塞式 I/O 的模型,使其輕量又高效。
V8 引擎是Chrome於2008年9月2日發佈開源。V8使用C++開發,相比其它的JavaScript的引擎轉換成字節碼或解釋執行,V8將其編譯成原生機器碼(IA-32, x86-64, ARM, or MIPS CPUs),而且使用瞭如內聯緩存(inline caching)等方法來提升性能。有了這些功能,JavaScript程序在V8引擎下的運行速度媲美二進制程序。
Chrome瀏覽器在Webkit渲染引擎中使用v8引擎來提升瀏覽器的渲染性能。
上圖是webkit大體結構,紅色部分是webkit的默認引擎,在谷歌系列產品中被替換爲v8引擎;
Nodejs是站在「巨人的肩膀」上進行一系列的封裝,它的高性能,離不開Chorme V8引擎。
java
Javascript 是一個靜態腳本語言,運行時必需要藉助於引擎才能運行。
Javascript 運行環境通常分爲兩種:node
咱們在Javascript中註冊個事件(回調函數)。但這個事件不是立刻執行。只有等事件被觸發的時候,纔會去執行這個事件(回調函數)。這種形式就是事件驅動。
webpack
阻塞:前一個程序未執行完就得一直等待。好比當你打電話問個問題時,那邊說你等等我給你查查,這時候你電話仍然是掛起的,等待等待,直到拿到結果。
非阻塞:前一個程序未執行完時能夠掛起,繼續執行其餘程序,等到使用時再執行。好比當你打電話過去問一個問題,而後掛電話,等那邊找到結果就打電話給你。查問題這段時間,你該幹嗎就幹嗎。
I/O: 磁盤的寫入(in)磁盤的讀取(out)。在程序執行過程當中必然要進行不少I/O操做,讀寫文件、輸入輸出、請求響應等等。I/O操做時最費時,舉個例子,你要讀一個文件,整個線程都暫停下來,等待文件讀完後繼續執行。換言之,I/O操做阻塞了代碼的執行,極大地下降了程序的效率。
在Nodejs裏面單線程能夠經過回調函數(事件驅動)來作異步操做,達到非阻塞I/O的效果。git
#安裝 brew install -g node #卸載 brew uninstall nodejs
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash # or wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash # 放入環境變量 source ~/.bash_profile # 判斷是否安裝成功 nvm list # 安裝node nvm install 6.14.4 # or 10.10.0, 8.9.1, etc # 判斷node安裝成功 node -v npm -v
在前端模塊化中已經對CommonJs作了介紹,並使用exports導出模塊,require引入模塊,實現了一個簡單案例。github
// index.js const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World\n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
運行 node index.js
會起一個去 127.0.0.1:3000
的服務,並在瀏覽器中輸出Hello world
web
path
模塊提供用於處理文件路徑和目錄路徑的實用工具。npm
// 引用 const path = require('path'); path.join('/foo', 'bar', 'baz/asdf', 'quux', '..'); // 返回: '/foo/bar/baz/asdf' // path.resolve() 方法將路徑或路徑片斷的序列解析爲絕對路徑 path.resolve('/foo/bar', './baz'); // 返回: '/foo/bar/baz'
fs
文件系統模塊,對文件和目錄進行讀寫操做。gulp
// 引用 const fs = require('fs'); // 讀取文件 fs.readFile('./test.txt', function(err, data) { if (err) { throw err; } console.log(data); }); // 寫入文件 fs.writeFile('input.txt', '我是新寫入的內容', function (err) { if (err) console.error(err); console.log('數據寫入的數據'); }); // 刪除 fs.unlink('/tmp/hello', (err) => { if (err) throw err; console.log('已成功刪除 /tmp/hello'); }); // 重命名 fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; console.log('重命名完成'); });
更多Api
參考Nodejs Api 官網。