认识Node.js及其与 Nginx 前端项目区别

1、什么是node.js?

node.js是一个平台,或者说是一个运行环境。Node.js 是一个开源、跨平台的 JavaScript 运行时环境,它允许开发者在服务器端运行 JavaScript 代码。

1.1、node运行方式

通过cmd进入Node.js就要在cmd中输入node

1.2、node.js前端应该了解些什么?

1.2.1、安装和设置Node.js环境:

要开始使用Node.js,首先需要访问官方网站,下载并安装最新版本的Node.js。然后配置系统的环境变量,确保可以在命令行中运行Node.js和npm(Node包管理器)命令。

// 查看 node 版本

node -v

// 列出 Node 版本

nvm ls

// 切换 Node 版本

nvm use xxx

1.2.2、核心能力模块:

Node.js提供了一系列的核心模块,如:

  • fs:文件系统操作。
  • http:创建 HTTP 服务器。
  • path:处理文件路径。
  • os:获取操作系统信息。
  • events:事件驱动机制。
1.2.3、重点能力-异步编程:

Node.js 的重点能力是 异步编程 ,这是因为它的核心设计基于 事件驱动非阻塞 I/O 模型。这种设计使得 Node.js 在处理高并发和 I/O 密集型任务时非常高效。

1.单线程模型

  • Node.js 使用单线程处理所有任务,但通过事件循环(Event Loop)和异步 I/O 实现高并发。
  • 单线程意味着 Node.js 不会为每个请求创建新的线程,而是通过异步回调处理多个请求。
  • 注意:在 Node.js 中,单线程的意思是:
  • Node.js 的主线程(也叫事件循环线程)只有一条执行路径,用于处理 JavaScript 代码的执行。
  • 主线程不会为每个请求创建新的线程,而是通过 事件循环(Event Loop)异步回调 来管理任务。

单线程并不意味着 Node.js 只能处理一个任务,而是通过异步机制将耗时的任务交给其他线程或系统模块处理,主线程继续执行其他任务。

2.非阻塞 I/O

3.事件驱动

  • Node.js 的 I/O 操作(如文件读写、网络请求、数据库查询)是非阻塞的。
  • 这意味着当一个 I/O 操作正在进行时,Node.js 不会等待其完成,而是继续处理其他任务。
  • Node.js 使用事件循环来监听和处理异步任务。
  • 当异步操作完成时,会触发相应的回调函数,将结果返回给主线程。
1.2.4、使用npm管理依赖:

npm是Node.js的包管理器,可用于安装、管理和发布JavaScript模块。需要学习如何使用npm安装第三方模块,并管理项目的依赖关系。

  • 了解 npm(Node Package Manager)或 Yarn,用于管理项目依赖。
  • 学习如何安装、更新和删除依赖包。
1.2.5、构建Web应用:

学习使用Node.js构建Web服务器和处理HTTP请求。

  • 现代前端开发中,许多构建工具基于 Node.js,例如:
    • Webpack:模块打包工具。
    • Vite:快速构建工具。
    • Rollup:用于打包库的工具。
    • Parcel:零配置打包工具。
  • 学习如何使用这些工具进行代码打包、压缩、转译(如 Babel)等操作。
1.2.6、调试和故障排查:

1.API 调试

  • 使用 Node.js 创建简单的 API 服务,模拟后端接口,方便前端开发和调试。
  • 示例:使用 Express 创建一个 RESTful API。

2.代理服务

3.Mock 数据

  • 使用 Node.js 搭建代理服务器,解决跨域问题。
  • 示例:通过 http-proxy-middleware 转发请求。
  • 使用工具如 json-serverMock.js,通过 Node.js 快速生成模拟数据。
1.2.7、性能优化:

1、非阻塞 I/O

2、流(Streams)

3、中间件

  • 理解 Node.js 的事件循环和异步编程模型。
  • 学习如何使用 async/await 或回调处理异步操作。
  • 学习如何使用 Node.js 的流处理大文件(如文件上传、下载)。
  • 学习如何在框架(如 Express)中使用中间件处理请求。

......

1.2.8、总结

Node.js 对前端开发者来说,不仅是一个后端工具,更是现代前端开发的重要组成部分。通过学习 Node.js,前端开发者可以更高效地构建工具链、处理服务端逻辑、优化前后端协作,并提升全栈开发能力。

1.3、 Node.js 是如何实现异步回调的?

单线程的含义:

Node.js 的主线程只有一条执行路径,用于处理 JavaScript 代码。

单线程并不意味着只能处理一个任务,而是通过异步机制实现高并发。

单线程如何实现异步?

Node.js 使用事件循环、线程池和系统模块,将耗时任务交给其他线程或系统处理。

主线程继续执行其他任务,异步任务完成后通过回调函数返回结果。

异步编程的意义:

避免阻塞主线程,提高性能。

适合处理 I/O 密集型任务(如文件操作、网络请求、数据库查询)。

Node.js 的单线程模型结合异步编程,使其在高并发场景下表现出色,同时避免了多线程编程中的复杂性(如线程同步、死锁等问题)。

1.3.1、 事件循环(Event Loop)

事件循环(Event Loop):指的就是同步、异步的任务分别进入不同的执行环境,最后都同步回归主线程,即主执行栈,异步进入到任务 队列 (Event Queue)。 主线程串行执行任务完毕后,会去任务队列(Event Queue)读取相应的任务,继续串行在主线程执行。 以上不断重复的过程被成为事件循环。

Node.js 的核心是 事件循环,它负责管理异步任务的执行。事件循环的工作流程如下:

1、主线程执行同步代码

  • 主线程会先执行所有同步代码。
  • 如果遇到异步任务(如 I/O 操作、定时器等),会将这些任务交给系统模块或线程池处理。

2、异步任务完成后,将回调函数放入任务队列

  • 异步任务完成后,会将对应的回调函数放入事件循环的任务队列中。

3、主线程从任务队列中取出回调函数执行

  • 主线程会不断检查任务队列,如果有回调函数,就取出并执行。

例子:

javascript 复制代码
const fs = require('fs');

console.log('Start');

// 异步读取文件
fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log('File content:', data);
});

console.log('End');

// 执行流程
// 主线程执行同步代码,打印 Start。
// 遇到 fs.readFile,将文件读取任务交给线程池处理,并继续执行后续代码。
// 主线程打印 End。
// 文件读取完成后,线程池将回调函数放入任务队列。
// 主线程从任务队列中取出回调函数并执行,打印文件内容。

// 输出结果
// Start
// End
// File content: <文件内容>
1.3.2 、异步任务的分类

rocess.nextTickPromise 都是微任务(Microtasks),但它们的执行优先级不同。

  1. process.nextTick 的回调会在当前操作结束后立即执行,优先级高于 Promise
  2. Promise 的回调会在当前操作结束后,且所有 process.nextTick 回调执行完毕后执行。

Node.js 中的异步任务主要分为两类:

  1. 宏任务(Macro Task)
  • 包括 setTimeoutsetIntervalsetImmediate、I/O 操作、DOM 事件、script 标签等。

    2.微任务(Micro Task)

  • 包括Promise的then、catch、Mutation0bserver、queueMicrotask(特殊:process.nextTick是微任务最早的)等。

事件循环的优先级是:先执行微任务,再执行宏任务

例子:

复制代码
  console.log('task1')

    setTimeout(()=>{
      new Promise((resolve,reject)=>{
        console.log('task2')
        resolve()
      }).then(()=>{
        console.log('task4')
      }).then(()=>{
        console.log('task7')
      })
    },0)

    new Promise((resolve,reject)=>{
      console.log('task3')
      resolve()
    }).then(()=>{
      console.log('task6')
    })

    console.log('task5')

1.同步任务

  • 执行 console.log('task1'),输出 task1
  • 遇到 setTimeout ,当 time 时间结束时将其回调函数注册并放入宏任务队列
  • 执行 new Promise 中的执行器函数,输出 task3
  • 执行器函数中的 resolve 方法执行,将 then 的回调函数注册到微任务队列
  • 执行 console.log('task5'),输出 task5
  • 至此,第一轮的同步任务执行完毕

2.微任务队列

  • 执行 then 的回调函数,输出 task6
  • 微任务队列清空

最终输出顺序是:task1 task3 task5 task6 task2 task4 task7

2、 基于 Node.js 服务器 和 基于 Nginx 转发 的前端项目区别

2.1、 核心概念

  • 基于 Nginx 的前端项目:

1.角色: Nginx 是一个高性能的 静态资源服务器反向代理/负载均衡器

2.特点

3.工作方式:

它接收用户浏览器的请求,然后直接从服务器的文件系统上找到对应的 HTML、CSS、JS、图片等静态文件,并将其快速地发送给浏览器。它只负责"分发",不负责"执行"前端代码(浏览器会执行JS)。如果涉及API请求,它会将这些请求转发(Proxy Pass) 到后端的应用服务器(如 Java, Python, Go, Node.js 应用)。

  • 高并发处理能力:Nginx使用事件驱动的方式处理请求,能够同时处理数万甚至数十万个并发连接。
  • 轻量级:Nginx是一个轻量级的服务器,占用的系统资源非常少。
  • 反向代理:Nginx可以充当反向代理服务器,将客户端请求转发到后端服务器。

1.角色: Node.js 是一个 JavaScript 运行时环境,可以运行服务器端程序。同时提供非阻塞I/O模型,这使得Node.js非常适合构建高性能、可扩展的网络应用程序。

  • 基于 Node.js 的前端项目:

2.特点:

  • 单线程异步I/O:Node.js使用事件循环和异步I/O模型,这使得它能够同时处理大量并发连接。
  • 非阻塞I/O:通过非阻塞I/O,Node.js能够避免长时间等待I/O操作完成,从而提高应用程序的响应速度。
  • 模块化:Node.js支持CommonJS模块系统,这使得代码组织和管理变得容易。

3.工作方式: 你使用 Node.js 编写了一个服务器程序(通常使用 Express、Koa 等框架)。这个程序会监听HTTP请求。当请求到来时,由这个 Node.js 程序来决定如何响应。它可以直接返回一个静态文件,也可以先执行一些服务器端的逻辑(比如服务器端渲染 SSR、用户认证、日志记录、连接数据库等),再生成 HTML 内容返回给浏览器。

2.2、 详细对比

|-----------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| 特性维度 | 基于 Nginx 的前端项目 | 基于 Node.js 的前端项目 |
| 核心角色 | 静态文件服务者反向代理 | 动态Web应用服务器 |
| 处理逻辑 | 简单、直接。收到URL,映射到磁盘文件,返回内容。 | 复杂、灵活。收到请求,可以执行任意JS代码逻辑,再生成响应。 |
| 性能 | 极高。处理静态资源是Nginx的强项,内存占用低,并发能力极强(基于事件驱动和异步IO)。 | 较高,但通常低于Nginx处理静态资源。Node.js也是异步IO,但应用逻辑本身会消耗CPU和内存。 |
| 功能 | 相对单一。主要功能:静态服务、反向代理、负载均衡、缓存、Gzip压缩、SSL终止等。 | 极其丰富 。可以做任何事情: 1. 服务器端渲染(SSR) 2. API 接口 (打造BFF层) 3. 用户会话管理 4. 数据库操作 5. WebSocket 服务 6. 复杂的身份认证和授权 |
| 适用场景 | 纯静态网站传统SPA(单页应用) 、作为CDN源站 、作为后端API的网关。 | 服务端渲染(SSR)应用 (如Next.js, Nuxt.js)、同构应用前端需要少量后端逻辑 的项目(如轻量级API)、全栈JavaScript应用(如MERN/MEAN栈)。 |
| 配置方式 | 主要通过修改 nginx.conf 配置文件,语法自成体系。 | 通过编写 JavaScript 代码,对前端开发者更友好,更灵活。 |
| SEO(搜索引擎优化) | 对传统SPA不友好。因为SPA的HTML初始内容通常是空的,靠JS异步加载,搜索引擎爬虫可能无法获取完整内容。 | 友好。尤其是SSR应用,服务器直接返回渲染好的完整HTML,利于搜索引擎抓取。 |
| 开发流程 | 开发时通常使用 webpack-dev-server 等工具,生产环境才用Nginx。 | |

2.3、现代最流行的架构:两者结合

在实际的生产环境中,几乎不会二选一,而是将它们结合起来,发挥各自最大的优势 。Node.js 本身可以作为一个独立的服务器运行,但在实际生产环境中,通常会结合 Nginx 使用,以充分发挥两者的优势。

这是一种非常经典且高效的架构。对于绝大多数现代前端项目,尤其是React、Vue等框架构建的项目,在生产环境中使用 Nginx 作为静态服务器和反向代理,将动态请求转发给 Node.js(或其它后端语言)服务,是最佳实践。 纯Node.js提供服务更适合全栈项目或需要SSR等特定功能的场景,而纯Nginx则适用于最简单的静态展示页面。

典型工作流程:

1.用户请求 https://www.example.com

2.Nginx (最外层):最先接收到请求。它承担第一道防线和流量指挥官的角色。

  • 静态文件请求(如 /static/js/main.js, /images/logo.png):Nginx 直接快速地从磁盘读取并返回,不再劳烦后面的Node.js,极大减轻应用服务器压力。
  • 动态请求(如 页面请求 /, /about, 或API请求 /api/users):Nginx 通过 proxy_pass 将请求转发给后端的 Node.js 应用服务器。

3.Node.js 服务器:接收到Nginx转发的请求。

  • 如果是页面请求(如 /),它可能执行SSR,从数据库获取数据,渲染出完整的HTML页面。
  • 如果是API请求(如 /api/users),它执行业务逻辑,查询数据库,返回JSON数据。

4.响应返回:Node.js 将处理结果返回给 Nginx,Nginx 再最终返回给用户的浏览器。

这种架构的优势

  1. 性能最大化:Nginx高效处理静态资源,Node.js专心处理动态逻辑。
  2. 安全性增强:Nginx可以作为安全屏障,隐藏后端Node.js服务器的真实端口和内部结构,处理SSL、防止DDoS攻击等。
  3. 可靠性提升:Nginx可以轻松做负载均衡,后面挂载多个Node.js实例,实现高可用。
  4. 便于扩展:每层都可以独立地进行水平扩展。

2.4、总结

Node.js 并不强制要求使用 Nginx,但在生产环境中,结合 Nginx 可以显著提升性能和安全性。Nginx 负责处理静态资源和请求分发,而 Node.js 专注于动态业务逻辑,这种组合是现代 Web 开发中的最佳实践。

|---------------------|------------------------|-------------------------------------|
| 方案 | 本质 | 一句话总结 |
| 纯 Nginx | 一个高效的文件分发员 | "你要什么文件?我给你找。" |
| 纯 Node.js | 一个全能的JavaScript服务员 | "你的请求来了,我现给你做(执行逻辑)。" |
| Nginx + Node.js | 分发员 + 专业厨师 的黄金组合 | "静态小菜(文件)我直接上,大菜(动态内容)让后面的厨师专门为你做。" |

相关推荐
RaidenLiu4 分钟前
从 Provider 迈向 Riverpod 3:核心架构与迁移指南
前端·flutter
前端进阶者5 分钟前
electron-vite_18Less和Sass共用样式指定
前端
数字人直播8 分钟前
稳了!青否数字人分享3大精细化AI直播搭建方案!
前端·后端
江城开朗的豌豆10 分钟前
我在项目中这样处理useEffect依赖引用类型,同事直呼内行
前端·javascript·react.js
听风的码13 分钟前
Vue2封装Axios
开发语言·前端·javascript·vue.js
转转技术团队13 分钟前
前端安全防御策略
前端
掘金一周20 分钟前
被老板逼出来的“表格生成器”:一个前端的自救之路| 掘金一周 8.21
前端·人工智能·后端
cc_z25 分钟前
vue代码优化
前端·vue.js
龙在天29 分钟前
你只会console.log就Out了
前端
用户6817224572130 分钟前
h5实现点击电话进入拨打电话功能
前端