Node.js 与前端开发实战 | 青训营笔记

116 阅读5分钟

Node.js 与前端开发实战 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第 16 天

概述

本节课程主要分为四个方面:

  1. 介绍 Node.js 的应用场景

  2. 介绍 Node.js 运行时结构

  3. 如何用编写 Http Server

  4. 延伸话题

课前

安装 Node.js。可以选择以下一种方式:

  1. 从 Node.js 官网安装 nodejs.org/en/

  2. Mac, Linux 环境可以使用 nvm 进行安装 github.com/nvm-sh/nvm

    1. NVM_NODEJS_ORG_MIRROR=npmmirror.com/mirrors/nod… nvm install 16

Node.js 的应用场景

  1. 前端工程化。早期 ajax, jquery 比较流行的时候,我们直接在页面中引入需要的 lib 即可。后续随着模块化、transpile 逐渐成熟、需求逐渐增多,对后端能力的需求也逐渐强烈。反过来说,也正是 Node.js 赋予了 js 开发者在浏览器外运行代码的能力,加速催生了这些项目的出现。

    • Bundle: webpack, vite, esbuild, parcel
    • Uglify: uglifyjs
    • Transpile: bablejs, typescript
    • 其他语言加入竞争:esbuild, parcel, prisma
    • 现状:难以替代
  2. Web 服务端应用。使用 Node.js 开发 Web 服务端应用,也就是后端服务。这里我们特别提一下 vercel 这家公司。

    • 学习曲线平缓,开发效率高
    • 运行效率接近常见的编译语言
    • 社区生态丰富及工具链成熟(npm, V8 inspector)
    • 与前端结合的场景会有优势
    • 现状:竞争激烈,Node.js 有自己独特的优势
  3. Electron 跨桌面端应用。这里不只是指 electron,还包括 nw.js.. ; 这个场景在较大的企业里面非常常见。

    • 商业应用:VSCode,Slack,Discord,Zoom
    • 大型公司内的效率工具
    • 现状:大部分场景在选型时,都值得考虑

Node.js 运行时结构

Pasted image 20220808101328.png

  • V8:JavaScript Runtime,诊断调试工具(inspector)
  • libuv:eventloop(事件循环),syscall(系统调用)
  • 举例:用 node-fetch 发起请求时...

特点

  1. 异步 I/O

    当 Node.js 执行 I/O 操作时,会在响应返回后恢复操作,而不是阻塞线程并占用额外内存等待

    Pasted image 20220808101624.png

  2. 单线程

    • JS 单线程
      • 实际:JS 线程 + uv 线程池 + V8 任务线程池 + V8 Inspector 线程
    • 优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能比较高效地利用系统资源
    • 缺点:阻塞会产生更多负面影响
      • 解决办法:多进程或多线程
  3. 跨平台

    • 跨平台(大部分功能。API)
    • Node.js 跨平台 + JS 无需编译环境(+Web 跨平台 + 诊断工具跨平台)=开发成本低(大部分场景无需担心跨平台问题),整体学习成本低

编写 HTTP Server

本节目标

  1. 安装 Node.js
  2. 编写 Http Server + Client,收发 GET,POST 请求
  3. 编写静态文件服务器
  4. 编写 React SSR 服务
  5. 适用 inspector 进行调试、诊断
  6. 部署简介

Http Server

Hello World

Pasted image 20220808102227.png

Pasted image 20220808102236.png

JSON

Pasted image 20220808102249.png

Pasted image 20220808102257.png

Http Client

Pasted image 20220808102311.png

Promisify

用 Promise + async await 重写这两个例子

技巧:将 callback 转换成 promise

Pasted image 20220808102428.png

静态文件

编写一个简单的静态文件服务:

Pasted image 20220808102449.png

与高性能、可靠的服务相比,还差什么:

  1. CDN:缓存 + 加速
  2. 分布式存储,容灾

外部服务:cloudflare,七牛云,阿里云,火山云 ...

React SSR

  • SSR(Server Side Rendering)有什么特点:

    • 相比传统 HTML 模板引擎:避免重复编写代码
    • 相比 SPA (Single Page Application):首屏渲染更快,SEO 友好
    • 缺点:通常 qps 较低,前端代码编写时需要考虑服务端渲染情况
  • HTML 例子

Pasted image 20220808102757.png

  • 替换成 React

Pasted image 20220808102814.png

SSR 难点:

  1. 需要打包处理代码
  2. 需要思考前端代码在服务端运行时的逻辑
  3. 移除对服务端无意义的副作用,或重置环境

Debug

  • V8 Inspector:开箱即用、特性丰富强大、与前端开发一致、跨平台

  • 场景:

    • 查看 console.log 内容
    • breakpoint
    • 高 CPU 、死循环:cpuprofile
    • 高内存占用:headsnapshot
    • 性能分析

演示:

Pasted image 20220808103128.png

Pasted image 20220808103139.png

Pasted image 20220808103145.png

部署

  • 部署要解决的问题
    • 守护进程:当进程退出时,重新拉起
    • 多进程:cluster 便捷地利用多进程
    • 记录进程状态,用于诊断
  • 容器环境
    • 通常有健康检查的手段,只需考虑多核 CPU 利用率即可

延伸话题

Node.js 贡献代码

  • 快速了解 Node.js 代码
  • 好处:
    • 从使用者的角色逐步理解底层细节,可以解决更复杂的问题
    • 自我证明,有助于职业发展
    • 解决社区问题,促进社区发展
  • 难点:
    • 花时间

编译 Node.js

  • 为什么要学习编译 Node.js
    • 认知:黑盒到白盒,发生问题时能有迹可循
    • 贡献代码的第一步
  • 如何编译
    • 参考:
    • ./configure && make install
    • 演示:给 net 模块添加自定义属性

诊断 / 追踪

  • 诊断是一个低频、重要,同时也相当有挑战的方向。是企业衡量自己能否依赖一门语言的重要参考
  • 技术咨询行业中的热门角色
  • 难点
    • 需要了解 Node.js 底层,需要了解操作系统以及各种工具
    • 需要经验

Pasted image 20220808101111.png

WASM,NAPI

  • Node.js(因为 V8)是执行 WASM 代码的天然容器,和浏览器 WASM 是同一运行时,同时 Node.js 支持 WASI
  • NAPI 执行 C 接口的代码(C/C++/Rust...),同时能保留原生代码的性能
  • 不同编程语言间通信的一种方案

课后