Skip to content

Node.js 入门指南

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它允许我们在服务器端运行 JavaScript 代码。本文将介绍 Node.js 的核心概念和使用方法。

1. 安装 Node.js

Windows

  1. 访问 Node.js 官网
  2. 下载 LTS 版本的安装包
  3. 运行安装程序,按照提示完成安装
  4. 打开命令提示符,运行 node -v 验证安装

macOS

  1. 访问 Node.js 官网
  2. 下载 LTS 版本的安装包
  3. 运行安装程序,按照提示完成安装
  4. 打开终端,运行 node -v 验证安装

Linux

bash
# 使用包管理器安装
# Ubuntu/Debian
sudo apt update
sudo apt install nodejs npm

# CentOS/RHEL
sudo yum install nodejs npm

# 验证安装
node -v
npm -v

2. 基本概念

模块系统

Node.js 使用 CommonJS 模块系统。

javascript
// 导出模块
// math.js
function add(a, b) {
  return a + b;
}

module.exports = {
  add
};

// 导入模块
// app.js
const math = require('./math');
console.log(math.add(1, 2)); // 3

包管理

Node.js 使用 npm 作为包管理器。

bash
# 初始化项目
npm init

# 安装包
npm install express

# 安装开发依赖
npm install --save-dev nodemon

# 运行脚本
npm run start

事件循环

Node.js 使用事件循环来处理异步操作。

javascript
console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 0);

console.log('End');

// 输出顺序:Start, End, Timeout

3. 核心模块

fs 模块

用于文件系统操作。

javascript
const fs = require('fs');

// 读取文件(同步)
try {
  const data = fs.readFileSync('file.txt', 'utf8');
  console.log(data);
} catch (err) {
  console.error(err);
}

// 读取文件(异步)
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

// 写入文件
fs.writeFile('file.txt', 'Hello Node.js', (err) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log('File written successfully');
});

http 模块

用于创建 HTTP 服务器。

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:3000/');
});

path 模块

用于处理文件路径。

javascript
const path = require('path');

// 连接路径
const fullPath = path.join(__dirname, 'file.txt');
console.log(fullPath);

// 获取文件名
const fileName = path.basename(fullPath);
console.log(fileName);

// 获取扩展名
const extName = path.extname(fullPath);
console.log(extName);

os 模块

用于获取操作系统信息。

javascript
const os = require('os');

// 获取操作系统类型
console.log(os.type());

// 获取操作系统版本
console.log(os.release());

// 获取内存信息
console.log(os.totalmem());
console.log(os.freemem());

// 获取 CPU 信息
console.log(os.cpus());

events 模块

用于处理事件。

javascript
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

// 监听事件
myEmitter.on('event', () => {
  console.log('An event occurred!');
});

// 触发事件
myEmitter.emit('event');

4. 异步编程

回调函数

javascript
function fetchData(callback) {
  setTimeout(() => {
    callback(null, 'Data fetched successfully');
  }, 1000);
}

fetchData((err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

Promise

javascript
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(err => console.error(err));

async/await

javascript
async function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
}

async function main() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

main();

5. 文件系统

同步操作

javascript
const fs = require('fs');

// 读取文件
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);

// 写入文件
fs.writeFileSync('file.txt', 'Hello Node.js');
console.log('File written successfully');

// 追加文件
fs.appendFileSync('file.txt', '\nAppend content');
console.log('File appended successfully');

// 删除文件
fs.unlinkSync('file.txt');
console.log('File deleted successfully');

异步操作

javascript
const fs = require('fs');

// 读取文件
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

// 写入文件
fs.writeFile('file.txt', 'Hello Node.js', (err) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log('File written successfully');
});

// 追加文件
fs.appendFile('file.txt', '\nAppend content', (err) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log('File appended successfully');
});

// 删除文件
fs.unlink('file.txt', (err) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log('File deleted successfully');
});

6. HTTP 服务器

基本服务器

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:3000/');
});

处理不同路由

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  
  if (req.url === '/') {
    res.end('Home page\n');
  } else if (req.url === '/about') {
    res.end('About page\n');
  } else {
    res.statusCode = 404;
    res.end('Not found\n');
  }
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:3000/');
});

处理 POST 请求

javascript
const http = require('http');
const querystring = require('querystring');

const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/submit') {
    let body = '';
    req.on('data', chunk => {
      body += chunk.toString();
    });
    req.on('end', () => {
      const data = querystring.parse(body);
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/plain');
      res.end(`Name: ${data.name}\nEmail: ${data.email}\n`);
    });
  } else {
    res.statusCode = 404;
    res.end('Not found\n');
  }
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:3000/');
});

7. 包管理

package.json

json
{
  "name": "my-nodejs-app",
  "version": "1.0.0",
  "description": "A Node.js application",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.7"
  },
  "keywords": ["nodejs", "express"],
  "author": "Your Name",
  "license": "MIT"
}

安装依赖

bash
# 安装所有依赖
npm install

# 安装特定依赖
npm install express

# 安装开发依赖
npm install --save-dev nodemon

# 卸载依赖
npm uninstall express

运行脚本

bash
# 运行 start 脚本
npm start

# 运行 dev 脚本
npm run dev

8. 调试

使用 console

javascript
console.log('Debug message');
console.error('Error message');
console.warn('Warning message');
console.info('Info message');

使用 debugger

  1. 在代码中添加 debugger; 语句
  2. 使用 node --inspect app.js 运行应用
  3. 在 Chrome 中打开 chrome://inspect
  4. 点击 "Open dedicated DevTools for Node"

使用 nodemon

bash
# 安装 nodemon
npm install --save-dev nodemon

# 运行应用
npx nodemon app.js

9. 部署

本地部署

bash
# 安装依赖
npm install

# 运行应用
npm start

云部署

Heroku

  1. 安装 Heroku CLI
  2. 登录 Heroku:heroku login
  3. 创建 Heroku 应用:heroku create
  4. 部署代码:git push heroku master
  5. 打开应用:heroku open

AWS

  1. 创建 EC2 实例
  2. 安装 Node.js
  3. 上传代码
  4. 安装依赖
  5. 运行应用

Docker

dockerfile
FROM node:14

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

10. 最佳实践

  1. 使用 async/await:避免回调地狱
  2. 错误处理:使用 try/catch 处理错误
  3. 模块化:将代码拆分为多个模块
  4. 环境变量:使用 .env 文件存储配置
  5. 日志记录:使用 winston 或 bunyan 进行日志记录
  6. 测试:使用 mocha 或 jest 进行测试
  7. 代码风格:使用 ESLint 和 Prettier
  8. 版本控制:使用 Git 进行版本控制
  9. 依赖管理:定期更新依赖
  10. 安全性:使用 helmet 等安全中间件

11. 常见问题

端口被占用

bash
# 查找占用端口的进程
lsof -i :3000

# 终止进程
kill -9 <PID>

依赖冲突

bash
# 清除缓存
npm cache clean --force

# 重新安装依赖
rm -rf node_modules package-lock.json
npm install

内存泄漏

  • 使用 node --inspect 进行调试
  • 使用 heapdump 生成堆快照
  • 使用 clinic 进行性能分析

12. 总结

Node.js 是一个强大的 JavaScript 运行时环境,它使我们能够在服务器端运行 JavaScript 代码。通过学习 Node.js,我们可以构建高性能的后端应用程序。

Node.js 的核心特性包括:

  • 非阻塞 I/O
  • 事件驱动
  • 单线程
  • 跨平台

Node.js 已经成为后端开发的主流技术,许多大型公司都在使用 Node.js 构建他们的应用程序。掌握 Node.js 是现代后端开发者的必备技能。