摘要:感謝大神的免費的計算機(jī)編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡介現(xiàn)在,越來越多的科技公司和開發(fā)者開始使用開發(fā)各種應(yīng)用。
說明
2017-12-14 我發(fā)了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當(dāng)不錯的,甚至連著名的hax賀老都很認(rèn)同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很明顯的感到Node.js的普及度還不夠,還存很多誤解。甚至說很多小白用戶也得不到很好的學(xué)習(xí)。大神都功成身退,書也跟不上,大部分都是2013年左右的,Node.js版本都是基于v0.10左右的,現(xiàn)在已經(jīng)v9了。想想也是有點可惜,使用如此廣泛的Node.js被大家默認(rèn),卻沒人來科普。
反思之后,我就想準(zhǔn)備一個科普的Live,于是就有了《狼叔:如何正確學(xué)習(xí) Node.js?》,相信能夠?qū)芏嘞矚gNode.js的朋友有所幫助。Live已完成目前1200多人,230人評價,平均4.8+,還算是一個比較成功的Live?,F(xiàn)整理出來,希望對更多朋友有用。
感謝 @justjavac 大神的 免費的計算機(jī)編程類中文書籍 收錄并推薦
github地址,以后在倉庫里更新
Live地址,聲音版
【全文】狼叔:如何正確的學(xué)習(xí)Node.jsLive 簡介
現(xiàn)在,越來越多的科技公司和開發(fā)者開始使用 Node.js 開發(fā)各種應(yīng)用。Node.js除了能夠輔助大前端開發(fā)外,還可以編寫Web應(yīng)用,封裝Api,組裝RPC服務(wù)等,甚至是開發(fā)VSCode編輯器一樣的PC客戶端。和其它技術(shù)相比, Node.js 簡單易學(xué),性能好、部署容易,能夠輕松處理高并發(fā)場景下的大量服務(wù)器請求。Node.js 周邊的生態(tài)也非常強(qiáng)大,NPM(Node包管理)上有超過60萬個模塊,日下超過載量3億次。但編寫 Node.js 代碼對新人和其它語言背景的開發(fā)者來說,不是一件容易的事,在入門之前需要弄懂不少復(fù)雜的概念。
我身邊也有很多人問我:如何學(xué)習(xí) Node.js ?作為一名 Node.js 布道者,我做過很多 Node.js 普及和推廣的工作,對它的基本概念和核心模塊都很熟悉; 此外,我還在撰寫一本名為《更了不起的 Node.js 》的書,已經(jīng)寫了 2 年,積累了很豐富的資料,本次 Live 也將為你提供對 Node.js 更全面的解讀。
本次 Live 主要包括以下內(nèi)容,目錄
Part 0 :Node.js簡介
a)Node.js簡介
b)什么是Node.js?
c)基本原理
Part 1前言:學(xué)習(xí) Node.js 的三個境界
Part 2準(zhǔn)備:如何學(xué)習(xí)Node.js
2.1 Node 用途那么多,我該從哪里學(xué)起?
2.2 Node Web 框架那么多,我該怎么選?
2.3 關(guān)于 Node 的書幾乎都過時了,我該買哪本?
Part 3延伸:大前端變化那么快,如何才能做到每日精進(jìn)?
Part 4實踐:從招聘角度來看, Node.js 開發(fā)需要具備哪些技能?
Part 5答疑:回答大家的問題
本次Live主要是科普,適用新用戶和比較迷茫的Node朋友,希望大家多多理解和支持。
Part 0 :Node.js簡介a)Node.js簡介
b)什么是Node.js?
c)基本原理
Node.js 誕生于 2009 年,由 Joyent 的員工 Ryan Dahl 開發(fā)而成,之后 Joyent 公司一直扮演著 Node.js 孵化者的角色。由于諸多原因,Ryan 在2012年離開社區(qū),隨后在2015年由于 Node 貢獻(xiàn)者對 es6 新特性集成問題的分歧,導(dǎo)致分裂出iojs,并由 iojs 發(fā)布1.0、2.0和3.0版本。由于 iojs 的分裂最終促成了2015年Node基金會的成立,并順利發(fā)布了4.0版本。Node.js基金會的創(chuàng)始成員包括 Google、Joyent、IBM、Paypal、微軟、Fidelity 和 Linux基金會,創(chuàng)始成員將共同掌管過去由 Joyent 一家企業(yè)掌控的 Node.js 開源項目。此后,Node.js基金會發(fā)展非常好,穩(wěn)定的發(fā)布5、6、7、8等版本,截止發(fā)稿最新版本已經(jīng)是8.6,長期支持版本是6.11。
Node.js 不是一門語言也不是框架,它只是基于 Google V8 引擎的 JavaScript 運行時環(huán)境,同時結(jié)合 Libuv 擴(kuò)展了 JavaScript 功能,使之支持 io、fs 等只有語言才有的特性,使得 JavaScript 能夠同時具有 DOM 操作(瀏覽器)和 I/O、文件讀寫、操作數(shù)據(jù)庫(服務(wù)器端)等能力,是目前最簡單的全棧式語言。
早在2007年,Jeff Atwood 就提出了著名的 Atwood定律
任何能夠用 JavaScript 實現(xiàn)的應(yīng)用系統(tǒng),最終都必將用 JavaScript 實現(xiàn)
目前 Node.js 在大部分領(lǐng)域都占有一席之地,尤其是 I/O 密集型的,比如 Web 開發(fā),微服務(wù),前端構(gòu)建等。不少大型網(wǎng)站都是使用 Node.js 作為后臺開發(fā)語言的,用的最多的就是使用Node.js做前端渲染和架構(gòu)優(yōu)化,比如 淘寶 雙十一、去哪兒網(wǎng) 的 PC 端核心業(yè)務(wù)等。另外,有不少知名的前端庫也是使用 Node.js 開發(fā)的,比如,Webpack 是一個強(qiáng)大的打包器,React/Vue 是成熟的前端組件化框架。
Node.js通常被用來開發(fā)低延遲的網(wǎng)絡(luò)應(yīng)用,也就是那些需要在服務(wù)器端環(huán)境和前端實時收集和交換數(shù)據(jù)的應(yīng)用(API、即時聊天、微服務(wù))。阿里巴巴、騰訊、Qunar、百度、PayPal、道瓊斯、沃爾瑪和 LinkedIn 都采用了 Node.js 框架搭建應(yīng)用。
另外, Node.js 編寫的包管理器 npm 已成為開源包管理了領(lǐng)域最好的生態(tài),直接到2017年10月份,有模塊超過47萬,每周下載量超過32億次,每個月有超過700萬開發(fā)者使用npm。
當(dāng)然了,Node.js 也有一些缺點。Node.js 經(jīng)常被人們吐槽的一點就是:回調(diào)太多難于控制(俗稱回調(diào)地獄)和 CPU 密集任務(wù)處理的不是很好。但是,目前異步流程技術(shù)已經(jīng)取得了非常不錯的進(jìn)步,從Callback、Promise 到 Async函數(shù),可以輕松的滿足所有開發(fā)需求。至于 CPU 密集任務(wù)處理并非不可解,方案有很多,比如通過系統(tǒng)底層語言 Rust 來擴(kuò)展 Node.js,但這樣會比較麻煩。筆者堅信在合適的場景使用合適的東西,尤其是在微服務(wù)架構(gòu)下,一切都是服務(wù),可以做到語言無關(guān)。如果大家想使 JavaScript 做 CPU 密集任務(wù),推薦 Node.js 的兄弟項目 fibjs,基于纖程(fiber,可以簡單理解為更輕量級的線程),效率非常高,兼容npm,同時沒有異步回調(diào)煩惱。
b)什么是Node.js?按照 Node.js官方網(wǎng)站主頁 的說法:
Node.js? is a JavaScript runtime built on Chrome"s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js" package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
從這段介紹來看,解讀要點如下
Node.js 不是 JavaScript 應(yīng)用,不是語言(JavaScript 是語言),不是像 Rails(Ruby)、 Laravel(PHP) 或 Django(Python) 一樣的框架,也不是像 Nginx 一樣的 Web 服務(wù)器。Node.js 是 JavaScript 運行時環(huán)境
構(gòu)建在 Chrome"s V8 這個著名的 JavaScript 引擎之上,Chrome V8 引擎以 C/C++ 為主,相當(dāng)于使用JavaScript 寫法,轉(zhuǎn)成 C/C++ 調(diào)用,大大的降低了學(xué)習(xí)成本
事件驅(qū)動(event-driven),非阻塞 I/O 模型(non-blocking I/O model),簡單點講就是每個函數(shù)都是異步的,最后由 Libuv 這個 C/C++ 編寫的事件循環(huán)處理庫來處理這些 I/O 操作,隱藏了非阻塞 I/O 的具體細(xì)節(jié),簡化并發(fā)編程模型,讓你可以輕松的編寫高性能的Web應(yīng)用,所以它是輕量(lightweight)且高效(efficient)的
使用 npm 作為包管理器,目前 npm 是開源庫里包管理最大的生態(tài),功能強(qiáng)大,截止到2017年12月,模塊數(shù)量超過 60 萬+
大多數(shù)人都認(rèn)為 Node.js 只能寫網(wǎng)站后臺或者前端工具,這其實是不全面的,Node.js的目標(biāo)是讓并發(fā)編程更簡單,主要應(yīng)用在以網(wǎng)絡(luò)編程為主的 I/O 密集型應(yīng)用。它是開源的,跨平臺,并且高效(尤其是I/O處理),包括IBM、Microsoft、Yahoo、SAP、PayPal、沃爾瑪及GoDaddy都是 Node.js 的用戶。
c)基本原理下面是一張 Node.js 早期的架構(gòu)圖,來自 Node.js 之父 Ryan Dahl 的演講稿,在今天依然不過時,它簡要的介紹了 Node.js 是基于 Chrome V8引擎構(gòu)建的,由事件循環(huán)(Event Loop)分發(fā) I/O 任務(wù),最終工作線程(Work Thread)將任務(wù)丟到線程池(Thread Pool)里去執(zhí)行,而事件循環(huán)只要等待執(zhí)行結(jié)果就可以了。
核心概念
Chrome V8 是 Google 發(fā)布的開源 JavaScript 引擎,采用 C/C++ 編寫,在 Google 的 Chrome 瀏覽器中被使用。Chrome V8 引擎可以獨立運行,也可以用來嵌入到 C/C++ 應(yīng)用程序中執(zhí)行。
Event Loop 事件循環(huán)(由 libuv 提供)
Thread Pool 線程池(由 libuv 提供)
梳理一下
Chrome V8 是 JavaScript 引擎
Node.js 內(nèi)置 Chrome V8 引擎,所以它使用的 JavaScript 語法
JavaScript 語言的一大特點就是單線程,也就是說,同一個時間只能做一件事
單線程就意味著,所有任務(wù)需要排隊,前一個任務(wù)結(jié)束,才會執(zhí)行后一個任務(wù)。如果前一個任務(wù)耗時很長,后一個任務(wù)就不得不一直等著。
如果排隊是因為計算量大,CPU 忙不過來,倒也算了,但是很多時候 CPU 是閑著的,因為 I/O 很慢,不得不等著結(jié)果出來,再往下執(zhí)行
CPU 完全可以不管 I/O 設(shè)備,掛起處于等待中的任務(wù),先運行排在后面的任務(wù)
將等待中的 I/O 任務(wù)放到 Event Loop 里
由 Event Loop 將 I/O 任務(wù)放到線程池里
只要有資源,就盡力執(zhí)行
我們再換一個維度看一下
核心
Chrome V8 解釋并執(zhí)行 JavaScript 代碼(這就是為什么瀏覽器能執(zhí)行 JavaScript 原因)
libuv 由事件循環(huán)和線程池組成,負(fù)責(zé)所有 I/O 任務(wù)的分發(fā)與執(zhí)行
在解決并發(fā)問題上,異步是最好的解決方案,可以拿排隊和叫號機(jī)來理解
排隊:在排隊的時候,你除了等之外什么都干不了
叫號機(jī):你要做的是先取號碼,等輪到你的時候,系統(tǒng)會通知你,這中間,你可以做任何你想做的事兒
Node.js 其實就是幫我們構(gòu)建類似的機(jī)制。我們在寫代碼的時候,實際上就是取號的過程,由 Event Loop 來接受處理,而真正執(zhí)行操作的是具體的線程池里的 I/O 任務(wù)。之所以說 Node.js 是單線程,就是因為在接受任務(wù)的時候是單線程的,它無需進(jìn)程/線程切換上下文的成本,非常高效,但它在執(zhí)行具體任務(wù)的時候是多線程的。
Node.js 公開宣稱的目標(biāo)是 “旨在提供一種簡單的構(gòu)建可伸縮網(wǎng)絡(luò)程序的方法”,毫無疑問,它確實做到了。這種做法將并發(fā)編程模型簡化了,Event Loop和具體線程池等細(xì)節(jié)被 Node.js 封裝了,繼而將異步調(diào)用 Api 寫法暴露給開發(fā)者。真是福禍相依,一方面簡化了并發(fā)編程,另一方面在寫法上埋下了禍根,這種做法的好處是能讓更多人輕而易舉的寫出高性能的程序!
在Node.js Bindings層做的事兒就是將 Chrome V8 等暴露的 C/C++ 接口轉(zhuǎn)成JavaScript Api,并且結(jié)合這些 Api 編寫了 Node.js 標(biāo)準(zhǔn)庫,所有這些 Api 統(tǒng)稱為 Node.js SDK,后面模塊章節(jié)會有更詳細(xì)的討論。
微軟在2016年宣布在MIT許可協(xié)議下開放 Chakra 引擎,并以 ChakraCore 為名在 Github 上開放了源代碼,ChakraCore 是一個完整的 JavaScript 虛擬機(jī),它擁有著和 Chakra 幾乎相同的功能與特性。微軟向 Node.js 主分支提交代碼合并請求,讓 Node.js 用上 ChakraCore引擎,即 nodejs/node-chakracore 項目。實際上微軟是通過創(chuàng)建名為 V8 shim 的庫的賦予了 ChakraCore 處理谷歌 Chrome V8 引擎指令的能力,其原理示意圖如下
目前,Node.js 同時支持這2種 JavaScript 引擎,二者性能和特性上各有千秋,ChakraCore 在特性上感覺更潮一些,曾經(jīng)是第一個支持 Async函數(shù) 的引擎,但目前 Node.js 還是以 Chrome V8 引擎為主, ChakraCore 版本需要多帶帶安裝,大家了解一下就好。
Part 1前言:學(xué)習(xí) Node.js 的三個境界我總結(jié)的編程3種境界
打日志:console.log
斷點調(diào)試:斷點調(diào)試:node debugger 或node inspector 或vscode
測試驅(qū)動開發(fā)(tdd | bdd)
大家可以自測一下,自己在哪個水平?如果是第三個階段,那么本場Live可能不太適合你。哈哈哈
Part 2準(zhǔn)備:如何學(xué)習(xí)Node.jsNode不是語言,不是框架,只是基于V8運行時環(huán)境。結(jié)合libuv能夠通過js語法獲得更好的等價于c/c++的性能。
它很簡單,異步是解決并發(fā)的最佳實踐。本節(jié)主要講如何學(xué)習(xí)Node.js,是本次Live非常核心的內(nèi)容,大家要注意聽。
基礎(chǔ)學(xué)習(xí)1)js語法必須會
js基本語法,都是c語系的,有其他語言背景學(xué)習(xí)起來相對更簡單
常見用法,比如正則,比如數(shù)據(jù)結(jié)構(gòu),尤其是數(shù)組的幾種用法。比如bind/call/apply等等
面向?qū)ο髮懛ās是基于對象的,所以它的oo寫起來非常詭異。參見紅皮書JavaScript高級編程,很多框架都是自己實現(xiàn)oo基礎(chǔ)框架,比如ext-core等。
犀牛書,《JavaScript權(quán)威指南》,沒事就多翻翻,看少多少遍都不為過。
2)個人學(xué)習(xí)和技術(shù)選型都要循序漸進(jìn)
先能寫,采用面向過程寫法,簡單理解就是定義一堆function,然后調(diào)用,非常簡單
然后再追求更好的寫法,可以面向?qū)ο?。對于?guī)?;木幊虂碚f,oo是有它的優(yōu)勢的,一般java、c#,ruby這些語言里都有面向?qū)ο?,所以后端更?xí)慣,但對于語言經(jīng)驗不那么強(qiáng)的前端來說算高級技巧。
等oo玩膩了,可以有更好的追求:函數(shù)式編程,無論編程思維,還是用法上都對已有的編程思維是個挑戰(zhàn)。我很喜歡函數(shù)式,但不太會在團(tuán)隊里使用,畢竟oo階段還沒完全掌握,風(fēng)險會比較大。但如果團(tuán)隊水平都非常高了,團(tuán)隊穩(wěn)定是可以用的。
可以看出我的思路,先能寫,然后再追求更好的寫法,比如面向?qū)ο?。等團(tuán)隊水平到一定程度了,并且穩(wěn)定的時候,可以考慮更加極致的函數(shù)式寫法。
團(tuán)隊是這樣選型的,個人學(xué)習(xí)也這樣,最好是循序漸進(jìn),步子邁大了不好。
3)各種高級的JavaScript友好語言
JavaScript友好語言指的是能夠使用其他語法實現(xiàn),但最終編譯成js的語言。自從Node.js出現(xiàn)后,這種黑科技層出不窮。比如比較有名的coffee、typescript、babel(es)等。
CoffeeScript雖然也是JavaScript友好語言,但其語法借鑒ruby,崇尚極簡,對于類型和OO機(jī)制上還是偏弱,而且這么多年也沒發(fā)展起來,仍然是比較小眾的活著。未來比例會越來越少的。
顯然TypeScript會越來越好,TypeScript 的強(qiáng)大之處是要用過才知道的。
1)規(guī)?;幊?,像Java那種,靜態(tài)類型,面向?qū)ο?,前端只有TypeScript能做到
2)親爹是微軟安德斯·海爾斯伯格,不知道此人的請看borland傳奇去
3)開源,未來很好
4)組合拳:TypeScript + VSCode = 神器
當(dāng)下前端發(fā)展速度極快,以指數(shù)級的曲線增長。以前可能1年都不一定有一項新技術(shù),現(xiàn)在可能每個月都有。大前端,Node全棧,架構(gòu)演進(jìn)等等都在快速變化??梢哉f,前端越復(fù)雜,有越多的不確定性,TypeScript的機(jī)會就越大。
4)再論面向?qū)ο?/p>
面向?qū)ο笙胗煤靡膊蝗菀椎?,而且js里有各種實現(xiàn),真是讓人眼花繚亂。
基于原型的寫法,縱觀JavaScript高級編程,就是翻來覆去的講這個,這個很基礎(chǔ),但不好是很好用??梢圆挥?,但不可以不會。
自己寫面向?qū)ο髾C(jī)制是最好的,但不是每個人都有這個能力的。好在es6規(guī)范出了更好一點的面向?qū)ο?,通過class、extends、super關(guān)鍵字來定義類,已經(jīng)明顯好很多了,雖然還很弱,但起碼勉強(qiáng)能用起來了。從面向過程走過來的同學(xué),推薦這種寫法,簡單易用。但要注意面向?qū)ο笠忻嫦驅(qū)ο蟮膶懛?,要理解抽象,繼承,封裝,多態(tài)4個基本特征。如果想用好,你甚至還需要看一些設(shè)計模式相關(guān)的書。好在有《JavaScript設(shè)計模式》一書。Koa2里已經(jīng)在用這種寫法了。
js是腳本語言,解釋即可執(zhí)行。所以它的最大缺點是沒有類型系統(tǒng),這在規(guī)模化編程里是非常危險的,一個函數(shù),傳參就能玩死人。于是現(xiàn)在流行使用flow和typescript來做類型校驗。flow只是工具,比較輕量級。而typescript是es6超級,給es6補充了類型系統(tǒng)和更完善的面向?qū)ο髾C(jī)制,所以大部分人都會對ts有好感,很有可能是未來的趨勢。
對于es6高級特性,我是比較保守的,一般node長期支持版本lts支持的我都讓用,一些更新的特性我一般不讓使用。根本lts版本保持一致就好。
我的團(tuán)隊現(xiàn)在是采用es6的面向?qū)ο髮懛ㄩ_發(fā),后面會一點一點轉(zhuǎn)到typescript上的。熟練oo轉(zhuǎn)到ts是非常容易的。
安裝Node.js環(huán)境3m安裝法
nvm(node version manager)【需要使用npm安裝,替代品是yrm(支持yarn),nvs對window支持很好】
nrm(node registry manager)【需要使用npm安裝,替代品是yrm(支持yarn)】
npm(node packages manager)【內(nèi)置,替代品是n或nvs(對win也支持)】
nvmnode版本發(fā)布非???,而且多版本共存可能性較大,推薦使用nvm來安裝node
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash $ echo "export NVM_DIR="$HOME/.nvm"" >> ~/.zshrc $ echo "[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm" >> ~/.zshrc $ source ~/.zshrc $ nvm install 0.10 $ nvm install 4 $ nvm install 6 $ nvm install 8nrm
https://registry.npmjs.com 是node官方的源(registry),服務(wù)器在國外,下載速度較慢,推薦安裝nrm來切換源,國內(nèi)的cnpm和taobao的源都非常快,當(dāng)然,如果你想自建源也是支持的。
$ npm install --global nrm --registry=https://registry.npm.taobao.org $ nrm use cnpmnpm
nrm切換完源之后,你安裝npm模塊的速度會更快。
$ npm install --global yarn
npm基本命令
名稱 | 描述 | 簡寫 |
---|---|---|
npm install xxx | 安裝xxx模塊,但不記錄到package.json里 | npm i xxx |
npm install --save xxx | 安裝xxx模塊,并且記錄到package.json里,字段對應(yīng)的dependency,是產(chǎn)品環(huán)境必須依賴的模塊 | npm i -s xxx |
npm install --save-de xxx | 安裝xxx模塊,并且記錄到package.json里,字段對應(yīng)的dev-dependency,是開發(fā)環(huán)境必須依賴的模塊,比如測試類的(mocha、chai、sinon、zombie、supertest等)都在 | npm i -D xxx |
npm install --global xxx | 全局安裝xxx模塊,但不記錄到package.json里,如果模塊里package.json有bin配置,會自動鏈接,作為cli命令 | npm i -g xxx |
1)oh my zsh是我最習(xí)慣的shell,終端下非常好用
配合iterm2分屏 + spectacle全屏,幾乎無敵
2)brew是mac裝軟件非常好的方式,和apt-get、rpm等都非常類似
安裝4個必備軟件
brew install git 最流行的SCM源碼版本控制軟件
brew install wget 下載、扒站神器
brew install ack 搜索代碼神器
brew install autojump 終端下多目錄跳轉(zhuǎn)神器
3)vim
我雖然不算vim黨,但也深愛著。janus是一個非常好用的vim集成開發(fā)環(huán)境。比如ctrl-p、nerdtree等插件都集成了,對我這種懶人足夠了。
IDE和編輯器關(guān)于Node.js的IDE和編輯器有很多選擇,對比如下
名稱 | 是否收費 | 斷點調(diào)試 | 功能 |
---|---|---|---|
Webstorm | 收費 | 支持 | 是IDE,在代碼提示、重構(gòu)等方面功能非常強(qiáng)大,支持的各種語言、框架、模板也非常多,支持?jǐn)帱c調(diào)試,好處是特別智能,缺點也是特別智能 |
Sublime/TextMate | 收費 | 不支持 | 編輯器里非常好用的,textmate主要針對mac用戶,sublime是跨平臺的,相信很多前端開發(fā)都熟悉 |
Vim/Emace | 免費 | 不支持 | 命令行下的編輯器,非常強(qiáng)大,難度也稍大,但更為酷炫,而且對于服務(wù)器部署開發(fā)來說是值得一學(xué)的 |
VSCode/Atom | 免費 | 支持 | Atom比較早,功能強(qiáng)大,缺點稍卡頓,VSCode是微軟出的,速度快,對于Node.js 調(diào)試,重構(gòu),代碼提示等方面支持都非常好 |
Visual Studio Code是一個運行于 Mac、Windows和 Linux 之上的,針對于編寫現(xiàn)代 Web 和云應(yīng)用的跨平臺源代碼編輯器。它功能強(qiáng)大,便于調(diào)試,加上它本身也是基于 Node.js 模塊 electron 構(gòu)建的,尤其要推薦大家使用。
Visual Studio Code(以下簡稱vsc)
vsc是一個比較潮比較新的編輯器(跨平臺Mac OS X、Windows和 Linux )
vsc功能和textmate、sublime、notepad++,ultraedit等比較,毫不遜色
vsc尤其是在nodejs(調(diào)試)和typescript、go上支持尤其好
vsc提供了自定義 Debugger Adapter 和 VSCode Debug Protocol 從而實現(xiàn)自己的調(diào)試器
值得一學(xué),我推薦VSCode編輯器!
更多調(diào)試方法,參見https://github.com/i5ting/nod...
Node.js應(yīng)用場景《Node.js in action》一書里說,Node.js 所針對的應(yīng)用程序有一個專門的簡稱:DIRT。它表示數(shù)據(jù)密集型實時(data-intensive real-time)程序。因為 Node.js 自身在 I/O 上非常輕量,它善于將數(shù)據(jù)從一個管道混排或代理到另一個管道上,這能在處理大量請求時持有很多開放的連接,并且只占用一小部分內(nèi)存。它的設(shè)計目標(biāo)是保證響應(yīng)能力,跟瀏覽器一樣。
這話不假,但在今天來看,DIRT 還是范圍小了。其實 DIRT 本質(zhì)上說的 I/O 處理的都算,但隨著大前端的發(fā)展,Node.js 已經(jīng)不再只是 I/O 處理相關(guān),而是更加的“Node”!
Node.js 使用場景主要分為4大類
1)跨平臺:覆蓋你能想到的面向用戶的所有平臺,傳統(tǒng)的PC Web端,以及PC客戶端 nw.js/electron 、移動端 cordova、HTML5、react-native、weex,硬件 ruff.io 等
2)Web應(yīng)用開發(fā):網(wǎng)站、Api、RPC服務(wù)等
3)前端:三大框架 React Vue Angular 輔助開發(fā),以及工程化演進(jìn)過程(使用Gulp /Webpack 構(gòu)建 Web 開發(fā)工具)
4)工具:npm上各種工具模塊,包括各種前端預(yù)編譯、構(gòu)建工具 Grunt / Gulp、腳手架,命令行工具,各種奇技淫巧等
下面列出具體的 Node.js 的使用場景,以模塊維度劃分
分類 | 描述 | 相關(guān)模塊 |
---|---|---|
網(wǎng)站 | 類似于 cnodejs.org 這樣傳統(tǒng)的網(wǎng)站 | Express / Koa |
Api | 同時提供給移動端,PC,H5 等前端使用的 HTTP Api 接口 | Restify / HApi |
Api代理 | 為前端提供的,主要對后端Api接口進(jìn)行再處理,以便更多的適應(yīng)前端開發(fā) | Express / Koa |
IM即時聊天 | 實時應(yīng)用,很多是基于 WebSocket協(xié)議的 | Socket.io / sockjs |
反向代理 | 提供類似于 nginx 反向代理功能,但對前端更友好 | anyproxy / node-http-proxy / hiproxy |
前端構(gòu)建工具 | 輔助前端開發(fā),尤其是各種預(yù)編譯,構(gòu)建相關(guān)的工具,能夠極大的提高前端開發(fā)效率 | Grunt / Gulp / Bower / Webpack / Fis3 / YKit |
命令行工具 | 使用命令行是非??岬姆绞剑岸碎_發(fā)自定義了很多相關(guān)工具,無論是shell命令,node腳本,還是各種腳手架等,幾乎每個公司小組都會自己的命令行工具集 | Cordova / Shell.js |
操作系統(tǒng) | 有實現(xiàn),但估計不太會有人用 | NodeOS |
跨平臺打包工具 | 使用 Web 開發(fā)技術(shù)開發(fā)PC客戶端是目前最流行的方式,會有更多前端開發(fā)工具是采用這種方式的 | PC端的electron、nw.js,比如釘釘PC客戶端、微信小程序IDE、微信客戶端,移動的Cordova,即老的Phonegap,還有更加有名的一站式開發(fā)框架Ionicframework |
P2P | 區(qū)塊鏈開發(fā)、BT客戶端 | webtorrent / ipfs |
編輯器 | Atom 和 VSCode 都是基于 electron 模塊的 | electron |
物聯(lián)網(wǎng)與硬件 | ruff.io和很多硬件都支持node sdk | ruff |
Node.js 應(yīng)用場景非常豐富,比如 Node.js 可以開發(fā)操作系統(tǒng),但一般我都不講的,就算說了也沒多大意義,難道大家真的會用嗎?一般,我習(xí)慣將 Node.js 應(yīng)用場景氛圍7個部分。
1)初衷,server端,不想成了前端開發(fā)的基礎(chǔ)設(shè)施
2)命令行輔助工具,甚至可以是運維
3)移動端:cordova,pc端:nw.js和electron
4)組件化,構(gòu)建,代理
5)架構(gòu),前后端分離、api proxy
6)性能優(yōu)化、反爬蟲與爬蟲
7) 全棧最便捷之路
編號 | 場景 | 說明 |
---|---|---|
1 | 反向代理 | Node.js可以作為nginx這樣的反向代理,雖然線上我們很少這樣做,但它確確實實可以這樣做。比如node-http-proxy和anyproxy等,其實使用Node.js做這種請求轉(zhuǎn)發(fā)是非常簡單的,在后面的http章節(jié)里,有多帶帶的講解。 |
2 | 爬蟲 | 有大量的爬蟲模塊,比如node-crawler等,寫起來比python要簡單一些,尤其搭配jsdom(node版本的jQuery)類庫的,對前端來說尤其友好 |
3 | 命令行工具 | 所有輔助開發(fā),運維,提高效率等等可以用cli做的,使用node來開發(fā)都非常合適,是編寫命令行工具最簡單的方式,java8以后也參考了node的命令行實現(xiàn) |
4 | 微服務(wù)與RPC | node里有各種rpc支持,比如node編寫的dnode,seneca,也有跨語言支持的grpc,足夠應(yīng)用了 |
5 | 微信公眾號開發(fā) | 相關(guān)sdk,框架非常多,是快速開發(fā)的利器 |
6 | 前端流行SSR && PWA | SSR是服務(wù)器端渲染,PWA是漸進(jìn)式Web應(yīng)用,都是今年最火的技術(shù)。如果大家用過,一定對Node.js不陌生。比如React、Vuejs都是Node.js實現(xiàn)的ssr。至于pwa的service-worker也是Node.js實現(xiàn)的。那么為啥不用其他語言實現(xiàn)呢?不是其他語言不能實現(xiàn),而是使用Node.js簡單、方便、學(xué)習(xí)成本低,輕松獲得高性能,如果用其他語言,我至少還得裝環(huán)境 |
可以說目前大家能夠看到的、用到的軟件都有 Node.js 身影,當(dāng)下最流行的軟件寫法也大都是基于 Node.js 的,比如 PC 客戶端 luin/medis 采用 electron 打包,寫法采用 React + Redux。我自己一直的實踐的【Node全?!?,也正是基于這種趨勢而形成的。在未來,Node.js 的應(yīng)用場景會更加的廣泛,更多參見 sindresorhus/awesome-nodejs。
Node核心:異步流程控制Node.js是為異步而生的,它自己把復(fù)雜的事兒做了(高并發(fā),低延時),交給用戶的只是有點難用的Callback寫法。也正是坦誠的將異步回調(diào)暴露出來,才有更好的流程控制方面的演進(jìn)。也正是這些演進(jìn),讓Node.js從DIRT(數(shù)據(jù)敏感實時應(yīng)用)擴(kuò)展到更多的應(yīng)用場景,今天的Node.js已經(jīng)不只是能寫后端的JavaScript,已經(jīng)涵蓋了所有涉及到開發(fā)的各個方面,而Node全棧更是熱門種的熱門。
直面問題才能有更好的解決方式,Node.js的異步是整個學(xué)習(xí)Node.js過程中重中之重。
1) 異步流程控制學(xué)習(xí)重點
2)Api寫法:Error-first Callback 和 EventEmitter
3)中流砥柱:Promise
4)終極解決方案:Async/Await
1) 異步流程控制學(xué)習(xí)重點我整理了一張圖,更直觀一些。從09年到現(xiàn)在,8年多的時間里,整個Node.js社區(qū)做了大量嘗試,其中曲折足足夠?qū)懸槐緯牧?。大家先簡單了解一下?/p>
紅色代表Promise,是使用最多的,無論async還是generator都可用
藍(lán)色是Generator,過度貨
綠色是Async函數(shù),趨勢
結(jié)論:Promise是必須會的,那你為什么不順勢而為呢?
推薦:使用Async函數(shù) + Promise組合,如下圖所示。
其實,一般使用是不需要掌握上圖中的所有技術(shù)的。對于初學(xué)者來說,先夠用,再去深究細(xì)節(jié)。所以,精簡一下,只了解3個就足夠足夠用了。
結(jié)論
Node.js SDK里callback寫法必須會的。
Node.js學(xué)習(xí)重點: Async函數(shù)與Promise
中流砥柱:Promise
終極解決方案:Async/Await
所以下面我們會分個小部分進(jìn)行講解。
2)Api寫法:Error-first Callback 和 EventEmittera)Error-first Callback
定義錯誤優(yōu)先的回調(diào)寫法只需要注意2條規(guī)則即可:
回調(diào)函數(shù)的第一個參數(shù)返回的error對象,如果error發(fā)生了,它會作為第一個err參數(shù)返回,如果沒有,一般做法是返回null。
回調(diào)函數(shù)的第二個參數(shù)返回的是任何成功響應(yīng)的結(jié)果數(shù)據(jù)。如果結(jié)果正常,沒有error發(fā)生,err會被設(shè)置為null,并在第二個參數(shù)就出返回成功結(jié)果數(shù)據(jù)。
下面讓我們看一下調(diào)用函數(shù)示例,Node.js 文檔里最常采用下面這樣的回調(diào)方式:
function(err, res) { // process the error and result }
這里的 callback 指的是帶有2個參數(shù)的函數(shù):"err"和 "res"。語義上講,非空的“err”相當(dāng)于程序異常;而空的“err”相當(dāng)于可以正常返回結(jié)果“res”,無任何異常。
b)EventEmitter
事件模塊是 Node.js 內(nèi)置的對觀察者模式“發(fā)布/訂閱”(publish/subscribe)的實現(xiàn),通過EventEmitter屬性,提供了一個構(gòu)造函數(shù)。該構(gòu)造函數(shù)的實例具有 on 方法,可以用來監(jiān)聽指定事件,并觸發(fā)回調(diào)函數(shù)。任意對象都可以發(fā)布指定事件,被 EventEmitter 實例的 on 方法監(jiān)聽到。
在node 6之后,可以直接使用require("events")類
var EventEmitter = require("events") var util = require("util") var MyEmitter = function () { } util.inherits(MyEmitter, EventEmitter) const myEmitter = new MyEmitter(); myEmitter.on("event", (a, b) => { console.log(a, b, this); // Prints: a b {} }); myEmitter.emit("event", "a", "b");
和jquery、vue里的Event是非常類似的。而且前端自己也有EventEmitter。
c)如何更好的查Node.js文檔
API是應(yīng)用程序接口Application Programming Interface的簡稱。從Node.js異步原理,我們可以知道,核心在于 Node.js SDK 中API調(diào)用,然后交由EventLoop(Libuv)去執(zhí)行,所以我們一定要熟悉Node.js的API操作。
Node.js的API都是異步的,同步的函數(shù)是奢求,要查API文檔,在高并發(fā)場景下慎用。
筆者推薦使用 Dash 或 Zeal 查看離線文檔,經(jīng)常查看離線文檔,對Api理解會深入很多,比IDE輔助要好,可以有效避免離開IDE就不會寫代碼的窘境。
3)中流砥柱:Promise回調(diào)地獄
Node.js 因為采用了錯誤優(yōu)先的回調(diào)風(fēng)格寫法,導(dǎo)致sdk里導(dǎo)出都是回調(diào)函數(shù)。如果組合調(diào)用的話,就會特別痛苦,經(jīng)常會出現(xiàn)回調(diào)里嵌套回調(diào)的問題,大家都非常厭煩這種寫法,稱之為Callback Hell,即回調(diào)地獄。一個經(jīng)典的例子來自著名的Promise模塊q文檔里。
step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });
這里只是做4步,嵌套了4層回調(diào),如果更多步驟呢?很多新手淺嘗輒止,到這兒就望而卻步,粉轉(zhuǎn)黑。這明顯不夠成熟,最起碼你要看看它的應(yīng)對解決方案吧!
Node.js 約定所有Api都采用錯誤優(yōu)先的回調(diào)方式,這部分場景都是大家直接調(diào)用接口,無太多變化。而Promise是對回調(diào)地獄的思考,或者說是改良方案。目前使用非常普遍,可以說是在async函數(shù)普及之前唯一一個通用性規(guī)范,甚至 Node.js 社區(qū)都在考慮 Promise 化,可見其影響之大。
Promise最早也是在commonjs社區(qū)提出來的,當(dāng)時提出了很多規(guī)范。比較接受的是promise/A規(guī)范。后來人們在這個基礎(chǔ)上,提出了promise/A+規(guī)范,也就是實際上現(xiàn)在的業(yè)內(nèi)推行的規(guī)范。ES6 也是采用的這種規(guī)范。
Promise意味著[許愿|承諾]一個還沒有完成的操作,但在未來會完成的。與Promise最主要的交互方法是通過將函數(shù)傳入它的then方法從而獲取得Promise最終的值或Promise最終最拒絕(reject)的原因。要點有三個:
遞歸,每個異步操作返回的都是promise對象
狀態(tài)機(jī):三種狀態(tài)轉(zhuǎn)換,只在promise對象內(nèi)部可以控制,外部不能改變狀態(tài)
全局異常處理
1)定義
var promise = new Promise(function(resolve, reject) { // do a thing, possibly async, then… if (/* everything turned out fine */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } });
每個Promise定義都是一樣的,在構(gòu)造函數(shù)里傳入一個匿名函數(shù),參數(shù)是resolve和reject,分別代表成功和失敗時候的處理。
2)調(diào)用
promise.then(function(text){ console.log(text)// Stuff worked! return Promise.reject(new Error("我是故意的")) }).catch(function(err){ console.log(err) })
它的主要交互方式是通過then函數(shù),如果Promise成功執(zhí)行resolve了,那么它就會將resolve的值傳給最近的then函數(shù),作為它的then函數(shù)的參數(shù)。如果出錯reject,那就交給catch來捕獲異常就好了。
Promise 的最大優(yōu)勢是標(biāo)準(zhǔn)化,各類異步工具庫都按照統(tǒng)一規(guī)范實現(xiàn),即使是async函數(shù)也可以無縫集成。所以用 Promise 封裝 API 通用性強(qiáng),用起來簡單,學(xué)習(xí)成本低。在async函數(shù)普及之前,絕大部分應(yīng)用都是采用Promise來做異步流程控制的,所以掌握Promise是Node.js學(xué)習(xí)過程中必須要掌握的重中之重。
Bluebird是 Node.js 世界里性能最好的Promise/a+規(guī)范的實現(xiàn)模塊,Api非常齊全,功能強(qiáng)大,是原生Promise外的不二選擇。
好處如下:
避免Node.js內(nèi)置Promise實現(xiàn) 問題,使用與所有版本兼容
避免Node.js 4曾經(jīng)出現(xiàn)的內(nèi)存泄露問題
內(nèi)置更多擴(kuò)展,timeout、 promisifyAll等,對Promise/A+規(guī)范提供了強(qiáng)有力的補充
限于時間關(guān)系,這里就不一一列舉了,還是那句話,在學(xué)習(xí)Node.js過程中,對于Promise了解多深入都不過分。
推薦學(xué)習(xí)資料
Node.js最新技術(shù)棧之Promise篇 https://cnodejs.org/topic/560...
理解 Promise 的工作原理 https://cnodejs.org/topic/569...
Promise 迷你書 http://liubin.github.io/promi...
4)終極解決方案:Async/AwaitAsync/Await是異步操作的終極解決方案,Koa 2在node 7.6發(fā)布之后,立馬發(fā)布了正式版本,并且推薦使用async函數(shù)來編寫Koa中間件。
這里給出一段Koa 2應(yīng)用里的一段代碼
exports.list = async (ctx, next) => { try { let students = await Student.getAllAsync(); await ctx.render("students/index", { students : students }) } catch (err) { return ctx.api_error(err); } };
它做了3件事兒
通過await Student.getAllAsync();來獲取所有的students信息。
通過await ctx.render渲染頁面
由于是同步代碼,使用try/catch做的異常處理
是不是非常簡單,現(xiàn)在Eggjs里也都是這樣同步的代碼。
4.1 正常寫法
const pkgConf = require("pkg-conf"); async function main(){ const config = await pkgConf("unicorn"); console.log(config.rainbow); //=> true } main();
{{BANNED}}寫法
const pkgConf = require("pkg-conf"); (async () => { const config = await pkgConf("unicorn"); console.log(config.rainbow); //=> true })();
4.2 await + Promise
const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); async function main(){ const contents = await fs.readFileAsync("myfile.js", "utf8") console.log(contents); } main();
4.3 await + co + generator
const co = require("co"); const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); async function main(){ const contents = co(function* () { var result = yield fs.readFileAsync("myfile.js", "utf8") return result; }) console.log(contents); } main();
要點
co的返回值是promise,所以await可以直接接co。
co的參數(shù)是genrator
在generator里可以使用yield,而yield后面接的有5種可能,故而把這些可以yield接的方式成為yieldable,即可以yield接的。
Promises
Thunks (functions)
array (parallel execution)
objects (parallel execution)
Generators 和 GeneratorFunctions
由上面3中基本用法可以推出Async函數(shù)要點如下:
Async函數(shù)語義上非常好
Async不需要執(zhí)行器,它本身具備執(zhí)行能力,不像Generator需要co模塊
Async函數(shù)的異常處理采用try/catch和Promise的錯誤處理,非常強(qiáng)大
Await接Promise,Promise自身就足夠應(yīng)對所有流程了,包括async函數(shù)沒有純并行處理機(jī)制,也可以采用Promise里的all和race來補齊
Await釋放Promise的組合能力,外加co和Promise的then,幾乎沒有不支持的場景
綜上所述
Async函數(shù)是趨勢,如果Chrome 52. v8 5.1已經(jīng)支持Async函數(shù)(https://github.com/nodejs/CTC...,Node.js支持還會遠(yuǎn)么?
Async和Generator函數(shù)里都支持promise,所以promise是必須會的。
Generator和yield異常強(qiáng)大,不過不會成為主流,所以學(xué)會基本用法和promise就好了,沒必要所有的都必須會。
co作為Generator執(zhí)行器是不錯的,它更好的是當(dāng)做Promise 包裝器,通過Generator支持yieldable,最后返回Promise,是不是有點無恥?
小結(jié)
這部分共講了4個小點,都是極其直接的必須掌握的知識點。
1) 異步流程控制學(xué)習(xí)重點
2)Api寫法:Error-first Callback 和 EventEmitter
3)中流砥柱:Promise
4)終極解決方案:Async/Await
這里再提一下關(guān)于Node.js源碼閱讀問題,很多人api都還沒完熟練就去閱讀源碼,這是非常不贊成的,不帶著問題去讀源碼是比較容易迷失在大量代碼中的。效果并不好。
先用明白,然后再去閱讀Node.js源碼,然后探尋libuv并發(fā)機(jī)制。很多人買了樸大的《深入淺出Node.js》一書,看了之后還是不太會用,不是書寫的不好,而是步驟不對。
Node in action和了不起的Node.js是入門的絕好書籍,非常簡單,各個部分都講了,但不深入,看了之后,基本就能用起來了
當(dāng)你用了一段之后,你會對Node.js的運行機(jī)制好奇,為啥呢?這時候去讀樸大的《深入淺出Node.js》一書就能夠解惑。原因很簡單,九淺一深一書是偏向底層實現(xiàn)原理的書,從操作系統(tǒng),并發(fā)原理,node源碼層層解讀。如果是新手讀,難免會比較郁悶。
實踐類的可以看看雷宗民(老雷)和趙坤(nswbmw)寫的書
我一般給大家的推薦是把Node in action讀上5遍10遍,入門干活足夠了。剩下的就是反復(fù)實踐,多寫代碼和npm模塊就好。
目前所有的書籍幾乎都有點過時了,大部分都是Node.js v0.10左右的版本的,我得新書是基于Node.js 8版本的,預(yù)計2018年3月或4月出版。別催我,真沒法更快了。
目錄
01 Node.js初識
02 安裝與入門
03 更了不起的Node.js
04 更好的Node.js
05 Node.js是如何執(zhí)行的
06 模塊與核心
07 異步寫法與流程控制
08 下一代Web框架Koa入門
09 Koa的核心擴(kuò)展機(jī)制:中間件
10 HTTP協(xié)議必知必會
11 Koa練習(xí)
12 數(shù)據(jù)庫入門
13 數(shù)據(jù)庫進(jìn)階
14 視圖模板
15 Koa項目實戰(zhàn)
16 自己動手寫NPM模塊
17 Node.js企業(yè)級Web開發(fā)
18 構(gòu)建具有Node.js特色的微服務(wù)
19 讓Node.js跑的更穩(wěn)
20 讓Node.js跑的更快
博文視點的美女編輯在苦逼的整理中,預(yù)計出版在3月之后(不要催我,我也沒法說),20章,800頁+,定價預(yù)計在130+。
Web編程要點一般,后端開發(fā)指的是 Web 應(yīng)用開發(fā)中和視圖渲染無關(guān)的部分,主要是和數(shù)據(jù)庫交互為主的重業(yè)務(wù)型邏輯處理。但現(xiàn)在架構(gòu)升級后,Node.js 承擔(dān)了前后端分離重任之后,有了更多玩法。從帶視圖的傳統(tǒng)Web應(yīng)用和面向Api接口應(yīng)用,到通過 RPC 調(diào)用封裝對數(shù)據(jù)庫的操作,到提供前端 Api 代理和網(wǎng)關(guān),服務(wù)組裝等,統(tǒng)稱為后端開發(fā),不再是以往只有和數(shù)據(jù)庫打交道的部分才算后端。這樣,就可以讓前端工程師對開發(fā)過程可控,更好的進(jìn)行調(diào)優(yōu)和性能優(yōu)化。
對 Node.js 來說,一直沒有在后端取得其合理的占有率,原因是多方面的,暫列幾條。
1)利益分配,已有實現(xiàn)大多是Java或者其他語言,基本是沒法撼動的,重寫的成本是巨大的,另外,如果用Node寫了,那么那些寫Java的人怎么辦?搶人飯碗,這是要拼命的。
2)Node相對年輕,大家對Node的理解不夠,回調(diào)和異步流程控制略麻煩,很多架構(gòu)師都不愿意花時間去學(xué)習(xí)。盡管在Web應(yīng)用部分處理起來非常簡單高效,但在遇到問題時并不容易排查定位,對開發(fā)者水平要求略高。
3)開發(fā)者技能單一,很多是從前端轉(zhuǎn)過來的,對數(shù)據(jù)庫,架構(gòu)方面知識欠缺,對系統(tǒng)設(shè)計也知之不多,這是很危險的,有種麻桿打狼兩頭害怕的感覺。
4)Node在科普、培訓(xùn)、布道等方面做的并不好,國外使用的非常多,國內(nèi)卻很少人知道,不如某些語言做得好。
盡管如此,Node.js 還是盡人皆知,卷入各種是非風(fēng)口,也算是在大前端浪潮中大紅大紫。原因它的定位非常明確,補足以 JavaScript 為核心的全棧體系中服務(wù)器部分。開發(fā)也是人,能夠同時掌握并精通多門語言的人畢竟不多,而且程序員的美德是“懶”,能使用 JavaScript 一門語言完成所有事兒,為什么要學(xué)更多呢?
對于 Web 應(yīng)用大致分2種,帶視圖的傳統(tǒng)Web應(yīng)用和面向Api接口應(yīng)用,我們先看一下 Node.js Web 應(yīng)用開發(fā)框架的演進(jìn)時間線大致如下:
2010年 TJ Holowaychuk 寫的 Express
2011年 Derby.js 開始開發(fā),8月5日,WalmartLabs 的一位成員 Eran Hammer 提交了 Hapi 的第一次git記錄。Hapi 原本是 Postmile 的一部分,并且最開始是基于 Express 構(gòu)建的。后來它發(fā)展成自己自己的框架,
2012年1月21日,專注于 Rest api 的 Restify 發(fā)布1.0版本,同構(gòu)的 Meteor 開始投入開發(fā),最像Rails 的 Sails 也開始了開發(fā)
2013年 TJ Holowaychuk 開始玩 es6 generator,編寫 co 這個 Generator 執(zhí)行器,并開始了Koa 項目。2013 年下半年李成銀開始 ThinkJS,參考 ThinkPHP
2014年4月9日,Express 發(fā)布4.0,進(jìn)入4.x時代持續(xù)到今天,MEAN.js 開始隨著 MEAN 架構(gòu)的提出開始開發(fā),意圖大一統(tǒng),另外 Total.js 開始起步,最像PHP里 Laravel 或 Python 里的 Django 或 ASP.NET MVC的框架,代表著 Node.js 的成熟,開始從其他語言里的成熟框架借鑒
2015年8月22日,下一代 Web 框架 Koa 發(fā)布1.0,可以在Node.js v0.12下面,通過co 和 generator實現(xiàn)同步邏輯,那時候 co 還是基于 thunkfy 的,在2015年10月30日,ThinkJS發(fā)布了首個基于 Es2015+ 特性開發(fā)的 v2.0 版本
2016 年 09 月,螞蟻金服的 Eggjs,在 JSConf China 2016 上亮相并宣布開源
2017年2月,下一代Web框架 Koa 發(fā)布v2.0正式版
我們可以根據(jù)框架的特性進(jìn)行分類
框架名稱 | 特性 | 點評 |
---|---|---|
Express | 簡單、實用,路由中間件等五臟俱全 | 最著名的Web框架 |
Derby.js && Meteor | 同構(gòu) | 前后端都放到一起,模糊了開發(fā)便捷,看上去更簡單,實際上上對開發(fā)來說要求更高 |
Sails、Total | 面向其他語言,Ruby、PHP等 | 借鑒業(yè)界優(yōu)秀實現(xiàn),也是 Node.js 成熟的一個標(biāo)志 |
MEAN.js | 面向架構(gòu) | 類似于腳手架,又期望同構(gòu),結(jié)果只是蹭了熱點 |
Hapi和Restfy | 面向Api && 微服務(wù) | 移動互聯(lián)網(wǎng)時代Api的作用被放大,故而獨立分類。尤其是對于微服務(wù)開發(fā)更是利器 |
ThinkJS | 面向新特性 | 借鑒ThinkPHP,并慢慢走出自己的一條路,對于Async函數(shù)等新特性支持,無出其右,新版v3.0是基于Koa v2.0的作為內(nèi)核的 |
Koa | 專注于異步流程改進(jìn) | 下一代Web框架 |
Egg | 基于Koa,在開發(fā)上有極大便利 | 企業(yè)級Web開發(fā)框架 |
對于框架選型
業(yè)務(wù)場景、特點,不必為了什么而什么,避免本末倒置
自身團(tuán)隊能力、喜好,有時候技術(shù)選型決定團(tuán)隊氛圍的,需要平衡激進(jìn)與穩(wěn)定
出現(xiàn)問題的時候,有人能夠做到源碼級定制。Node.js 已經(jīng)有8年歷史,但模塊完善程度良莠不齊,如果不慎踩到一個坑里,需要團(tuán)隊在無外力的情況能夠搞定,否則會影響進(jìn)度
Tips:個人學(xué)習(xí)求新,企業(yè)架構(gòu)求穩(wěn),無非喜好與場景而已
Node.js 本來就為了做后端而設(shè)計的,這里我們再看看利益問題。Node.js 向后端延伸,必然會觸動后端開發(fā)的利益。那么 Proxy 層的事兒,前后端矛盾的交界處,后端不想變,前端又求變,那么長此以往,Api接口會變得越來越惡心。后端是愿意把Api的事兒叫前端的,對后端來說,只要你不動我的數(shù)據(jù)庫和服務(wù)就可以。
但是 Node.js 能不能做這部分呢?答案是能的,這個是和 Java、PHP 類似的,一般是和數(shù)據(jù)庫連接到一起,處理帶有業(yè)務(wù)邏輯的。目前國內(nèi)大部分都是以 Java、PHP 等為主,所以要想吃到這部分并不容易。
小公司,創(chuàng)業(yè)公司,新孵化的項目更傾向于 Node.js ,簡單,快速,高效
微服務(wù)架構(gòu)下的某些服務(wù),使用 Node.js 開發(fā),是比較合理的
國內(nèi)這部分一直沒有做的很好,所以 Node.js 在大公司還沒有很好的被應(yīng)用,安全問題、生態(tài)問題、歷史遺留問題等,還有很多人對 Node.js 的誤解。
單線程很脆弱,這是事實,但單線程不等于不能多核并發(fā),而且你還有集群呢
運維,其實很簡單,比其他語言之簡單,日志采集、監(jiān)控也非常簡單
模塊穩(wěn)定性,對于 MongoDB、MySQL、Redis 等還是相當(dāng)不錯,但其他的數(shù)據(jù)庫支持可能沒那么好。
安全問題是個偽命題,所有框架面臨的都是一樣的。
這些對于提供Api服務(wù)來說已經(jīng)足夠了,本書后面有大量篇幅講如何使用 Koa 框架來構(gòu)建Api服務(wù)。
Web編程核心
異步流程控制(前面講過了)
基本框架 Koa或Express,新手推薦Express,畢竟資料多,上手更容易。如果有一定經(jīng)驗,推薦Koa,其實這些都是為了了解Web編程原理,尤其是中間件機(jī)制理解。
數(shù)據(jù)庫 mongodb或mysql都行,mongoose和Sequelize、bookshelf,TypeOrm等都非常不錯。對于事物,不是Node.js的鍋,是你選的數(shù)據(jù)庫的問題。另外一些偏門,想node連sqlserver等估計還不成熟,我是不會這樣用的。
模板引擎, ejs,jade,nunjucks。理解原理最好。尤其是extend,include等高級用法,理解布局,復(fù)用的好處。其實前后端思路都是一樣的。
迷茫時學(xué)習(xí)Node.js最好的方法Node.js 編寫的包管理器 npm 已成為開源包管理了領(lǐng)域最好的生態(tài),直接到2017年10月份,有模塊超過47萬,每周下載量超過32億次,每個月有超過700萬開發(fā)者使用npm。現(xiàn)在早已經(jīng)超過60萬個模塊了。
這里就不一一舉例了,給出一個迷茫時學(xué)習(xí)Node.js最好的方法吧!
某天,我在3w咖啡整理書稿,然后小弟梁過來了,聊聊他的現(xiàn)狀,一副很不好的樣子,在天津我曾帶過他大半年,總不能不管,我給他的建議是:“每天看10個npm模塊”
對于學(xué)習(xí)Node.js迷茫的人來說,這是最好的方式,當(dāng)你不知道如何做的時候,就要向前(錢)看,你要知道積累哪些技能對以后有好處。對于學(xué)習(xí)Node.js必經(jīng)之路,一定是要掌握很多模塊用法,并從中汲取技巧、思路、設(shè)計思想的。與其不知道學(xué)什么,為什么不每天積累幾個技巧呢?
推薦一個repo即 https://github.com/parro-it/a... 小型庫集合,一天看十個不是夢!
更多討論 https://zhuanlan.zhihu.com/p/...
非科班出身如何Node.js有朋友提問
狼叔,關(guān)注你和cnode很久了,最近有點迷茫,想請你指點下。 我的情況是這樣的,非科班出身,從事前端工作4年,公司使用的技術(shù)棧是vue2、vue-router、vuex、webpack,目前的能力處理工作還是比較輕松,但是也很明確自己有很多不足,只是對于如何提升比較迷茫。 不足: 1、非科班出身,計算機(jī)基礎(chǔ)薄弱 2、對當(dāng)前使用的技術(shù)了解不夠深入,很多東西只停留在會用的層面 3、對服務(wù)端了解較少,想學(xué)node,卻不知道如何系統(tǒng)的學(xué)習(xí)
解答困惑:
1、計算機(jī)基礎(chǔ)薄弱該如何完善自己的知識體系?
答:追逐長尾,所見所聞不懂的都去學(xué)就好啦。我是這樣過來的,頭幾年每天14個小時+,很累,不過效果還可以。os,算法,數(shù)據(jù)結(jié)構(gòu),設(shè)計模式,編譯原理,基本也就這些重點。做到每天都有進(jìn)步就好,別貪多求快。數(shù)學(xué)和英文當(dāng)然也是越狠越好的!
2、如何在技術(shù)上做更深入的探索?
答:技術(shù)人只關(guān)注技術(shù),想法創(chuàng)意通常比較少。最簡單的辦法就是抓自己的癢,比我大學(xué)時和朋友們翻譯過grails文檔,所以對翻譯有情節(jié)。為了翻譯,我用node寫了無數(shù)工具嘗試,反復(fù)對比各種翻譯工具,理解它們背后的設(shè)計。包括markdown里嵌html標(biāo)簽標(biāo)識中英文,然后gulp編譯成獨立文檔。甚至一度想上線賣服務(wù)。這種折騰真的很爽,甚至耽誤了不少翻譯。有時要警惕長尾,不要忘了自己的初衷
3、如何系統(tǒng)的學(xué)習(xí)node?
答:階段
1/要會用,能完成工作任務(wù)
2/寫點提高效率的工具
3/參與開源項目,甚至是node源碼
應(yīng)對方法
1/《node in action》看五遍,然后就去寫吧,別管代碼質(zhì)量如何,能寫敢寫
2/多用些模塊,理解它們,如果有機(jī)會就自己寫一下,萬一有很多人用你,我小弟寫過一個地區(qū)選擇加載的json數(shù)據(jù),star數(shù)不少呢
3/給別人貢獻(xiàn)代碼,要去學(xué)別人的習(xí)慣,網(wǎng)上有g(shù)it標(biāo)準(zhǔn)工作流和提pr方法,你要做的是精研該模塊代碼,關(guān)注issue,其他就是等機(jī)會。另外樸靈的深入淺出多讀幾遍,試著讀node源碼,你的理解會更好。推薦看看我寫的《通過開源項目去學(xué)習(xí)》https://github.com/i5ting/Stu...
4/跳出node范圍,重新審視node的應(yīng)用場景,對未來你的技術(shù)選項和決策大有裨益
2.1 Node 用途那么多,我該從哪里學(xué)起?
答:如果有機(jī)會就直接上Web應(yīng)用,如果沒有機(jī)會就從前端構(gòu)建,工具等方面開始做,慢慢引入更潮更酷的前端技術(shù),自然就把Node引入進(jìn)來了。不要急。
2.2 Node Web 框架那么多,我該怎么選?
答:初學(xué)者推薦Express,如果有一定經(jīng)驗,推薦Koa。當(dāng)然真正項目里還是推薦Eggjs和Thinkjs這樣的框架。
2.3 關(guān)于 Node 的書幾乎都過時了,我該買哪本?
答:
1)Node in action和了不起的Node.js是入門的絕好書籍,非常簡單,各個部分都講了,但不深入,看了之后,基本就能用起來了
2)當(dāng)你用了一段之后,你會對Node.js的運行機(jī)制好奇,為啥呢?這時候去讀樸大的《深入淺出Node.js》一書就能夠解惑。原因很簡單,九淺一深一書是偏向底層實現(xiàn)原理的書,從操作系統(tǒng),并發(fā)原理,node源碼層層解讀。如果是新手讀,難免會比較郁悶。
3)實踐類的可以看看雷宗民(老雷)和趙坤(nswbmw)寫的書
如果你不著急,也可以等我的那本《更了不起的Node.js》,時間待定。
Part 3延伸:大前端變化那么快,如何才能做到每日精進(jìn)?有朋友問現(xiàn)在Android開發(fā)和web前端開發(fā)哪個前景更好?我的回答是明顯是前端更好,看一下移動端發(fā)展過程
native < hybrid < rn/weex < h5
目前rn和weex的開發(fā)逐漸變得主流,組件化寫法已經(jīng)由前端主導(dǎo)了。以前ios和android程序員占比很高,但現(xiàn)在就留1到2個寫插件,真是差別很大。
Web開發(fā)對移動端的沖擊非常大。當(dāng)然現(xiàn)在Web技術(shù)也開發(fā)PC client了,比如vscode是通過electron打包的,效果還是相當(dāng)不錯的。
前端可以說是最近幾年開發(fā)里最火的部分,原因很多,最主要是開發(fā)方式的變更,以今時今日的眼光來看,稱之為現(xiàn)代Web開發(fā)是不為過的。
先給出現(xiàn)代Web開發(fā)的概覽圖
每次演講我會都問大家是不是前端,回答“是”的人非常多,我會開玩笑的恭喜大家:“現(xiàn)在的前端就是錢端”,確實,現(xiàn)在前端發(fā)展異常的快,而且沒有趨向于類比java里ssh框架的那種穩(wěn)定,所以未來很長一段時間,還會增長,持續(xù)混亂,這對前端來說是把雙刃劍,一方面有很強(qiáng)的壓迫感,不學(xué)習(xí)就跟不上時代,另一方它也是機(jī)遇,能夠帶給更多機(jī)會,包括money。
大家都疑惑的一個問題是如何在這樣巨變的時代能夠通過學(xué)習(xí)來應(yīng)變,我可以很負(fù)責(zé)的告訴大家,沒有捷徑,但通過掌握 Node.js 能夠讓你降低這個學(xué)習(xí)曲線而已,畢竟Node.js是大前端的基礎(chǔ)設(shè)施。大家可以看一下,前端的開發(fā)過程,模塊化,構(gòu)建,輔助工具,調(diào)優(yōu),架構(gòu)調(diào)整,可以說Node.js是無處不在的。
其實,輔助大前端開發(fā)只是Node.js的一個非常無心插柳的衍生功能,通過掌握Node.js能夠讓你能做的更多、獲得的更多,甚至可以說有更多自我實現(xiàn)的快樂,這也是我那本書書名字里“更了不起的”要去闡述的內(nèi)容。
綜上種種,就是我一直提倡以 JavaScript 語言為中心的 Node全棧 概念的緣由,JavaScript 覆蓋所有前端,Node.js 擅長做 I/O 密集型的后端,外加輔助開發(fā)的各種基礎(chǔ)設(shè)施,無疑是工作、學(xué)習(xí)和成為快速掌握全棧技術(shù)最好的途徑。你會的越多,你能做的就更多,你的人生也將會有不一樣的精彩篇章。
全棧核心
后端不會的 UI(界面相關(guān))
前端不會的 DB(業(yè)務(wù)相關(guān))
只要打通這2個要點,其他就比較容易了。最怕的是哪樣都接觸點,然后就號稱自己是全棧,建議大家不要這樣做,這就好比在簡歷里寫精通一樣,基本上都會被問到尷尬。全棧是一種信仰,不是拿來吹牛逼的,而可以解決更多問題,讓自己的知識體系不留空白,享受自我實現(xiàn)的極致快樂。
我的全棧之路想問一下狼叔最近的業(yè)務(wù)一直都是簡單的用express搭一個后端服務(wù),沒有其他更加深入node的業(yè)務(wù)了,這種時候應(yīng)該如何自己給自己創(chuàng)應(yīng)用場景呢
沒有目標(biāo)就向錢看,有目標(biāo)就向前看
從 java 開始,蹭課,背著機(jī)箱到深圳,3個月胖20斤
堅持翻譯英文文檔,看 《Thinking in Java》
畢業(yè)后開始 bi,整理 bi 文檔
學(xué)長明林清,傳授 jQuery,愿意學(xué),別人就更愿意分析
接手《內(nèi)蒙廣電數(shù)據(jù)分析與科學(xué)決策系統(tǒng)》,打通前、后端
廣東聯(lián)通,自己造輪子,寫 jQuery 插件,DRY
做云計算,學(xué)習(xí) AIX,寫有《凌云志》
分手、離職,去做 iOS,從 cordova 開始搞 H5,研究各種移動端框架,自己寫框架,轉(zhuǎn)原生
面試也是學(xué)習(xí)的利器,輕松進(jìn)新浪
總結(jié)了大量 iOS 經(jīng)驗,想寫書,結(jié)果寫了一堆寫書的工具
既然無法逃避,就熱愛它,最后變成興趣
去網(wǎng)秦做技術(shù)總監(jiān),做首席,管架構(gòu),帶人,寫開源項目
創(chuàng)業(yè),當(dāng) CTO,結(jié)婚,做公眾號運營,寫書,最苦的時候沒錢吃飯,又不能找媳婦要,只能在 StuQ 上講點課
加入去哪兒網(wǎng),任職前端架構(gòu)師
加入阿里巴巴,前端技術(shù)專家
人生不只有代碼,但它能讓我快樂,終生受益
也曾懵懂,也曾迷茫,但我這人比較傻,一直信奉:“一次只做1件事兒,盡力做到極致”,短時間看這是比較傻的,但一旦你堅持下去,你就會發(fā)現(xiàn)技術(shù)其實是門手藝,厚積薄發(fā)。
我沒辦法說自己最擅長什么,但在什么場景下用什么技術(shù)是我擅長的。或者說,應(yīng)變是我最大的本事。很多框架,新技術(shù)我都沒見過,用過,但花一點點過一下,就能拿已有的知識快速的理解它,這其實是長期學(xué)習(xí)的好處。
現(xiàn)在越來越忙,寫代碼的時間越來越少,技術(shù)又越發(fā)展越快,我能做好的就是每日精進(jìn),仗著這點已有的知識儲備跟年輕人比賽。我不覺得累,相反我很享受這種感覺,沒有被時代淘汰,是一件多么幸福的事兒。
從后端轉(zhuǎn)做后端的人
對數(shù)據(jù)庫是比較熟悉,無論 mongodb,還是 mysql、postgres
對前端理解比較弱,會基本的 html,css,模板引擎等比較熟悉
4階段循序漸進(jìn),build 與工具齊飛
前端開發(fā)4階段,我的感覺是按照順序,循序漸進(jìn)就好。
從前端轉(zhuǎn)從前端往后端轉(zhuǎn),api 接口非常容易學(xué)會,像 express、koa 這類框架大部分人一周就能學(xué)會,最難的是對 db、er 模型的理解,說直白點,還是業(yè)務(wù)需求落地的理解
我們來想想一般的前端有什么技能?
html
css(兼容瀏覽器)
js 會點(可能更多的是會點 jquery)
ps 切圖
firebug 和 chrome debuger 會的人都不太多
用過幾個框架,大部分人是僅僅會用
英語一般
svn/git 會一點
那么他們?nèi)绻朐谇岸祟I(lǐng)域做的更深有哪些難點呢?
基礎(chǔ):oo,dp,命令,shell,構(gòu)建等
編程思想上的理解(mvc、ioc,規(guī)約等)
區(qū)分概念
外圍驗收,如 H5 和 hybird 等
追趕趨勢,如何學(xué)習(xí)新東西
以上皆是痛點,所以比較好的辦法應(yīng)該是這樣的。
玩轉(zhuǎn) npm、gulp 這樣的前端工具類(此時還是前端)
使用 node 做前后端分離(此時還是前端)
express、koa 這類框架
jade、ejs 等模板引擎
nginx
玩轉(zhuǎn)【后端】異步流程處理(promise/es6的(generator|yield)/es7(async|await))
玩轉(zhuǎn)【后端】mongodb、mysql 對應(yīng)的 Node 模塊
從我們的經(jīng)驗看,這樣是比較靠譜的。先做最簡單前后端分離,里面沒有任何和db相關(guān),前端可以非常容易的學(xué)會,基本2周就已經(jīng)非常熟練了。一般半年后,讓他們接觸【異步流程處理】和【數(shù)據(jù)庫】相關(guān)內(nèi)容,學(xué)習(xí)后端代碼,就可以全棧了。
從移動端轉(zhuǎn)看一下移動端發(fā)展過程
native < hybrid < rn/weex < h5
目前rn和weex的開發(fā)逐漸變得主流,組件化寫法已經(jīng)由前端主導(dǎo)了。以前ios和android程序員占比很高,但現(xiàn)在就留1到2個寫插件,真是差別很大。狼叔一直固執(zhí)的以為未來是h5的。
現(xiàn)在的 Native 開發(fā)是姥姥不疼舅舅不愛,非常尷尬,很明顯連培訓(xùn)出的人就業(yè)不要工資混經(jīng)驗就
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/115875.html
摘要:感謝大神的免費的計算機(jī)編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡介現(xiàn)在,越來越多的科技公司和開發(fā)者開始使用開發(fā)各種應(yīng)用。 說明 2017-12-14 我發(fā)了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當(dāng)不錯的,甚至連著名的hax賀老都很認(rèn)同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
摘要:開局一張圖,故事全靠編是啥變色龍又是啥自從有小程序以來,小程序的第三方框架便孕育而生,從原始時代的只基于微信小程序多如今多端統(tǒng)一開發(fā)框架,可以說前端技術(shù)從年到年又發(fā)生了天翻地覆的變化。 Created 2019-4-6 21:57:17 by huqi Updated 2019-4-7 22:54:55 by huqi showImg(https://segmentfault.c...
摘要:業(yè)務(wù)開發(fā)中的調(diào)試方法總結(jié)這段時間,接觸了單元測試,同時業(yè)務(wù)中遇到了一些需要排錯調(diào)試的情況,就把自己的經(jīng)驗做個小結(jié)。但是如果你的業(yè)務(wù)經(jīng)常變化,但是變化的部分并不會影響單元測試,那這種情況下的單元測試性價比就很高。 業(yè)務(wù)開發(fā)中的調(diào)試方法總結(jié) 這段時間,接觸了單元測試,同時業(yè)務(wù)中遇到了一些需要排錯調(diào)試的情況,就把自己的經(jīng)驗做個小結(jié)。 3種調(diào)試方法 狼叔說,常見的三種調(diào)試的境界 初級: 打l...
摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
閱讀 1611·2021-10-25 09:44
閱讀 2994·2021-09-04 16:48
閱讀 1667·2019-08-30 15:44
閱讀 2550·2019-08-30 15:44
閱讀 1774·2019-08-30 15:44
閱讀 2874·2019-08-30 14:14
閱讀 3008·2019-08-30 13:00
閱讀 2204·2019-08-30 11:09