前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 环境搭建

30 秒速记

  • 目标就一句:开发机、CI、生产跑同一个 Node 主版本、装出同一份依赖
  • 版本钉死:项目根目录放 .nvmrc,package.json 写 engines
  • 依赖钉死:提交 lockfile,CI 用 npm ci 不用 npm install
  • 原生依赖(sharp、bcrypt)最容易出环境差异,换平台、换主版本要重装
  • 验证别只看 node -v:装一遍依赖、跑一遍测试才算环境搭好

搭 Node 环境的关键不是把 node 装上,而是让每台机器跑的版本和依赖一模一样。 我一般会在项目里放一个 .nvmrc 写上主版本,package.json 里用 engines 声明范围,大家进目录 nvm use 就对齐了。依赖这边,lockfile 必须提交,CI 和部署用 npm ci,它严格按 lockfile 装,和 package.json 对不上就直接报错,不会偷偷升级。很多「我电脑上能跑」的问题,根子都是 Node 主版本不一样或者没锁依赖。

理解「环境搭建」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

环境搭建这件事,真正难的不是装上 node,而是保证「同一份代码在任何地方跑出同样的结果」。可以按三层来对齐。

第一层是 Node 版本。项目根目录放一个 .nvmrc:

echo "22" > .nvmrc
nvm use        # 读取 .nvmrc,切到 22.x
node -v        # v22.x.x
@前端进阶之旅: 代码已经复制到剪贴板

package.json 里再声明一次:

{
  "engines": { "node": ">=22 <23" }
}
@前端进阶之旅: 代码已经复制到剪贴板

配合 .npmrc 里的 engine-strict=true,版本不对时 npm install 会直接失败,而不是只打一行没人看的警告。

第二层是依赖。package-lock.json(或 yarn.lock、pnpm-lock.yaml)一定要提交,它记录了每个包的精确版本和下载地址。开发时用 npm install 加依赖,CI 和部署统一用 npm ci,严格按 lockfile 安装。

第三层是系统环境。node-gyp 编译原生模块需要 Python 和 C++ 编译工具,Windows 上还要装 Visual Studio Build Tools;环境变量也要列成清单,别让某个只在你机器上存在的变量决定程序能不能跑。

最后验证别只敲一句 node -v。一个比较靠谱的检查是:干净目录克隆代码,nvm use、npm ci、npm test 三步全过,才算这台机器的环境真正搭好了。

面试官追问

追问 1本地好好的,CI 上 npm install 之后测试挂了,同一份代码,你先查什么?
参考回答

先比两边的 node -v 和实际装出来的依赖版本。npm install 会在 semver 范围内装新版,CI 换成 npm ci 严格按 lockfile,大部分这类问题就消失了。

追问 2npm ci 和 npm install 有什么区别?
参考回答

npm ci 先删掉 node_modules,完全按 package-lock.json 装,lockfile 和 package.json 不一致直接失败,也不会改写 lockfile。npm install 会解析范围、可能更新 lockfile,适合开发时加依赖。

追问 3package.json 写了 "engines": { "node": ">=20" },有人用 Node 18 装依赖为什么没报错?
参考回答

npm 默认对 engines 只给警告。要强制拦住就在 .npmrc 里加 engine-strict=true,版本不对直接安装失败。

追问 4从 Node 18 升到 22 之后,启动报 was compiled against a different Node.js version,怎么回事?
参考回答

原生模块是按 Node 的 ABI 编译的,主版本一换就不兼容。删掉 node_modules 重新装,或者 npm rebuild;Docker 镜像里也要确保构建和运行用同一个基础镜像版本。

追问 5Dockerfile 里写 FROM node:latest,有什么问题?
参考回答

latest 会跟着 Node 发版漂移,今天构建是 24,过几个月可能就是 26,构建结果不可复现。写死主版本,比如 node:22-alpine,升级当成一次显式变更来做。

# 认识 Node.js

30 秒速记

  • Node.js 不是语言也不是框架,是让 JS 跑在浏览器外的运行时:V8 + libuv + 内置模块
  • 事件驱动 + 非阻塞 I/O:读文件、发请求交给底层,主线程不傻等
  • 擅长 I/O 密集(接口层、BFF、SSR、工具链),不擅长 CPU 密集(大计算会卡住事件循环)
  • 和浏览器比:没有 DOM / window,多了 fs、http、process 这些系统能力
  • 生态靠 npm,前端工具链(Webpack、Vite、ESLint)几乎全跑在 Node 上

Node.js 是一个让 JavaScript 跑在服务端的运行时,核心是 Chrome 的 V8 引擎加上 libuv 提供的事件循环和异步 I/O。 它不是新语言,语法还是 JS,只是把浏览器里的 DOM、window 换成了 fs、http、process 这些系统能力。它快的地方在 I/O:读文件、查数据库都交给底层异步去做,主线程接着处理下一个请求,所以单线程也能扛很多并发连接。反过来,图片压缩、大循环这类 CPU 密集的活会把唯一的主线程卡住,这时候要上 worker_threads 或者拆出去。

const fs = require('fs');
fs.readFile(__filename, () => console.log('2. 文件读完了'));
console.log('1. 不等文件,先往下走');
// 输出顺序:1 → 2
@前端进阶之旅: 代码已经复制到剪贴板
  • Node 是一个服务器端 JavaScript 解释器
  • Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境
  • Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效
  • Node.js 的包管理器 npm,是全球最大的开源库生态系统
  • Node.js 是一门动态语言,运行在服务端的 Javascript

面试官追问

追问 1都说 Node 是单线程,那它怎么同时处理几千个请求?
参考回答

单线程指的是执行 JS 的主线程只有一个。网络 I/O 交给操作系统的 epoll / kqueue,文件 I/O 交给 libuv 线程池,主线程只负责在结果回来时执行回调,所以不会因为等 I/O 而堵住。

追问 2接口里要对一张 20MB 的图片做压缩,直接写在请求处理函数里会怎样?
参考回答

压缩期间主线程被占满,其他所有请求都排队,表现是整个服务卡顿、健康检查超时。要么用 sharp 这类底层多线程的库,要么丢给 worker_threads 或者单独的任务队列。

追问 3浏览器里写的代码,拿到 Node 里跑报 window is not defined,为什么?
参考回答

Node 没有 window 和 DOM,全局对象是 global,通用写法是 globalThis。做 SSR 时这种报错特别常见,访问浏览器 API 的代码要放到只在客户端执行的地方。

追问 4前端为什么要懂 Node?
参考回答

前端工具链本身就是 Node 程序,Vite 插件、Webpack loader、ESLint 规则都要用 Node 写;SSR 和 BFF 层也跑在 Node 上,出了内存泄漏、事件循环阻塞这类问题得自己能查。

# 版本介绍

30 秒速记

  • 看版本:node -v;看各组件版本:node -p process.versions
  • 发版规律:偶数主版本会进 LTS 长期维护,奇数版本只是 Current,生产别用奇数版
  • ES6 支持粗略分代:4.x 有了 class / 箭头函数,6.x 覆盖绝大部分 ES6,7.6+ 原生 async/await
  • 历史版本 0.x → io.js 分裂 → 合并后直接跳到 4.0,所以没有 1.x ~ 3.x 的 Node
  • 查某个语法哪个版本开始支持,去 node.green 对照

查版本直接 node -v,选版本记住一条:生产用偶数号的 LTS 版本。 Node 每年发两个主版本,偶数版本会进入大约 30 个月的长期维护,奇数版本半年左右就停止维护,只适合尝鲜。早年各版本对 ES6 的支持差别很大,4.x 开始有 class 和箭头函数,6.x 基本覆盖了 ES6,7.6 之后 async/await 才能原生用。现在这些都不是问题了,更要关心的是你用的版本是否还在维护期,过了 EOL 就没有安全补丁。

node -v                    # v22.11.0
node -p process.versions.v8   # 查 V8 版本
node -p "process.release.lts" # LTS 版本会打印代号,比如 'Jod'
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
      • 认识 Node.js
      • 版本介绍
      • 环境搭建
        • NVM管理Node版本
      • Node.js 模块
      • npm scripts
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

环境搭建|Nodejs专题系列

# 环境搭建

30 秒速记

  • 目标就一句:开发机、CI、生产跑同一个 Node 主版本、装出同一份依赖
  • 版本钉死:项目根目录放 .nvmrc,package.json 写 engines
  • 依赖钉死:提交 lockfile,CI 用 npm ci 不用 npm install
  • 原生依赖(sharp、bcrypt)最容易出环境差异,换平台、换主版本要重装
  • 验证别只看 node -v:装一遍依赖、跑一遍测试才算环境搭好

搭 Node 环境的关键不是把 node 装上,而是让每台机器跑的版本和依赖一模一样。 我一般会在项目里放一个 .nvmrc 写上主版本,package.json 里用 engines 声明范围,大家进目录 nvm use 就对齐了。依赖这边,lockfile 必须提交,CI 和部署用 npm ci,它严格按 lockfile 装,和 package.json 对不上就直接报错,不会偷偷升级。很多「我电脑上能跑」的问题,根子都是 Node 主版本不一样或者没锁依赖。

理解「环境搭建」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

环境搭建这件事,真正难的不是装上 node,而是保证「同一份代码在任何地方跑出同样的结果」。可以按三层来对齐。

第一层是 Node 版本。项目根目录放一个 .nvmrc:

echo "22" > .nvmrc
nvm use        # 读取 .nvmrc,切到 22.x
node -v        # v22.x.x
@前端进阶之旅: 代码已经复制到剪贴板

package.json 里再声明一次:

{
  "engines": { "node": ">=22 <23" }
}
@前端进阶之旅: 代码已经复制到剪贴板

配合 .npmrc 里的 engine-strict=true,版本不对时 npm install 会直接失败,而不是只打一行没人看的警告。

第二层是依赖。package-lock.json(或 yarn.lock、pnpm-lock.yaml)一定要提交,它记录了每个包的精确版本和下载地址。开发时用 npm install 加依赖,CI 和部署统一用 npm ci,严格按 lockfile 安装。

第三层是系统环境。node-gyp 编译原生模块需要 Python 和 C++ 编译工具,Windows 上还要装 Visual Studio Build Tools;环境变量也要列成清单,别让某个只在你机器上存在的变量决定程序能不能跑。

最后验证别只敲一句 node -v。一个比较靠谱的检查是:干净目录克隆代码,nvm use、npm ci、npm test 三步全过,才算这台机器的环境真正搭好了。

面试官追问

追问 1本地好好的,CI 上 npm install 之后测试挂了,同一份代码,你先查什么?
参考回答

先比两边的 node -v 和实际装出来的依赖版本。npm install 会在 semver 范围内装新版,CI 换成 npm ci 严格按 lockfile,大部分这类问题就消失了。

追问 2npm ci 和 npm install 有什么区别?
参考回答

npm ci 先删掉 node_modules,完全按 package-lock.json 装,lockfile 和 package.json 不一致直接失败,也不会改写 lockfile。npm install 会解析范围、可能更新 lockfile,适合开发时加依赖。

追问 3package.json 写了 "engines": { "node": ">=20" },有人用 Node 18 装依赖为什么没报错?
参考回答

npm 默认对 engines 只给警告。要强制拦住就在 .npmrc 里加 engine-strict=true,版本不对直接安装失败。

追问 4从 Node 18 升到 22 之后,启动报 was compiled against a different Node.js version,怎么回事?
参考回答

原生模块是按 Node 的 ABI 编译的,主版本一换就不兼容。删掉 node_modules 重新装,或者 npm rebuild;Docker 镜像里也要确保构建和运行用同一个基础镜像版本。

追问 5Dockerfile 里写 FROM node:latest,有什么问题?
参考回答

latest 会跟着 Node 发版漂移,今天构建是 24,过几个月可能就是 26,构建结果不可复现。写死主版本,比如 node:22-alpine,升级当成一次显式变更来做。

# 认识 Node.js

30 秒速记

  • Node.js 不是语言也不是框架,是让 JS 跑在浏览器外的运行时:V8 + libuv + 内置模块
  • 事件驱动 + 非阻塞 I/O:读文件、发请求交给底层,主线程不傻等
  • 擅长 I/O 密集(接口层、BFF、SSR、工具链),不擅长 CPU 密集(大计算会卡住事件循环)
  • 和浏览器比:没有 DOM / window,多了 fs、http、process 这些系统能力
  • 生态靠 npm,前端工具链(Webpack、Vite、ESLint)几乎全跑在 Node 上

Node.js 是一个让 JavaScript 跑在服务端的运行时,核心是 Chrome 的 V8 引擎加上 libuv 提供的事件循环和异步 I/O。 它不是新语言,语法还是 JS,只是把浏览器里的 DOM、window 换成了 fs、http、process 这些系统能力。它快的地方在 I/O:读文件、查数据库都交给底层异步去做,主线程接着处理下一个请求,所以单线程也能扛很多并发连接。反过来,图片压缩、大循环这类 CPU 密集的活会把唯一的主线程卡住,这时候要上 worker_threads 或者拆出去。

const fs = require('fs');
fs.readFile(__filename, () => console.log('2. 文件读完了'));
console.log('1. 不等文件,先往下走');
// 输出顺序:1 → 2
@前端进阶之旅: 代码已经复制到剪贴板
  • Node 是一个服务器端 JavaScript 解释器
  • Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境
  • Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效
  • Node.js 的包管理器 npm,是全球最大的开源库生态系统
  • Node.js 是一门动态语言,运行在服务端的 Javascript

面试官追问

追问 1都说 Node 是单线程,那它怎么同时处理几千个请求?
参考回答

单线程指的是执行 JS 的主线程只有一个。网络 I/O 交给操作系统的 epoll / kqueue,文件 I/O 交给 libuv 线程池,主线程只负责在结果回来时执行回调,所以不会因为等 I/O 而堵住。

追问 2接口里要对一张 20MB 的图片做压缩,直接写在请求处理函数里会怎样?
参考回答

压缩期间主线程被占满,其他所有请求都排队,表现是整个服务卡顿、健康检查超时。要么用 sharp 这类底层多线程的库,要么丢给 worker_threads 或者单独的任务队列。

追问 3浏览器里写的代码,拿到 Node 里跑报 window is not defined,为什么?
参考回答

Node 没有 window 和 DOM,全局对象是 global,通用写法是 globalThis。做 SSR 时这种报错特别常见,访问浏览器 API 的代码要放到只在客户端执行的地方。

追问 4前端为什么要懂 Node?
参考回答

前端工具链本身就是 Node 程序,Vite 插件、Webpack loader、ESLint 规则都要用 Node 写;SSR 和 BFF 层也跑在 Node 上,出了内存泄漏、事件循环阻塞这类问题得自己能查。

# 版本介绍

30 秒速记

  • 看版本:node -v;看各组件版本:node -p process.versions
  • 发版规律:偶数主版本会进 LTS 长期维护,奇数版本只是 Current,生产别用奇数版
  • ES6 支持粗略分代:4.x 有了 class / 箭头函数,6.x 覆盖绝大部分 ES6,7.6+ 原生 async/await
  • 历史版本 0.x → io.js 分裂 → 合并后直接跳到 4.0,所以没有 1.x ~ 3.x 的 Node
  • 查某个语法哪个版本开始支持,去 node.green 对照

查版本直接 node -v,选版本记住一条:生产用偶数号的 LTS 版本。 Node 每年发两个主版本,偶数版本会进入大约 30 个月的长期维护,奇数版本半年左右就停止维护,只适合尝鲜。早年各版本对 ES6 的支持差别很大,4.x 开始有 class 和箭头函数,6.x 基本覆盖了 ES6,7.6 之后 async/await 才能原生用。现在这些都不是问题了,更要关心的是你用的版本是否还在维护期,过了 EOL 就没有安全补丁。

node -v                    # v22.11.0
node -p process.versions.v8   # 查 V8 版本
node -p "process.release.lts" # LTS 版本会打印代号,比如 'Jod'
@前端进阶之旅: 代码已经复制到剪贴板
  • 在命令窗口中输入 node -v 可以查看版本
  • 0.x 完全不技术 ES6
  • 4.x 部分支持 ES6 特性
  • 5.x 部分支持ES6特性(比4.x多些),属于过渡产品,现在来说应该没有什么理由去用这个了
  • 6.x 支持98%的 ES6 特性
  • 8.x 支持 ES6 特性

面试官追问

追问 1为什么说生产环境别用奇数版本?
参考回答

奇数版本只有大约半年的维护期,到期就不再修安全漏洞,而且不会进入 LTS。生产选当前处于 Active LTS 或 Maintenance LTS 的偶数版本。

追问 2老项目还跑在 Node 14,有什么风险?要不要升?
参考回答

Node 14 早就 EOL,出了安全漏洞没人修,很多新版依赖也声明了更高的 engines,装不上新包。建议升,但按主版本逐级升、每级跑全量测试,原生依赖重点关注。

追问 3代码里用了 ?. 可选链,部署到某台机器上报 SyntaxError: Unexpected token '.',为什么?
参考回答

那台机器的 Node 太老,可选链从 Node 14 才原生支持。先 node -v 确认,统一版本是根治;临时兼容就让构建工具把语法降级。

追问 4怎么快速查某个新语法从哪个 Node 版本开始能用?
参考回答

看 node.green,它按 Node 版本列出了每个 ECMAScript 特性的支持情况;Node 官方的 changelog 也会写升级了哪个 V8 版本。

# 环境搭建

node部署 →

fe