第五部分:第一节 - Node.js 简介与环境:让 JavaScript 走进厨房

我们之前学习的 JavaScript 主要运行在浏览器中,由浏览器内置的 JavaScript 引擎(如 Chrome 的 V8 引擎)来解释执行。Node.js 则是一个JavaScript 运行时环境 ,它也使用了 Chrome 的 V8 引擎,但它不是在浏览器里,而是在服务器端 或者你的本地计算机上运行。这意味着,你可以使用你熟悉的 JavaScript 语言来编写服务器端的代码了!

为什么选择 Node.js 做后端?

Node.js 的设计哲学是事件驱动 (Event-driven)非阻塞 I/O (Non-blocking I/O)

想象一下餐厅厨房:

  • 阻塞 I/O (Blocking I/O) 就像一个厨师在准备一道需要炖 2 小时的菜。在炖的过程中,这个厨师就不能去做其他任何事情,只能干等着。
  • 非阻塞 I/O (Non-blocking I/O) 就像厨师把菜放进炖锅,然后立即 转身去切菜、炒别的菜,当炖锅里的菜好了,计时器会发出事件通知,厨师再去处理。

Node.js 的非阻塞 I/O 使得它在处理大量并发请求时表现出色。它不会因为等待某个耗时操作(比如读取文件、查询数据库、网络请求)而阻塞整个进程,而是通过事件循环 (Event Loop) 在后台处理这些操作,并在完成后触发回调函数(事件),这样就可以同时处理更多的"订单"。这使得 Node.js 非常适合构建高并发的网络应用。

此外,Node.js 和前端使用同一种语言,可以方便地共享代码和开发者资源,这是全栈 JavaScript 的一大优势。

安装 Node.js:

请访问 Node.js 官方网站 (https://nodejs.org/) 下载并安装适合你操作系统的版本。安装 Node.js 会同时安装 npm (Node Package Manager) 包管理器。如果你倾向使用 yarn,可以单独安装 yarn (npm install -g yarn)。

npm/yarn 包管理器与 package.json:

我们之前在前端已经接触过 npm/yarn,用来安装和管理前端库。在 Node.js 项目中,它们同样是管理第三方依赖(比如 Express 框架、数据库驱动等)的核心工具。

package.json 文件是 Node.js 项目的"身份证"和"项目配置清单"。它记录了:

  • 项目的名称 (name)、版本 (version)。
  • 项目的描述 (description)。
  • 项目的入口文件 (main)。
  • 项目使用的脚本命令 (scripts),比如启动服务器、运行测试等。
  • 项目依赖的第三方包 (dependencies) 和开发依赖 (devDependencies)。

初始化一个 Node.js 项目:

bash 复制代码
mkdir my-node-app
cd my-node-app
npm init -y   # 使用 -y 参数跳过交互式提问,快速生成默认的 package.json
# 或者使用 yarn
# yarn init -y

现在你的项目目录下就有了 package.json 文件。

安装第三方包:

bash 复制代码
npm install express   # 安装 express 包到 dependencies (生产环境和开发环境都需要)
npm install typescript --save-dev # 安装 typescript 包到 devDependencies (只在开发环境需要,编译用)
# 或者使用 yarn
# yarn add express
# yarn add typescript --dev

安装后,package.json 文件会更新,记录下这些依赖包及其版本。项目目录下会生成一个 node_modules 目录,所有安装的包都在这里。同时会生成 package-lock.json (npm) 或 yarn.lock (yarn),用于锁定依赖版本,确保团队成员安装到完全一致的环境。

模块系统:CommonJS vs ES Modules:

在 Node.js 发展初期,JavaScript 本身没有模块系统。Node.js 采用了 CommonJS 模块系统,使用 require() 导入模块,使用 module.exportsexports 导出模块。

javascript 复制代码
// CommonJS 导出
// utils.js
const add = (a, b) => a + b;
module.exports = { add };

// CommonJS 导入
// main.js
const utils = require('./utils');
console.log(utils.add(1, 2)); // 3

随着 ES6 标准的发布,JavaScript 有了自己的模块系统 ES Modules (import/export)。较新版本的 Node.js (12+) 已经原生支持 ES Modules,可以通过在 package.json 中设置 "type": "module" 或者使用 .mjs 文件后缀来启用。

javascript 复制代码
// ES Modules 导出
// utils.mjs 或者 utils.js (如果 package.json 中设置了 "type": "module")
export const add = (a, b) => a + b;

// ES Modules 导入
// main.mjs 或者 main.js (如果 package.json 中设置了 "type": "module")
import { add } from './utils.js'; // 注意:在 Node.js 中使用 ES Modules 导入本地文件需要带上文件扩展名 .js 或 .mjs
console.log(add(1, 2)); // 3

在实际项目中,特别是新项目,推荐使用 ES Modules。如果使用 TypeScript,通常也会配置 TypeScript 编译器生成 ES Modules 代码。

小例子:Hello World Node.js 脚本

创建一个文件 hello.js:

javascript 复制代码
// hello.js
console.log("Hello, Node.js!");

在终端运行:

bash 复制代码
node hello.js

你会在终端看到输出 "Hello, Node.js!"。恭喜你,你已经成功在服务器端(本地计算机上)运行了第一段 JavaScript 代码。

小例子:使用 npm 安装和使用第三方包

在你的 my-node-app 项目目录中(确保已经 npm init -y):

bash 复制代码
npm install lodash

创建一个文件 use-lodash.js:

javascript 复制代码
// use-lodash.js
const _ = require('lodash'); // CommonJS 方式导入 lodash

const numbers = [1, 2, 3, 4, 5];
const sum = _.sum(numbers);

console.log("使用 lodash 计算总和:", sum);

运行脚本:

bash 复制代码
node use-lodash.js

输出应为 "使用 lodash 计算总和: 15"。这展示了如何在 Node.js 中使用 npm 安装和导入第三方库。

小结: Node.js 使得 JavaScript 可以运行在服务器端,其事件驱动和非阻塞 I/O 的特性使其适合高并发场景。npm/yarn 是 Node.js 项目的包管理器,package.json 是项目配置清单。Node.js 支持 CommonJS 和 ES Modules 两种模块系统,现代项目推荐使用 ES Modules。

练习:

  1. 在一个新的目录中初始化一个 Node.js 项目。
  2. 安装 fs 模块(fs 是 Node.js 的核心模块,无需安装,直接 require 即可)。
  3. 编写一个 Node.js 脚本,使用 fs.readFile() 方法(异步读取文件)读取一个本地文本文件(例如 package.json),并在文件读取完成后,将文件内容打印到控制台。注意处理读取文件可能出现的错误。
  4. 修改上一个脚本,使用 fs.readFileSync() 方法(同步读取文件),比较两种方法的不同(异步是非阻塞的,同步是阻塞的)。
相关推荐
xun-ming4 小时前
AI时代Java程序员自救手册
java·开发语言·人工智能
张健11564096484 小时前
C++访问控制与友元
java·开发语言·c++
薛定猫AI5 小时前
【深度解析】Gemma Chat 本地 AI 编程 Agent:Electron + MLX + 开源模型的离线 Vibe Coding 实战
javascript·人工智能·electron
2zcode5 小时前
基于MATLAB改进最大熵法的大规模新能源并网概率潮流计算
开发语言·matlab
一只幸运猫.5 小时前
JAVA后端面试题
java·开发语言
全栈前端老曹5 小时前
【前端地图】多地图平台适配方案——高德、百度、腾讯、Google Maps SDK 差异对比、封装统一地图接口
前端·javascript·百度·dubbo·wgs84·gcj-02·bd09
还是阿落呀5 小时前
基本控制结构
开发语言·c++·算法
笑虾5 小时前
Win10 修改注册表 让鼠标悬停PNG上时 tip 始终显示分辨率
开发语言·javascript·ecmascript
lolo大魔王5 小时前
Go语言的并发、协调创建和通信机制
开发语言·golang
xxyy8885 小时前
关于labelimg安装后在标注过程中闪退和死机的问题处理
开发语言·python