noder eyes for frontend guys

48
Noder eyes for frontend guys by Fillano

Upload: hsu-ping-feng

Post on 23-Jun-2015

567 views

Category:

Technology


2 download

DESCRIPTION

my s

TRANSCRIPT

Page 1: Noder eyes for frontend guys

Noder eyes for frontend guysby Fillano

Page 2: Noder eyes for frontend guys

先說聲抱歉 Orz

Page 3: Noder eyes for frontend guys

關於題目

● 源自 "Queer eyes for straight guys"● 澄清一下

○ 寫node.js不表示比較厲害,只是希望能讓熟悉瀏覽器的Javascript coder可以知道進入node.js需要的知識跟常見的難點

○ I'm not queer, but I do have some friends.● 另外...

Page 4: Noder eyes for frontend guys

這個投影片不會講到

● node.js的教學● 各個module怎麼用的詳細說明● 怎麼做出XXX(忍不住還是會...)

Page 5: Noder eyes for frontend guys

這個投影片會專注在

● 寫node.js程式需要的關鍵知識● 如何開始寫node.js程式的一些提示

Page 6: Noder eyes for frontend guys

開始吧...

Page 7: Noder eyes for frontend guys

window物件在哪?

● 可能情境:裝完node.js,進入shell,不知道有什麼可以使用

● 在瀏覽器中,一切都可以從window物件開始,那在node.js中,有什麼相同的東西?

● 這要從Javascript的基本特性談起...

Page 8: Noder eyes for frontend guys

Javascrip基本:依賴於host環境

● 核心物件之外,所有能用的功能,都放在Global中

● 在browser中,Global就是window物件● 在node.js中,Global就是global物件● 檢查一下:test001.js● 有三個同名的物件,實際上都是global物件● 檢查一下:test001a.js● 但是呢...

Page 9: Noder eyes for frontend guys

node.js對於Global做了一點調整

● 操作global物件,可以反應在global scope● 但是直接操作global scope,並不會影響到

global物件● 這跟在瀏覽器環境中的行為不太一樣● 檢查一下:test001b.js● 在瀏覽器中:test794.html● 那麼...

Page 10: Noder eyes for frontend guys

global物件到底能做什麼

● 只有:○ 操作TypedArray需要的相關物件

○ process物件

○ Buffer constructor○ setTimeout/setInterval相關函數

○ console物件,用來作stdio

● 檢查一下:test002.js● 接下來咧?好像沒啥東西...

Page 11: Noder eyes for frontend guys

那其他功能怎麼辦?

● 其實還有require這個核心函數,可以用它來載入模組

● 檢查一下:test003.js● 後面還會詳細解釋一下模組的運作● 了解了global物件,再看一個偶爾會有人問的

問題...

Page 12: Noder eyes for frontend guys

我可以使用jQuery嗎?

● 通常我會想:別傻了,你在寫伺服器程式● 不是沒有解(JSDom...)● 但除了做蜘蛛,通常不會用到● 下一個問題也有不少人問...就是...

Page 13: Noder eyes for frontend guys

什麼?單一執行緒?

● 用關鍵字應該可以找到不少這方面的討論● 不過這個問題說來話長...下一頁繼續

Page 15: Noder eyes for frontend guys

歸納起來,就是

● 不論是非同步的事件、timer、UI parsing等● browser所載入的每個網頁,你寫的Javascript

都是在一個thread裡面跑● 在node.js也是這樣

Page 16: Noder eyes for frontend guys

所以,Javascript到底怎麼跑?

● 可以把Javascript的執行過程想像成a. 執行top most的程式碼(主要是global scope,以及此時

執行的函數)

b. 進入event loop

c. 一有有事件程式放進event queue,event loop就會取出來執行

■ 由timer觸發的,不會在時間到之前執行,但是可能會更慢

■ 由event觸發的,就是儘快執行

● node.js的特異功能a. process.nextTick():會盡量排在event queue前面讓他

可以先執行,而不是從後面填入

Page 17: Noder eyes for frontend guys

這不是例外,但其實你有機會碰到別的

thread

● 在網頁端:○ frame/iframe○ web worker

● 在node.js○ sub process○ threads-a-gogo模組(這是真的thread,只能透過

message溝通,目前還無法做什麼事)

● 測試:test644.html(WebWorker的global跟網頁中完全不同)

Page 18: Noder eyes for frontend guys

在底層,還有更多東西必須使用thread

● 寫Javascript不會直接接觸...但是在機制上○ 瀏覽器:XMLHttpRequest底層

■ onreadystatuschange● 網路I/O在另外一個thread跑,根據處理的狀態

變化,才把叫onreadystatuschange事件處理函數塞進event queue

○ node.js:I/O底層■ fs.read■ fs.write

● 所以,single thread是對Javascript Coder必須的概念,但是引擎實作並不是這樣

Page 19: Noder eyes for frontend guys

single thread的方便性

● 同一時間不會執行兩段程式○ 沒有race

○ 不需要lock

○ 寫非同步比較簡單

● 但是我們寫的code可能會...

Page 20: Noder eyes for frontend guys

程式寫壞了,就全部塞住

● 這不論在瀏覽器或伺服器端都一樣,某個

function中的程式卡住(ex. 無窮迴圈),就全部卡住了

● 在node.js,沒有catch到的exception,會讓程式

exit,但是沒exception照樣可能卡著(ex. 無窮迴圈)

● 就算沒卡住...

Page 21: Noder eyes for frontend guys

程式寫不好,伺服器反應就全部變慢

● 沒那麼糟,但是不優● 但是有時...就是得做花時間的事情● 有什麼辦法?

Page 22: Noder eyes for frontend guys

所以有些事可以慢點做

● 程式打死結(ex. 無窮迴圈),是一定沒救● 但是某個事件處理程式跑太久,還是會阻礙別

人● 在Browser跟node.js解法都一樣,make it async

by do something later● 使用setTimeout()/setInterval()● 使用process.nextTick()● 在single thread中跑的程式,就像DOS時代的合

作式多工...

Page 23: Noder eyes for frontend guys

不過async會讓邏輯更複雜XD

● 這在node.js常碰到,建議要習慣用async的邏輯來思考事情

● 有一些解決方法,容後再述● 另外的問題是,程式都在同一個thread跑喔,

可是...

Page 24: Noder eyes for frontend guys

node.js在伺服器端執行耶!?

● 這不是瀏覽器...● 如果只有單核心,再多thread也只會用到一個

cpu核心的資源,就沒差● 可是,我的伺服器有四路八核心cpu,總共有32

核心,但是node只會用到一個...● 解法在v0.6.x之後出現...容後再敘● 有了一些基本認識,可以開始coding了...不過一

頭鑽進去會發現...

Page 25: Noder eyes for frontend guys

hello world...然後我要做什麼?

● hello world總是很美好XD● 但是很遺憾...http模組幫你做的事情不多● 因為他沒做,所以你需要基本的http知識

○ http request○ http headers○ session相關

■ cookie header■ setcookie header■ 怎麼做出伺服器端session

○ MIME○ ...

● 另外,沒人幫你map靜態檔案● ...

Page 26: Noder eyes for frontend guys

對於新手來說,單靠node.js核心模組是

不可能寫出功能完整的伺服器Orz

● 想像一下,你要用幾個基本的物件做出apache httpd伺服器,工程很大的...

● 我自己為例,之前參加ITHelp鐵人賽,花了一個月還只有架構

● 所以要快的話,還是得先靠第三方模組○ Connect middleware可以做基礎○ 一些Web Framework

■ Express■ others

● Meteor● Mojito● ...

● 那要怎樣找模組?...

Page 27: Noder eyes for frontend guys

模組管理工具:NPM

● NPM(Node Package Manager)● 原本是第三方的解決方案● 目前已納入node.js的binary distribution中● 怎麼找模組?

○ `npm search KEYWORD` (常會用完記憶體)

○ http://search.npmjs.org/ (官網,但是很慢)

○ https://github.com/joyent/node/wiki/modules (這是分門別類的目

錄,但是更新可能比較慢)

○ nipster (很快,而且用評分排序)

Page 28: Noder eyes for frontend guys

● 之前測試過...test003.js可以看到一些線索● 模組預設搜尋路徑

○ 目前工作目錄下的node_modules目錄

○ require.main.paths陣列中的目錄

● npm list -g顯示的路徑加上node_modules○ 預設

■ UNIX: /usr/lib or /usr/local/lib■ Windows: %APPDATA\npm

● 用npm安裝/管理模組會使用的路徑○ 沒有加-g:目前路徑

○ 有加-g:npm list -g顯示的路徑

node怎麼找到模組

Page 29: Noder eyes for frontend guys

想使用global module

● 如果(不建議)希望可以直接使用● 需要設定NODE_PATH環境變數,指向npm list

-g使用的模組目錄 + node_modules

Page 30: Noder eyes for frontend guys

使用了模組...怎麼維護相依性?

● 我們使用npm,npm使用package.json檔● package.json(模組根目錄中)

○ 不管寫不寫模組,最好都知道裡面定義的各個欄位○ 跟執行相關

■ 定義模組的entry檔案■ 定義模組的相依性

● 許多node.js hosting service,都支援package.json,在deploy的過程中,會幫你把相依的模組裝好

● 參考:○ http://package.json.nodejitsu.com/○ npm help json

Page 31: Noder eyes for frontend guys

node.js的模組載入機制與注意事項

● require是同步執行的○ 呼叫require時,要等到模組載入完畢,才會執行下一行

程式

● module是在沙箱中跑的○ 所以,模組裡面沒有辦法動到主程式○ 主程式要用到的東西,全部都要export(module.exports

或exports)

● 執行過一次require後,模組就會被cache起來○ 所以,修改過的module,要重新啟動程式才會有作用

Page 32: Noder eyes for frontend guys

但是我希望程式可以在修改後不停機自

動apply耶...

● 最好讓host服務替你做,省功夫● 手動做的話,可以考慮使用cluster● 驗證一下:test005.js

○ 由於每個worker都是獨立的process,kill掉再重新執行,就會使用新的程式了

○ 缺點是:master無法更新...○ 仔細想一想:如果把worker內的程式寫成模組來載入,

然後master用fs.watch模組的目錄,然後每次deploy都更新這個模組...其實就類似hosting的做法了

Page 33: Noder eyes for frontend guys

但是,我需要AMD的話怎麼辦?

● 參考:require.js● 其實,你可以自己做● 例如:node-amd-loader● 重點:

○ node只提供了核心模組○ 沒人告訴你其他的不能自己做○ 忘記那些爭論吧(阿?有爭論?)

Page 34: Noder eyes for frontend guys

我需要物件導向嗎?

● node.js常用的作法:○ 使用util.inherits(),這是給constructor來用的喔○ 最常使用的地方:需要使用到事件機制,就要繼承

EventEmitter

● 其他...就任意...Javascript有多種作法● 參考一下良葛格的意見

○ 程式語言的特性本質(三)-從消弭重複性看封裝、繼承、多型

● 再來是另一個常被問到的問題...

Page 35: Noder eyes for frontend guys

有辦法避開callback地獄嗎?

● 這是無法避免的,請練習async的邏輯思考● 可以透過適當的調整來改善

○ 取代匿名函數callback(這是一個過程,這樣還可以方便單元測試)

■ 改用非匿名的函數

■ 進一步利用模組帶入這個函數

○ 利用flow control來管理函數,讓你可以控制數個函數

執行過程的關係,例如某幾個函數要順序執行、某幾個函數要平行執行等

Page 36: Noder eyes for frontend guys

有辦法避開非同步地獄嗎?

● 同樣難以避免● 而且,在執行上有時會碰到邏輯上的困難點● 解決方式如前述● 那麼...

Page 37: Noder eyes for frontend guys

什麼是flow control?

● 函數在Javascript是一等公民,所以可以用函數來處理函數

● 測試一下:test006.js○ 執行三個函數○ 全部執行完畢,才執行某個函數來處理結果

● 除了使用flow control,要能使用flow control的函數,通常要改寫成cps的形式

● cps (continuation passing style)○ 簡單地說就是傳入一個callback○ 在函數結束時(可能不只一處),呼叫這個callback,有

返回值時,需要把返回值傳給它

Page 38: Noder eyes for frontend guys

關於flow control的好文章

● Tim Caswell○ Control Flow in Node○ Control Flow in Node Part II○ Control Flow in Node Part III

● Mixu's tech blog○ Essential Node.js patterns and snippets○ 我的例子用這個改的,因為邏輯最簡單

● 一些模組○ https://github.com/creationix/step○ https://github.com/caolan/async○ https://github.com/laverdet/node-fibers

Page 39: Noder eyes for frontend guys

另外一個讓程式碼更有結構又乾淨的方

● CoffeeScript● ...我沒在用,我已經太習慣Javascript了XD● 早上有人講這個喔(高見龍 / 龍哥)● 另外一個寫伺服器會發現的,是關於...

Page 40: Noder eyes for frontend guys

gloal variables

● 以http server為例,每個request是一個事件● 要維護cross request的狀態(ex. session),用

global variable就可以做到(其實不一定,要看事件處理函數定義的位置)

● 不過當需要scale的時候,這個作法就會出問題(ex. cluster)

● 所以,共享的狀態,儘量用外部實現比較好(memcache, mongodb etc.)

● 好,終於要來看怎麼解決無法利用多核心cpu的...

Page 41: Noder eyes for frontend guys

cluster模組

● since v0.6.x● 解決single thread無法充分利用多核心的系統

優勢的問題● 使用多個sub process,共享同一個port● master/worker之間,透過message來溝通● 測試一下?(之前測過了XD)

Page 42: Noder eyes for frontend guys

cluster不是真的scaling

● 不要被cluster這個名字拐了● 真正要scaling,請使用reverse proxy,例如:

○ nginx○ node-proxy模組 (效能不如nginx)

● 基本上,不論使用怎樣的程式語言,大多數伺服器都可以這樣scale

● 另外,許多PAAS(node.js hosting)會提供方案及工具來做

Page 43: Noder eyes for frontend guys

我要怎樣debug?

● 建議把邏輯集中到function,放進module,做單元測試(這是基本的refactoring)

● 簡單的邏輯bug,用console.log、console.dir就可以解決

● 如果需要做profiling、找出memory leak,再來使用debug工具,例如○ Using Eclipse as Node Applications Debugger○ other solutions: node-inpector, ndb etc.

Page 44: Noder eyes for frontend guys

有什麼hosting服務嗎?

● 有許多廠商提供這方面的服務○ Joyent (MiCloud)○ Heroku○ Nodejitsu○ Nodester○ Azure○ more...

● 選擇重點○ 基本管理工具

○ deploy方式○ 擴充方案

Page 45: Noder eyes for frontend guys

兩三事代替總結

● 這些主題,有很多是在nodejs group上常見的● 而且,裡面有些東西是火藥庫● node.js開發team的目標,是一個精簡而可靠

的核心,所以會放棄很多用第三方模組就可以做到的功能

● 有需求的地方,就是可以自己插手的地方,畢竟node.js還很年輕

● 後面某一場,Ben會分享他為什麼要開發自己的framework,大家可以聽一聽他的心得

Page 46: Noder eyes for frontend guys

Q&A

Page 47: Noder eyes for frontend guys

我最近的出沒地點

● 我的Facebook● 我的噗浪● facebook Javascript.tw group● facebook nodejs.tw group● facebook PHP 台灣 group● Zen of Friends讀書會以及Web Dev Party● 我的部落格 (自從用噗浪以後就少出沒了)

● 歡迎來交朋友...

Page 48: Noder eyes for frontend guys

The End