Node Cookbook 3rd-Packt Publishing 2017-ReadingNotes.md
調試進程
-
用DevTools調試Node
$ mkdir app $ cd app $ npm init -y $ npm install --save express $ node --inspect index.js (6.3.0+,這個調試真的不錯啊,酷斃了!)
How it works... 這段內容很有意思,因爲它涉及了v8的debugger協議細節
- 8+ 啓動時暫停:
node --inspect-brk index.js
- 命令行調試:
node debug index.js
- Enhancing stack trace output
- 增加棧深度顯示:
--stack-trace-limit=21
- 進一步在代碼中指定:
Error.stackTraceLimit = Infinity
- 增加棧深度顯示:
- Asynchronous stack traces
$ npm install --save-dev longjohn
這是什麼原理?
- 啓用debug logs:
DEBUG=* node index.js
- 啓用core debug logs:
- 特殊的環境變量:
$ NODE_DEBUG=timer node index.js
- NODE_DEBUG可設置爲下列模塊:http net tls stream module timer cluster child_process fs
- 特殊的環境變量:
編寫模塊
- npm config set init.author.name "< name here >"
- npm init(package.json文件裏似乎沒有依賴字段?)
- npm version 1.0.0
- 安裝依賴:
- npm install --save hsl-to-rgb-for-reals
- --save-dev
- npm run lint
- 安裝全局依賴不需要sudo(實質是修改了prefix路徑):
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
- 或:
npm config set prefix ~/ npm-global
(需要添加到PATH中)
- 或:
- node -p "require('./')( 0, 100, 100)" (-p選項有點像Perl裏的-e)
- 測試:
- tap 代碼覆蓋?
- 發佈模塊
- npm login
- npm publish --access = public
- 模塊安全
- npm i -g auditjs
- prepublish(略)
- 發佈到IPFS:npm install -g stay-cli
- 使用私有倉庫(npm官方也是使用的這個實現嗎?還是說僅僅是mock的api?)
- npm install -g sinopia && sinopia &> /dev/null &
- npm set registry http://localhost:4873
Coordinating I/O
- setInterval(() => process.stdout.write('.'), 10).unref()
- 監視目錄:chokidar
Using Streams
- stream事件
- data
- end(輸入流)--> finish(輸出流)
- close,error(不保證一定有觸發)
- pause/resume(都是針對ReadableStream的!pull模型)
- 使用pipe
- !產品環境中不要使用,推薦
pump
(見鬼) - backpressure
- content.pipe( socket, {end: false})
- content.on('end', ()=>{socket.end()})
- 驗證:同一input可以pipe到多個output???
- !產品環境中不要使用,推薦
- pipe缺少error處理???!不早說,tnnd
- npm install --save pump
- pump(input, output, (error)={...})
- 避免自己手寫的boilerplate代碼:
- stream.pipe(res); res.on('close', ()=>{stream.destroy()})
- pumpify:忽略pipeline中間的transform流,只展示開始的input和最終的output?
- 創建自己的transform流:through2 ?
- 推薦使用readable-stream,而不是core stream,以屏蔽不同Node版本的差異?
- 對象流*
- from2、to2(見鬼)
- stream.Readable/Writable
- flow control:
- readable流的_read方法依賴於push的驅動,怎麼以異步方式連續push多次呢?
- 包from2 + 嵌套setTimeout???
- duplex流:const stream = duplexify(ws, rs)
- Decoupling I/O(???)
- By default, writable streams have a high watermark of 16,384 bytes (16 KB). 如果超過了仍繼續寫入就會內存泄露。
- pipe控制的write每次寫不會超過16KB,但直接write可以超過:
rs.on(' data', (chunk) = > ws.write( chunk))
- 這種情況下,需要檢查write的返回值,true代表可以繼續寫,false說明需要暫停,直到drain事件觸發:
rs.resume()) ws.once('drain', () = > rs.resume())
- pipe控制的write每次寫不會超過16KB,但直接write可以超過:
Wielding Web Protocols
- 上傳文件via PUT和xhr2: 。。。
const buffer = Buffer.allocUnsafe(size); ... chunk.copy(buffer, index)
持久化到數據庫
- Postgres jsonb類型?
- $ npm install --save hiredis(比純JS的包redis更快?)
- LevelDB?跟SQLite屬於嵌入式環境使用吧
使用Web框架
- express
- Hapi
- Koa(v2: 8+)
const router = require('koa-router')() router.get('/', async function (ctx, next) { await next() const { title } = ctx.state ctx.body = `...` }, async (ctx) = > ctx.state = {...});
處理安全
- express:用helmet增強http響應頭部*
- 防禦XSS:url請求參數中用JS嵌入特殊的token(?似乎不是根本的解決方法?)
- 協議handler類型的XSS(javascript:...)
- 防禦CSRF:cookie sameSite選項?
優化性能
- HTTP性能基準測試
- autocannon:POST請求
- Finding bottlenecks with flamegraphs(用火焰圖來尋找瓶頸)
- 0x ? --pref-basic-prof 使用HTML+D3.js生成圖表?
- 優化同步函數調用
- node --trace-opt --trace-deopt app.js
- 優化異步回調
- Profiling memory
構建微服務系統
- fuge???
- 服務發現機制:dns?
- Consul.io
- etcd
- zookeeper
- P2P協議,如Raft
Deploying Node.js
- kops: 管理多個k8s集羣???