Node.js前端
既是語言也是平臺,跳過了 Apache、Nginx 等 HTTP 服務器,直接面向前端開發node
JavaScript 是由 ECMAScript、文檔對象模型(DOM)和瀏覽器對象模型(BOM)組成的jquery
而 Mozilla 則指出 JavaScript 由 Core JavaScript 和 Client JavaScript 組成linux
能夠認爲,Node.js 中所謂的 JavaScript 只是 Core JavaScript,或者說是 ECMAScript 的一個實現webpack
最出色的一個實現: 將 JavaScript 移植到瀏覽器外程序員
node.js 興起之後,產生了 CommonJS web
CommonJS 試圖擬定一套完整的 JavaScript 規範,chrome
以彌補普通應用程序所需的 API,譬如文件系統訪問、命令行、模塊管理、函數庫集成等功能數據庫
CommonJS 制定者但願衆多服務端 JavaScript 實現遵循 CommonJS 規範,express
以便相互兼容和代碼複用。Node.js 的部份實現遵循了CommonJS規範,
但因爲二者還都處於誕生之初的快速變化期,也會有不一致的地方
使用了一個事件驅動、非阻塞 I/O 的模型,輕量又高效
適用於 I/O 密集型的領域: web 前端開發渲染、前端項目構建 webpack
適用於低延遲的網絡應用: 如 restful API、即時聊天
node.js 不須要操做 DOM 頁面文檔節點,因此沒有 document
node.js 沒有 window,node.js 的頂級對象是 global,有 global.console、setInterval、setTimeout... ...
node.js 實現了絕大部分 ECMAScript 語法規範
遠不止開發一個網站那麼簡單:
這和 PHP、Perl 不同,由於在使用 PHP 的時候,必須先搭建一個 Apache 之類的HTTP 服務器,
而後經過 HTTP 服務器的模塊加載或 CGI 調用,才能將 PHP 腳本的執行結果呈現給用戶
Node 除了用 V8 引擎來解析 JavaScript 外,還提供了高度優化的應用庫,用來提升服務器效率
消息事件是 JavaScript 和 Node 的核心 (一個很恰當的類比是,你從書店預訂一本書,等書到貨時,書店會「回調」通知你去取)
設計 Node.js 的一個主要目的是提供高度可擴展的服務器環境
早先 Netscape 服務器程序就支持 JavaScript 做爲一門服務器端腳本語言(稱爲 LiveScript)
Node 在內存處理上比傳統服務器程序高效得多,也就是可以同時快速地服務更多的用戶
Node 給 Web 服務器程序開發領域引進了事件驅動編程
AJAX 中 "J" 的惟一選擇就是 JavaScript,徹底沒有其餘替代品。
這致使整個行業急需大量優秀的 JavaScript 程序員。Web 成爲一個真正意義上的平臺
異步,因此會有回調函數嵌套太多,太深的問題(回調地獄)
異步事件模式: 要把一個完整的邏輯拆分爲一個個事件,增長了開發和調試難度(第三方模塊有解決方案)
單線程,處理很差 CPU 密集型任務(壓縮,解壓,服務器讀數據庫的數據)
最大的特色就是: 採用異步式 I/O 與事件驅動的架構設計
使用的是單線程模型,對於全部 I/O 都採用異步式的請求方式,避免了頻繁的上下文切換
Node.js 在執行的過程當中會維護一個事件隊列,
程序在執行時進入事件循環,等待下一個事件到來,
每一個異步式 I/O 請求完成後會被推送到事件隊列,等待程序進程進行處理
異步機制是基於事件的
全部的磁盤 I/O、網絡通訊、數據庫查詢都以非阻塞方式請求
返回的結果由事件循環來處理
// 傳統作法 res = db.query('SELECT * from some_table'); res.output(); // 以上代碼在執行到第一行的時候,線程會阻塞,等待數據庫返回查詢結果,而後再繼續處理。 // 然而,因爲數據庫查詢可能涉及磁盤讀寫和網絡通訊,其延時可能相 // 當大(長達幾個到幾百毫秒,相比CPU的時鐘差了好幾個數量級), // 線程會在這裏阻塞等待結果返回。對於高併發的訪問,一方面線程長期阻塞等待,另外一方面 // 爲了應付新請求而不斷增長線程,所以會浪費大量系統資源,同時線程的增多也會佔用大量 // 的 CPU 時間來處理內存上下文切換,並且還容易遭受低速鏈接攻擊
// Node.js 解決方案 db.query('SELECT * from some_table', function(res) { res.output(); }); // 這段代碼中 db.query 的第二個參數是一個函數,咱們稱爲回調函數。 // 進程在執行到 db.query 的時候,不會等待結果返回,而是直接繼續 // 執行後面的語句,直到進入事件循環。當數據庫查詢結果返回時, // 會將事件發送到事件隊列,等到線程進入事件循環之後, // 纔會調用以前的回調函數繼續執行後面的邏輯
Node.js 進程在同一時刻只會處理一個事件,完成後當即進入事件循環檢查並處理後面的事件。
這樣作的好處是,CPU 和內存在同一時間集中處理一件事,同時儘量讓耗時的 I/O 操做並行執行。
對於低速鏈接攻擊,Node.js 只是在事件隊列中增長請求,等待操做系統的迴應,
於是不會有任何多線程開銷,很大程度上能夠提升 Web 應用的健壯性,防止惡意攻擊
還有好比,在服務器端開發程序經常須要處理二進制文件,JavaScript 語言自己對此支持得很差,所以 V8 也如此,
如今出現了愈來愈多用 JavaScript 編寫的複雜網頁應用(如 Gmail),
若是能把越多的代碼共享到服務器上運行,那麼開發的成本也會越低。
好比,把文件系統或數據庫操做封裝成事件驅動形式的函數接口。
非阻塞函數會在它得到文件內容後,通知 Node 中的程序
正由於 Node 很容易擴展,在 Node 項目對外發布後,其社區便迅速涌現出大量擴展庫。
其中許可能是鏈接數據庫或其餘軟件的驅動接口,還有至關一部分是獨立有用的軟件
.help 會顯示幫助菜單
.clear 會清除當前運行的內容 它會清除內存中任何變量或閉包,而不須要重啓解析器
.exit 將退出 Node解析器
// 經過 require 方法把 HTTP 庫包含到程序中來
var http = require('http'); // HTTP 庫所具備的功能已經賦給了 http 對象
// Node 自己就是 Web 服務器 // 調用 HTTP 模塊的一個工廠模式方法(createServer)來建立新的 HTTP 服務器
// 新建立的 HTTP 服務器並無賦值給任何變量,它只會成爲存活在全局範圍內的匿名對象
// 傳了一個匿名函數做爲參數。此函數綁定在新建立服務器的事件監聽器上進行 request 事件處理
http.createServer(function (req, res) { // 一個是請求的對象(req),一個是響應的對象(res)
// 調用了 res 對象的幾個方法,這將修改響應結果
// 必須調用 res.writeHead 方法來設置 HTTP 響應頭,不然就不能返回真實內容給客戶端
// 設置狀態代碼爲 200(表示 HTTP 狀態代碼「200 OK」),而且傳入一段 HTTP 頭描述
res.writeHead(200, {'Content-Type': 'text/plain'}); // end 方法將會關閉 HTTP 鏈接。但由於咱們同時還傳入了一個字符串
res.end('Hello World\n'); // end 方法將在把此內容發送給客戶端後才關閉鏈接
}).listen(8124, "127.0.0.1"); // 經過鏈式調用來初始化服務器,並告訴它監聽在 8124 端口
console.log('Server running at http://127.0.0.1:8124/'); // 將在標準輸出 stdout 上打印信息 // 每當一個新的訪問請求到達 Web 服務器,它都將調用咱們指定的函數方法來處理
npm 徹底是用 JavaScript 和 node 編寫的
npm 給開發者提供了安裝工具,也給模塊維護人員提供了發佈工具
提供了發佈代碼的方法,或者將代碼發佈到本地,或者經過全局的 Node 模塊資源庫
管理代碼依賴包的安裝,以及其餘與發佈代碼相關的工做。
bin 可執行的二進制文件
lib/src js 代碼
doc 文檔
test 單元測試
表達非代碼相關信息, JSON 格式文件
包含字段:
name 包名
version 包的版本號 x.x.x-???
main 主模塊 (dist/jquery.js)
dependencies 生產依賴(好比基於 jQuery 開發的,項目運行時依賴就是 jQuery)
scripts
devDependencies 開發依賴(項目構建打包時須要的依賴)
自動建立 node_modules 文件夾,包含下載好的包
自動建立 package-lock.json 文件,以便二次下載更快
自動在 package.json 中的 dependencies 中默認添加到生產依賴
(npm install babel --save-dev 包添加到開發依賴)
(npm remove babel 刪除 包 和 這個包相關的全部信息)
npm install (下載 package.json 中的全部依賴包)
下載的包 使用,直接寫包名:
// (index.js)
const $ = requery('jquery');
自定義的包 使用,必須寫 ./ 或者 ../ 相對路徑開頭:
require(相對路徑/包名);
能夠安裝本身本地下載的包
但更多時候須要用 npm 在註冊庫中安裝遠程的包。
註冊庫保存了其餘 Node 開發者共享的包,供你使用
如數據庫驅動、流控制庫、數學庫。
npm 安裝的大部分庫是徹底用 JavaScript 編寫的,但也有少數須要編譯。幸運的是,npm 會幫你完成這些工做
npm search packagename // 若是你沒有提供包的名字,那麼全部可用的包都會顯示出來
npm remove packagename
npm cache clean
只須要建立一個 package.json 文件,
並添加關於你的模塊的簡單說明(包的名字和版本號是最重要的部分)。
要快速生成一個有效的包文件,能夠
在你的模塊文件夾路徑下運行命令 ① npm init,它會提示你輸入關於該模塊的描述信息,
而後該命令會在當前目錄下生成一個 packages.json 文件。
若是已經存在包文件,它的屬性會被做爲默認值,並容許修改
要使用本身的包,能夠
使用命令 ② npm install /path/to/yourpacage 進行安裝。
路徑能夠是本地文件系統的一個文件夾,也能夠是一個外部 URL(好比 GitHub)
若是你的模塊對大衆用戶也有用,而且已經準備好了,那麼能夠經過 npm 的 publish 命令對外發布
1. 用 adduser 命令建立一個用戶: ③npm adduser
2. 用 publish 命令發佈包: ④ npm publish
3. 目前,並不須要註冊或者驗證有效性
由於全部人均可以發佈包,並且沒有進行過濾或監督,因此你用 npm 安裝的包的質量是沒有保證的。因此說,用者自理
npm link 命令能建立你的項目及其依賴項之間的符號連接,所以在項目開發過程當中,依賴項中的任何改動都能爲你所用
你想從當前項目中經過 require() 訪問另一個項目中的功能
你想在多個項目中使用同一個包,並且不須要在每一個項目中都維護一個版本
好比,輸入 npm link express 會在全局包路徑中安裝 Express 框架,幷包含到你的項目中來。
每當 Express 升級,你的項目會自動從全局包文件夾中找到最新版原本使用。
若是你在多個項目中連接了 Express,全部這些項目都會同步到最新的版本,
這樣就不須要在 Express 升級時一個一個地操做了。
npm install -g cnpm -registry=https://registry.npm.taobao.org
npm install yarn -g
npm install cyarn -g --registry "https://registry.npm.taobao.org"
yarn -version
yarn add express
yarn init
yarn add global packagename
yarn remove packagename
yarn add packagename --dev
yarn list
yarn info packagename
Facebook 的 React框架
更快,有進度提示
有緩存
沒有本身的倉庫地址,使用的是 npm 倉庫地址
安裝路徑