这是我参与「第四届青训营 」笔记创作活动的的第10天
Node.js 是什么
Node.js 诞生于 2009 年,由 Joyent 的员工 Ryan Dahl 开发而成, 目前官网最新版本已经更新到 12.0.0版本,最新稳定的是10.15.3。Node.js 不是一门语言也不是框架,它只是基于 Google V8 引擎的 JavaScript 运行时环境,同时结合 Libuv 扩展了 JavaScript 功能,使之支持 io、fs 等只有语言才有的特性,使得 JavaScript 能够同时具有 DOM 操作(浏览器)和 I/O、文件读写、操作数据库(服务器端)等能力,是目前最简单的全栈式语言。 这里我们可以简单理解Node.js是一个内置有chrome V8引擎的JavaScript运行环境,他可以使原本在浏览器中运行的JavaScript有能力跑后端,从而操作我们数据库,进行文件读写等。 目前市面上高密集的I/O模型,比如 Web 开发,微服务,前端构建等都有做Node.js的身影。不少大型网站都是使用 Node.js 作为后台开发语言的,比如 淘宝 双十一、去哪儿网 的 PC 端核心业务等。另外我们一些前端工具譬如VSCode,webpack等也是有Node.js开发。 Node.js的包管理工具,npm已经成为世界开源包管理中最大的生态,功能强大,目前单月使用者接近1000万。
Node.js 的应用场景
- 前端工程化
- Web 服务端应用
- Electron等 跨端桌面应用
前端工程化
- Bundle:webpack,vite,esbuild,parcel
- Uglify:uglifyjs
- Transpile:bablejs,typescript
- 其他语言加入竞争:esbuild,parcel,prisma
- 现状:难以替代
Web 服务端应用
- 学习曲线平缓,开发效率较高
- 运行效率接近常见的编译语言
- 社区生态丰富及工具链成熟 ( npm,V8 inspector)
- 与前端结合的场景会有优势 (SSR)
- 现状:竞争激烈,Node.js 有自己独特的优势
跨端桌面应用
- 商业应用:vscode,slack,discord,Zoom
- 大型公司内的效率工具
- 现状:大部分场景在选型时,都值得考虑
Node.js 运行时结构
V8、libuv
- V8:JavaScript Runtime,.诊断调试工具((inspector))
- libuv:eventloop(事件循环),syscall(系统调用)
- 举例:用 node-fetch 发起请求时
特点-异步 I/O
当 Node.js 执行 I/O 操作时,会在响应返回后恢复操作,而不是阻塞线程并占用额外内存等待
特点-单线程
- JS单线程
- 实际:JS 线程+uv 线程池+V8 任务线程池+V8 Inspector线程
- 优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能比较高效地利用系统资源;
- 缺点:阻塞会产生更多负面影响
- 解决办法:多进程或多线程
特点-跨平台
- 跨平台 (大部分功能、api)
- Node.js 跨平台 + JS 无需编译环境 (+Web 跨平台 + 诊断工具跨平台)
- 开发成本低 (大部分场景无需担心跨平台问题),整体学习成本低
Http Server
Debug
- V8 Inspector:开箱即用、特性丰富强大、与前端开发一致、跨平台
- node --inspect
- open http://localhost:9229/json
- 场景:
- 查看console.log内容
- breakpoint
- 高 CPU、死循环:cpuprofile
- 高内存占用:heapsnapshot
- 性能分析
部署
- 部署要解决的问题
- 守护进程:当进程退出时,重新拉起
- 多进程:cluster便捷地利用多进程
- 记录进程状态,用于诊断
- 如 PM2
- 容器环境
- 通常有健康检查的手段,只需考虑多核cpu利用率即可
延伸
WASM、NAPI
- Node.js(因为V8)是执行WASM代码的天然容器,和浏览器WASM是同一运行时,同时Node.js支持WASl
- NAPI 执行 C 接口的代码 ( C/C++/Rust ), 同时能保留原生代码的性能。
- 不同编程语言间通信的一种方案。