Node.js 核心基础
后端核心 Node.js NPM一、后端 Web 开发概述
1.1 前端 vs 后端
| 层面 | 前端(Client Side) | 后端(Server Side) |
|---|---|---|
| 用户可见 | ✅ | ❌ |
| 技术 | HTML + CSS + JS | Node.js / Python / Java 等 |
| 类比 | 餐厅大堂(顾客看到的) | 厨房(顾客看不到的) |
1.2 后端三大组件
浏览器 ←→ 服务器 ←→ 应用程序 ←→ 数据库
(电脑) (逻辑代码) (持久存储)| 组件 | 类比(餐厅) | 职责 |
|---|---|---|
| 服务器(Server) | 整间厨房 | 24/7 运行,监听浏览器请求 |
| 应用程序(Application) | 厨师 + 菜谱 | 根据请求执行业务逻辑 |
| 数据库(Database) | 食品储藏室 | 持久化存储用户数据 |
1.3 请求-响应循环
用户点击按钮
↓
浏览器发送 Request → 服务器
↓
应用程序处理请求 ← 查询数据库
↓
服务器返回 Response → 浏览器
↓
用户看到新页面餐厅类比完整版:
- 顾客(用户)看菜单(网页界面)
- 告诉服务员(HTTP 请求)想要什么
- 服务员将订单送到厨房(服务器)
- 厨师(应用程序)查看菜谱、取食材(数据库)
- 做好菜品(HTML/CSS/JS)送回前台
- 顾客享用(浏览器渲染)
1.4 静态网页 vs Web 应用
| 特性 | 静态网页 | Web 应用 |
|---|---|---|
| 交互性 | 仅展示 | 用户登录、数据处理等 |
| 后端 | 不需要 | 需要服务器 + 应用 + 数据库 |
| 托管 | GitHub Pages 即可 | 需要服务器运行应用 |
| 示例 | 个人博客、作品集 | Gmail、Twitter、Amazon |
1.5 为什么选择 Node.js
| 理由 | 说明 |
|---|---|
| JS 全栈 | 前后端使用同一语言 |
| 最流行 | StackOverflow 调查中 #1 后端框架 |
| 就业需求 | 全栈岗位最常见的要求 |
| 高性能 | 异步非阻塞,适合高并发 |
| 庞大生态 | NPM 拥有数百万开源包 |
| 企业采用 | LinkedIn、Twitter、Netflix、NASA |
二、什么是 Node.js
2.1 定义
Node.js 是一个 异步的、事件驱动的 JavaScript 运行时,专为构建可扩展的网络应用而设计。
关键词解析:
| 概念 | 含义 |
|---|---|
| JavaScript 运行时 | 让 JS 能在 浏览器之外 运行(基于 Chrome 的 V8 引擎) |
| 异步(Asynchronous) | 不需要按顺序等待,可以同时处理多件事 |
| 事件驱动(Event-driven) | 代码在特定事件发生时才执行 |
2.2 同步 vs 异步
同步(Synchronous):
网购 → 站在门口等快递 → 收到后才能做其他事
❌ 浪费时间
异步(Asynchronous):
网购 → 继续做其他事 → 快递到了再处理
✅ 高效2.3 Node.js 解放了 JavaScript
| 之前 | 之后(有了 Node) |
|---|---|
| JS 只能在浏览器中运行 | JS 可以在任何机器上运行 |
| 只能做前端 | 可以做后端、桌面应用、CLI 工具 |
| 受浏览器 API 限制 | 可访问文件系统、网络等 |
三、使用 Node.js
3.1 版本检查
bash
node -v # 查看 Node 版本,应 ≥ 18
npm -v # 查看 NPM 版本3.2 Node REPL
REPL = Read → Eval → Print → Loop
bash
node # 进入 REPL
> 5 + 8 # 13
> let a = 3
> a + 12 # 15
> .exit # 退出(或 Ctrl+C 两次)3.3 运行 JS 文件
bash
# 创建文件
touch index.js
# 写入代码
# console.log("Hello from Node!");
# 运行
node index.js # 输出: Hello from Node!💡 技巧:输入文件名前几个字母后按
Tab自动补全,同时验证你在正确的目录中。
四、原生 Node 模块
4.1 模块概念
原生模块 = Node 自带的 预装工具集,无需额外安装。
类比:就像操作系统预装的小游戏(扫雷、纸牌),开箱即用。
4.2 fs(File System)文件系统
最基础也最重要的原生模块——允许 读写本地文件。
引入方式:
javascript
// CommonJS(旧)
const fs = require("fs");
// ESM(新,推荐)
import fs from "fs";写入文件:
javascript
import fs from "fs";
fs.writeFile("message.txt", "Hello from Node!", (err) => {
if (err) throw err;
console.log("The file has been saved!");
});读取文件:
javascript
fs.readFile("./message.txt", "utf8", (err, data) => {
if (err) throw err;
console.log(data); // "Hello from Node!"
});为什么需要 utf8?
不指定编码时返回的是 Buffer(二进制缓冲区),指定 "utf8" 后返回 可读文本。
4.3 其他常用原生模块
| 模块 | 功能 |
|---|---|
fs | 文件读写 |
http | 创建 HTTP 服务器 |
path | 处理文件路径 |
os | 获取操作系统信息 |
events | 事件处理 |
五、NPM 包管理器
5.1 NPM 是什么
NPM = Node Package Manager
类比:社区工具图书馆 — 开发者共享自己写的工具包,全球开发者免费借用。
- 随 Node.js 一起安装
- 数百万开源包可搜索:npmjs.com
5.2 初始化项目
bash
npm init # 交互式初始化,逐步填写信息
npm init -y # 全部使用默认值(快速初始化)生成 package.json——项目的 配置文件:
json
{
"name": "my-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"author": "Hugo",
"license": "ISC",
"dependencies": {}
}5.3 安装包
bash
# 安装单个包
npm install sillyname
npm i sillyname # 简写
# 安装多个包
npm i inquirer qr-image # 空格分隔
# 安装后自动添加到 package.json 的 dependencies安装后:
package.json新增dependencies字段- 创建
node_modules/目录(存放下载的包代码)
5.4 使用已安装的包
javascript
import generateName from "sillyname";
console.log(`My name is ${generateName()}.`);
// My name is Spot Runner Bison.六、CommonJS vs ESM
6.1 两种模块系统
| 特性 | CommonJS (CJS) | ECMAScript Modules (ESM) |
|---|---|---|
| 语法 | require() / module.exports | import / export |
| 默认 | Node < 12 的默认 | 需在 package.json 中启用 |
| 加载 | 同步 | 异步 |
| 前后端一致 | ❌ 仅后端 | ✅ 前后端统一 |
6.2 启用 ESM
在 package.json 中添加:
json
{
"type": "module"
}6.3 对比示例
javascript
// CommonJS(旧)
const fs = require("fs");
const express = require("express");
// ESM(新,推荐)
import fs from "fs";
import express from "express";不能混用
同一个项目中,require() 和 import 不能混合使用。选定一种后保持一致。
七、QR Code 项目实战 📱
7.1 项目目标
用户输入 URL → 生成 QR 码图片 + 保存 URL 到文本文件。
7.2 使用的包
| 包 | 功能 |
|---|---|
inquirer | 获取用户在命令行中的输入 |
qr-image | 将文本转换为 QR 码 PNG 图片 |
fs(原生) | 写入文件到本地 |
7.3 核心代码
javascript
import inquirer from "inquirer";
import qr from "qr-image";
import fs from "fs";
// 1. 获取用户输入
inquirer
.prompt([
{ message: "Type in your URL:", name: "URL" }
])
.then((answers) => {
const url = answers.URL;
// 2. 生成 QR 码图片
var qr_svg = qr.image(url);
qr_svg.pipe(fs.createWriteStream("qr_image.png"));
// 3. 保存 URL 到文本文件
fs.writeFile("URL.txt", url, (err) => {
if (err) throw err;
console.log("The file has been saved!");
});
})
.catch((error) => {
console.log(error);
});7.4 涉及的知识点
| 知识点 | 在项目中的应用 |
|---|---|
| NPM 安装 | npm i inquirer qr-image |
| ESM 导入 | import ... from "..." |
| 原生 fs 模块 | fs.writeFile()、fs.createWriteStream() |
| Promise 链 | .then().catch() 处理异步结果 |
| package.json | "type": "module" 启用 ESM |
八、Node.js 生态全景
Node.js 生态
├── 原生模块(预装)
│ ├── fs — 文件系统
│ ├── http — HTTP 服务器
│ ├── path — 路径处理
│ └── ...
├── NPM 包(社区)
│ ├── express — Web 框架 ⭐
│ ├── inquirer — 命令行交互
│ ├── qr-image — QR 码生成
│ └── 数百万其他包...
└── 框架层
├── Express.js — 最流行的 Web 框架
├── Next.js — React 全栈框架
└── ...