Node.js与前端开发实战 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第12天 与大家分享Node.js的基础知识,包括前端开发实战应用等,不足之处欢迎大家批评指正!
Node.js的应用场景
总述
01 前端工程化
02 Web服务器端应用
后端服务,特别Vercel公司
03 Electron跨桌面应用
较大的企业中比较常见
前端工程化
- Bundle:webpack,vite,esbuid,parcel
- Uglify:uglifyjs
- Transpile:bablejs,typescript
- 其他语言加入竞争:esbuild,parcel,prisma
- 现状:难以替代
Web服务器端应用
- 学习曲线平缓,开发效率较高
- 运行效率接近常见的编译语言
- 社区生态丰富及工具链成熟(npm,V8 inspector)
- 与前端结合的场景会有优势(SSR)
- 现状:竞争激烈,Node.js有自己独特的优势
Electron跨端桌面应用
- 商业应用:vscode,slack,discord,zoom
- 大型公司内的效率工具
- 现状:大部分场景在选型时,都值得考虑
Node.js在字节
- BFF应用、SSR应用,举例:Modern.js
https://modernjs.dev/ - 服务器端应用,举例:头条搜索、西瓜视频、懂车帝
- Electron应用:飞连,飞书
- 每年新增1000+ Node.js应用
Node.js运行时结构
特点
- 异步I/o
- 单线程
worker_thread可以起独立线程,但每个线程的模型没有太大变化
- 跨平台
异步I/O
当Node.js执行I/O操作时,会在响应后返回恢复操作,而不是阻塞线程并占用额外内存等待。
好处:不需要等待
单线程
-
JS单线程 实际:JS线程 + uv线程 + v8任务线程池 + V8 Inspector线程
-
优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能比较高效地利用系统资源
-
缺点:阻塞会产生更多负面影响
解决方法:多进程或多线程
跨平台
- 跨平台(大部分功能,API)
- Node.js跨平台 + JS无需编译环境(+ Web跨平台 + 诊断工具跨平台) = 开发成本低(大部分场景无需担心跨平台问题),整体学习成本低
编写HTTP Server
安装Node.js
- Mac, Linux 推荐使用 nvm ,多版本管理
- Windows推荐 nvm4w 或官方安装包
- 安装慢,安装失败的情况,设置安装源
编写Http Server
- http_server.js
运行结果
- http_server.json
运行结果
- http_client.js
Promisify
用Promise + async await重写这两个例子
原因:更好地维护代码
技巧:将callback转换成promise
Promise只适用于改写函数被调用一次的场景
静态文件
编写一个静态文件服务:
与高性能、可靠的服务相比,还差什么?
外部服务:cloudflare,七牛云,阿里云,火山云...
- CDN:缓存 + 加速
- 分布式储存,容灾
React SSR
- SSR(Server side rendering)有什么特点?
- 优点
- 相比传统HTML模板引擎:避免重复编写代码
- 相比SPA(single page application):首屏渲染更快,SEO友好
- 缺点
- 通常qps较低,前端代码编写时需要考虑服务端渲染情况
- HTML例子
- 替换成React
- SSR难点
- 需要打包处理代码
- 需要思考前端代码在运行时的逻辑
- 移除对服务端无意义的副作用,或重置环境
Debug
- V8 Inspector:开箱即用,特性丰富强大,与前端开发一致,跨平台
node --inspect
open http://localhost:9229/json
- 场景
查看
console.log内容
breakpoint
高CPU、死循环:cpuprofile
高内存占用:heapsnapshot
性能分析
- 演示
部署
- 部署要解决的问题:
- 守护进程:当进程退出时,重新拉起
- 多进程:
cluster便捷地利用多进程 - 记录进程状态,用于诊断
- 容器环境
- 通常有健康检查的手段,只需考虑多核cpu利用率即可
延伸话题
Node.js贡献代码
-
快速了解Node.js代码 Node.js Core 贡献入门
https://github.com/joyeecheung/talks/blob/master/code_and_learn_2019_beijing/contributing-to-node-core.pdf -
好处
- 从使用者的角色逐步理解底层细节,可以解决更复杂的问题
- 自我证明,有助于职业发展
- 解决社区问题,促进社区发展
- 难点
- 花时间
编译Node.js
- 为什么要学习编译Node.js
- 认知:黑盒到白盒,发生问题时能有迹可循
- 贡献代码的第一步
- 如何编译?
-
参考:
Maintaining the build files'github.com/nodejs/node…' -
./configure&&make install -
演示:给net模块添加自定义属性
诊断/追踪
-
诊断是一个低频、重要同时也相当有挑战的方向,是企业衡量自己能否依赖一门语言的重要参考
-
技术咨询行业中的热门角色
-
难点:
- 需要了解Node.js底层,需要了解操作系统以及各种工具
- 需要经验
WASM,NAPI
-
Node.js(因为V8)是执行WASM代码的天然容器,和浏览器WASM是同一运行时,同时Node.js支持WASI
-
NAPI执行C接口的代码(c/c++/Rust...),同时能保留原生代码的性能
-
不同编程语言间通信的一种方案