01-Node.js环境安装与基础

摘要:本文是 Node.js 服务器开发的入门指南,涵盖环境安装、版本管理、模块化系统、npm 包管理、核心模块使用和第一个 HTTP 服务器。通过本文档,你将掌握 Node.js 的基础知识,为后续进阶开发打下坚实基础。

关键词:Node.js、环境安装、npm、模块化、CommonJS、ES Modules、HTTP服务器

适合人群:有 JavaScript 基础、想要学习服务器端开发的开发者

预计完成时间:90 分钟(含所有实践环节)


文章目录

  • [实践 1:环境安装与配置](#实践 1:环境安装与配置)
    • [1.1 Node.js 安装](#1.1 Node.js 安装)
    • [1.2 nvm 版本管理](#1.2 nvm 版本管理)
    • [1.3 npm 包管理器配置](#1.3 npm 包管理器配置)
  • [实践 2:模块化系统](#实践 2:模块化系统)
    • [2.1 CommonJS 模块](#2.1 CommonJS 模块)
    • [2.2 ES Modules 模块](#2.2 ES Modules 模块)
    • [2.3 核心模块 vs 第三方模块](#2.3 核心模块 vs 第三方模块)
  • [实践 3:核心模块使用](#实践 3:核心模块使用)
    • [3.1 fs 文件系统模块](#3.1 fs 文件系统模块)
    • [3.2 path 路径模块](#3.2 path 路径模块)
    • [3.3 events 事件模块](#3.3 events 事件模块)
  • [实践 4:HTTP 服务器](#实践 4:HTTP 服务器)
    • [4.1 创建基础 HTTP 服务器](#4.1 创建基础 HTTP 服务器)
    • [4.2 处理 POST 请求](#4.2 处理 POST 请求)
    • [4.3 静态文件服务器](#4.3 静态文件服务器)
  • [实践 5:项目初始化与配置](#实践 5:项目初始化与配置)
    • [5.1 package.json 详解](#5.1 package.json 详解)
    • [5.2 环境变量配置](#5.2 环境变量配置)
    • [5.3 nodemon 自动重启](#5.3 nodemon 自动重启)
  • 常见问题排查
    • [Q1:node 命令找不到?](#Q1:node 命令找不到?)
    • [Q2:npm install 速度慢?](#Q2:npm install 速度慢?)
    • Q3:端口被占用?
    • [Q4:require 找不到模块?](#Q4:require 找不到模块?)
    • [Q5:ES Modules 语法报错?](#Q5:ES Modules 语法报错?)
  • 学习建议
  • 官方资源

实践 1:环境安装与配置

1.1 Node.js 安装

  目标:正确安装 Node.js 并验证安装成功。

  步骤 1:下载 Node.js

  访问官网:https://nodejs.org/

  • LTS 版本(长期支持版):生产环境推荐,稳定性高
  • Current 版本(最新版):包含最新特性,适合开发测试

  步骤 2:安装(Windows)

  1. 下载 .msi 安装包
  2. 双击运行,按提示完成安装
  3. 安装时勾选 "Add to PATH"(添加到环境变量)

  步骤 3:验证安装

bash 复制代码
# 查看 Node.js 版本
node -v
# 输出:v18.17.0 或更高

# 查看 npm 版本
npm -v
# 输出:9.6.7 或更高

  步骤 4:第一个 Node.js 程序

  创建 hello.js:

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

  运行:

bash 复制代码
node hello.js
# 输出:Hello, Node.js!

1.2 nvm 版本管理

  目标:使用 nvm 管理多个 Node.js 版本,适应不同项目需求。

  步骤 1:安装 nvm-windows

  下载地址:https://github.com/coreybutler/nvm-windows/releases

  下载 nvm-setup.exe 并安装。

  步骤 2:常用命令

bash 复制代码
# 查看可安装版本
nvm list available

# 安装指定版本
nvm install 18.17.0
nvm install 20.5.0

# 查看已安装版本
nvm list

# 切换版本
nvm use 18.17.0

# 设置默认版本
nvm alias default 18.17.0

  步骤 3:验证切换

bash 复制代码
nvm use 18.17.0
node -v
# 输出:v18.17.0

nvm use 20.5.0
node -v
# 输出:v20.5.0

1.3 npm 包管理器配置

  目标:配置 npm 提升包安装速度,设置全局安装路径。

  步骤 1:配置国内镜像

bash 复制代码
# 使用淘宝镜像
npm config set registry https://registry.npmmirror.com

# 验证配置
npm config get registry
# 输出:https://registry.npmmirror.com

  步骤 2:配置全局安装路径

bash 复制代码
# 创建全局安装目录
mkdir C:\Users\你的用户名\nodejs\global
mkdir C:\Users\你的用户名\nodejs\cache

# 配置 npm
npm config set prefix "C:\Users\你的用户名\nodejs\global"
npm config set cache "C:\Users\你的用户名\nodejs\cache"

# 将全局安装路径添加到系统环境变量 PATH

  步骤 3:常用 npm 命令

bash 复制代码
# 初始化项目
npm init
npm init -y  # 跳过问答,使用默认配置

# 安装依赖
npm install express          # 安装到当前项目
npm install -g nodemon       # 全局安装
npm install lodash --save    # 安装并保存到 dependencies
npm install jest --save-dev  # 安装到 devDependencies

# 查看依赖
npm list                     # 查看当前项目依赖
npm list -g                  # 查看全局依赖

# 更新依赖
npm update                   # 更新所有依赖
npm update express           # 更新指定依赖

# 卸载依赖
npm uninstall express
npm uninstall -g nodemon

实践 2:模块化系统

2.1 CommonJS 模块

  目标:掌握 Node.js 默认的模块化规范。

  步骤 1:导出模块

  创建 math.js:

javascript 复制代码
// 方式 1:导出单个函数
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

// 导出多个函数
module.exports = {
  add,
  subtract
};

  步骤 2:导入模块

  创建 app.js:

javascript 复制代码
// 导入自定义模块(需要相对路径)
const math = require('./math');

console.log(math.add(5, 3));       // 输出:8
console.log(math.subtract(5, 3));  // 输出:2

  步骤 3:导出单个值

  创建 config.js:

javascript 复制代码
// 导出单个对象
module.exports = {
  port: 3000,
  host: 'localhost',
  database: {
    host: '127.0.0.1',
    port: 5432,
    name: 'myapp'
  }
};

  使用:

javascript 复制代码
const config = require('./config');
console.log(config.port);  // 输出:3000

  步骤 4:模块缓存机制

javascript 复制代码
// counter.js
let count = 0;

module.exports = {
  increment: () => ++count,
  getCount: () => count
};

  测试:

javascript 复制代码
const counter1 = require('./counter');
const counter2 = require('./counter');

counter1.increment();
console.log(counter1.getCount());  // 输出:1
console.log(counter2.getCount());  // 输出:1(同一个模块实例)

  说明 :Node.js 会缓存已加载的模块,多次 require 返回同一个实例。

2.2 ES Modules 模块

  目标:使用现代 ES6 模块化语法。

  步骤 1:启用 ES Modules

  在 package.json 中添加:

json 复制代码
{
  "type": "module"
}

  或者使用 .mjs 文件扩展名。

  步骤 2:导出模块

  创建 utils.mjs:

javascript 复制代码
// 命名导出
export function formatName(first, last) {
  return `${first} ${last}`;
}

export function calculateAge(birthYear) {
  return new Date().getFullYear() - birthYear;
}

// 默认导出
export default class User {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    return `Hello, ${this.name}!`;
  }
}

  步骤 3:导入模块

  创建 app.mjs:

javascript 复制代码
// 导入默认导出
import User from './utils.mjs';

// 导入命名导出
import { formatName, calculateAge } from './utils.mjs';

const user = new User('张三');
console.log(user.greet());  // 输出:Hello, 张三!

console.log(formatName('张', '三'));  // 输出:张三
console.log(calculateAge(1990));      // 输出:34(根据当前年份)

  步骤 4:动态导入

javascript 复制代码
// 条件加载模块
async function loadModule(condition) {
  if (condition) {
    const moduleA = await import('./moduleA.mjs');
    moduleA.doSomething();
  } else {
    const moduleB = await import('./moduleB.mjs');
    moduleB.doSomething();
  }
}

loadModule(true);

2.3 核心模块 vs 第三方模块

  目标:理解不同类型模块的导入方式。

javascript 复制代码
// 核心模块(无需安装,直接使用)
const fs = require('fs');
const path = require('path');
const http = require('http');

// 第三方模块(需 npm install)
const express = require('express');
const lodash = require('lodash');

// 自定义模块(需相对路径)
const utils = require('./utils');
const config = require('./config');

  模块解析顺序:

  1. 核心模块(如 fs、http)
  2. node_modules 中的第三方模块
  3. 相对路径的自定义模块

实践 3:核心模块使用

3.1 fs 文件系统模块

  目标:掌握文件读写、目录操作等文件系统操作。

  步骤 1:读取文件

  创建 test.txt:

复制代码
Hello, Node.js!
这是测试文件内容。

  同步读取:

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

// 同步读取(阻塞)
const data = fs.readFileSync('./test.txt', 'utf8');
console.log(data);

  异步读取(推荐):

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

// 异步读取(非阻塞)
async function readFile() {
  try {
    const data = await fs.readFile('./test.txt', 'utf8');
    console.log(data);
  } catch (error) {
    console.error('读取文件失败:', error);
  }
}

readFile();

  步骤 2:写入文件

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

async function writeFile() {
  try {
    // 写入文件(覆盖)
    await fs.writeFile('./output.txt', 'Hello, World!', 'utf8');
    console.log('文件写入成功');
    
    // 追加内容
    await fs.appendFile('./output.txt', '\n追加的内容');
    console.log('内容追加成功');
  } catch (error) {
    console.error('写入文件失败:', error);
  }
}

writeFile();

  步骤 3:目录操作

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

async function directoryOperations() {
  try {
    // 创建目录
    await fs.mkdir('./uploads', { recursive: true });
    console.log('目录创建成功');
    
    // 读取目录内容
    const files = await fs.readdir('./');
    console.log('目录内容:', files);
    
    // 获取文件信息
    const stats = await fs.stat('./test.txt');
    console.log('文件大小:', stats.size, '字节');
    console.log('创建时间:', stats.birthtime);
    console.log('修改时间:', stats.mtime);
    
    // 删除文件
    await fs.unlink('./output.txt');
    console.log('文件删除成功');
    
    // 删除目录
    await fs.rmdir('./uploads');
    console.log('目录删除成功');
  } catch (error) {
    console.error('操作失败:', error);
  }
}

directoryOperations();

3.2 path 路径模块

  目标:掌握跨平台路径处理,避免路径错误。

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

// 路径拼接(推荐,跨平台兼容)
const fullPath = path.join('users', 'uploads', 'avatar.jpg');
console.log(fullPath);  // Windows: users\uploads\avatar.jpg, Linux: users/uploads/avatar.jpg

// 获取绝对路径
const absolutePath = path.resolve('./test.txt');
console.log(absolutePath);  // C:\Users\...\test.txt

// 获取文件名
console.log(path.basename('/users/uploads/avatar.jpg'));  // avatar.jpg

// 获取扩展名
console.log(path.extname('avatar.jpg'));  // .jpg

// 获取目录名
console.log(path.dirname('/users/uploads/avatar.jpg'));  // /users/uploads

// 解析路径
const parsed = path.parse('/users/uploads/avatar.jpg');
console.log(parsed);
// {
//   root: '/',
//   dir: '/users/uploads',
//   base: 'avatar.jpg',
//   ext: '.jpg',
//   name: 'avatar'
// }

3.3 events 事件模块

  目标:理解事件驱动编程,掌握 EventEmitter 使用。

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

// 创建事件发射器
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

// 监听事件
myEmitter.on('greeting', (name) => {
  console.log(`Hello, ${name}!`);
});

// 监听一次
myEmitter.once('onceEvent', () => {
  console.log('这个事件只会触发一次');
});

// 发射事件
myEmitter.emit('greeting', '张三');  // 输出:Hello, 张三!
myEmitter.emit('onceEvent');         // 输出:这个事件只会触发一次
myEmitter.emit('onceEvent');         // 无输出(已移除监听器)

// 移除监听器
const handler = () => {
  console.log('处理函数');
};

myEmitter.on('data', handler);
myEmitter.emit('data');       // 输出:处理函数
myEmitter.removeListener('data', handler);
myEmitter.emit('data');       // 无输出

  实战:订单事件系统

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

class OrderSystem extends EventEmitter {
  createOrder(orderId) {
    console.log(`创建订单: ${orderId}`);
    this.emit('orderCreated', orderId);
  }
  
  payOrder(orderId) {
    console.log(`支付订单: ${orderId}`);
    this.emit('orderPaid', orderId);
  }
  
  shipOrder(orderId) {
    console.log(`发货订单: ${orderId}`);
    this.emit('orderShipped', orderId);
  }
}

const orderSystem = new OrderSystem();

// 监听订单事件
orderSystem.on('orderCreated', (orderId) => {
  console.log(`[通知] 订单 ${orderId} 已创建,等待支付`);
});

orderSystem.on('orderPaid', (orderId) => {
  console.log(`[通知] 订单 ${orderId} 已支付,准备发货`);
});

orderSystem.on('orderShipped', (orderId) => {
  console.log(`[通知] 订单 ${orderId} 已发货`);
});

// 测试流程
orderSystem.createOrder('ORD001');
orderSystem.payOrder('ORD001');
orderSystem.shipOrder('ORD001');

实践 4:HTTP 服务器

4.1 创建基础 HTTP 服务器

  目标:使用 Node.js 内置 http 模块创建 Web 服务器。

  步骤 1:最简单的服务器

  创建 server.js:

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

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

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

  运行:

bash 复制代码
node server.js

  访问:http://localhost:3000

  步骤 2:处理不同路由

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

const server = http.createServer((req, res) => {
  const url = req.url;
  const method = req.method;
  
  // 设置响应头
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
  
  // 路由处理
  if (url === '/' && method === 'GET') {
    res.statusCode = 200;
    res.end(JSON.stringify({ message: '欢迎使用 API' }));
  } else if (url === '/users' && method === 'GET') {
    res.statusCode = 200;
    res.end(JSON.stringify({
      users: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' }
      ]
    }));
  } else if (url === '/about' && method === 'GET') {
    res.statusCode = 200;
    res.end(JSON.stringify({ about: '这是一个 Node.js HTTP 服务器示例' }));
  } else {
    res.statusCode = 404;
    res.end(JSON.stringify({ error: '路由不存在' }));
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

  测试:

bash 复制代码
# 测试不同路由
curl http://localhost:3000/
curl http://localhost:3000/users
curl http://localhost:3000/about
curl http://localhost:3000/notfound

4.2 处理 POST 请求

  目标:接收并解析 POST 请求体数据。

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

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
  
  // 处理 POST 请求
  if (req.url === '/users' && req.method === 'POST') {
    let body = '';
    
    // 监听数据块
    req.on('data', (chunk) => {
      body += chunk.toString();
    });
    
    // 数据接收完成
    req.on('end', () => {
      try {
        const userData = JSON.parse(body);
        console.log('接收到用户数据:', userData);
        
        res.statusCode = 201;
        res.end(JSON.stringify({
          message: '用户创建成功',
          user: userData
        }));
      } catch (error) {
        res.statusCode = 400;
        res.end(JSON.stringify({ error: '无效的 JSON 数据' }));
      }
    });
  } else {
    res.statusCode = 404;
    res.end(JSON.stringify({ error: '路由不存在' }));
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

  测试:

bash 复制代码
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name": "张三", "age": 25}'

4.3 静态文件服务器

  目标:提供静态文件访问服务。

  创建目录结构:

复制代码
project/
├── server.js
└── public/
    ├── index.html
    └── style.css

  创建 public/index.html:

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>静态文件服务器</title>
  <link rel="stylesheet" href="/style.css">
</head>
<body>
  <h1>欢迎使用静态文件服务器</h1>
  <p>这是一个 HTML 文件</p>
</body>
</html>

  创建 public/style.css:

css 复制代码
body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
  text-align: center;
  padding: 50px;
}

h1 {
  color: #333;
}

  创建 server.js:

javascript 复制代码
const http = require('http');
const fs = require('fs').promises;
const path = require('path');

const MIME_TYPES = {
  '.html': 'text/html; charset=utf-8',
  '.css': 'text/css; charset=utf-8',
  '.js': 'application/javascript; charset=utf-8',
  '.json': 'application/json; charset=utf-8',
  '.png': 'image/png',
  '.jpg': 'image/jpeg',
  '.gif': 'image/gif'
};

const server = http.createServer(async (req, res) => {
  // 默认访问 index.html
  let filePath = req.url === '/' ? '/index.html' : req.url;
  filePath = path.join('./public', filePath);
  
  // 获取文件扩展名
  const extname = path.extname(filePath);
  const contentType = MIME_TYPES[extname] || 'application/octet-stream';
  
  try {
    // 读取文件
    const content = await fs.readFile(filePath);
    res.statusCode = 200;
    res.setHeader('Content-Type', contentType);
    res.end(content);
  } catch (error) {
    if (error.code === 'ENOENT') {
      res.statusCode = 404;
      res.setHeader('Content-Type', 'text/html; charset=utf-8');
      res.end('<h1>404 - 文件未找到</h1>');
    } else {
      res.statusCode = 500;
      res.end('服务器内部错误');
    }
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`静态文件服务器运行在 http://localhost:${PORT}`);
});

  测试:

  访问 http://localhost:3000 查看 HTML 页面,CSS 样式会自动加载。


实践 5:项目初始化与配置

5.1 package.json 详解

  目标:理解项目配置文件的每个字段含义。

  创建项目:

bash 复制代码
mkdir my-node-app
cd my-node-app
npm init -y

  编辑 package.json:

json 复制代码
{
  "name": "my-node-app",
  "version": "1.0.0",
  "description": "我的第一个 Node.js 应用",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": ["nodejs", "tutorial"],
  "author": "你的名字",
  "license": "MIT",
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}

  字段说明:

字段 说明
name 项目名称(小写,无空格)
version 版本号(语义化版本)
main 入口文件
scripts 自定义命令
dependencies 生产环境依赖
devDependencies 开发环境依赖
engines Node.js 版本要求

5.2 环境变量配置

  目标:使用环境变量管理配置,区分开发/生产环境。

  步骤 1:使用 process.env

  创建 config.js:

javascript 复制代码
const config = {
  port: process.env.PORT || 3000,
  host: process.env.HOST || 'localhost',
  nodeEnv: process.env.NODE_ENV || 'development',
  database: {
    host: process.env.DB_HOST || '127.0.0.1',
    port: process.env.DB_PORT || 5432,
    name: process.env.DB_NAME || 'myapp',
    user: process.env.DB_USER || 'root',
    password: process.env.DB_PASSWORD || ''
  }
};

module.exports = config;

  使用:

javascript 复制代码
const config = require('./config');

console.log(`运行环境: ${config.nodeEnv}`);
console.log(`服务器端口: ${config.port}`);
console.log(`数据库: ${config.database.host}:${config.database.port}`);

  步骤 2:使用 dotenv 管理环境变量

  安装:

bash 复制代码
npm install dotenv

  创建 .env 文件:

复制代码
NODE_ENV=development
PORT=3000
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=myapp
DB_USER=root
DB_PASSWORD=123456

  创建 .env.example 文件(提交到 Git):

复制代码
NODE_ENV=development
PORT=3000
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=myapp
DB_USER=root
DB_PASSWORD=

  重要 :将 .env 添加到 .gitignore,不要提交敏感信息!

复制代码
# .gitignore
node_modules/
.env

  使用:

javascript 复制代码
require('dotenv').config();

const config = {
  port: process.env.PORT || 3000,
  nodeEnv: process.env.NODE_ENV || 'development',
  database: {
    host: process.env.DB_HOST,
    password: process.env.DB_PASSWORD
  }
};

console.log(config);

5.3 nodemon 自动重启

  目标:开发时自动重启服务器,提升开发效率。

  安装:

bash 复制代码
npm install -D nodemon

  修改 package.json:

json 复制代码
{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  }
}

  运行:

bash 复制代码
npm run dev

  现在修改代码后,服务器会自动重启。

  创建 nodemon.json 配置(可选):

json 复制代码
{
  "watch": ["src/"],
  "ext": "js,json",
  "ignore": ["node_modules/", "test/"],
  "delay": "1000"
}

常见问题排查

Q1:node 命令找不到?

  原因:Node.js 未正确安装或未添加到 PATH。

  解决:

bash 复制代码
# Windows:重新安装 Node.js,勾选 "Add to PATH"
# 或手动添加 Node.js 安装目录到系统环境变量 PATH

Q2:npm install 速度慢?

  解决:使用国内镜像

bash 复制代码
npm config set registry https://registry.npmmirror.com

Q3:端口被占用?

  错误信息 :Error: listen EADDRINUSE: address already in use :::3000

  解决:

bash 复制代码
# Windows 查找占用端口的进程
netstat -ano | findstr :3000
taskkill /PID 进程ID /F

# Linux/macOS
lsof -i :3000
kill -9 进程ID

Q4:require 找不到模块?

  错误信息 :Error: Cannot find module 'xxx'

  解决:

bash 复制代码
# 检查是否已安装
npm list xxx

# 重新安装
npm install xxx

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

Q5:ES Modules 语法报错?

  错误信息 :SyntaxError: Cannot use import statement outside a module

  解决:

  在 package.json 中添加:

json 复制代码
{
  "type": "module"
}

  或使用 .mjs 扩展名。


学习建议

  1. 先掌握 CommonJS :大多数现有项目使用 CommonJS,先熟练使用再学 ES Modules

  2. 理解异步编程 :Node.js 的核心是异步,务必理解回调、Promise、async/await

  3. 动手实践 :不要只看文档,一定要动手写代码

  4. 查看官方文档 :遇到问题优先查阅官方文档:https://nodejs.org/docs

  5. 使用版本控制:项目代码使用 Git 管理,方便回滚和协作

官方资源

相关推荐
damoluomu3 小时前
Directus 换掉 GPL 之后,Node.js CMS 到底怎么选?(二)
node.js
孟陬4 小时前
JavaScript 反引号(` backtick)和双引号的不完全等价 ≠ 场景
javascript·node.js·bun
幸运小圣1 天前
Buffer 新手入门【Node.js】
node.js·编辑器·vim
jj_ccwgw1 天前
从 0 到 1 搭建 pnpm + Workspaces + Turborepo Monorepo 保姆级指南
前端·node.js
梦想平凡1 天前
棋牌游戏技术实战(一):用 Node.js 实现房间消息队列、请求幂等与断线恢复
游戏·node.js
小天源1 天前
GEO 品牌监测系统实战:基于 Node.js + Playwright 实现多平台采集与报告导出
人工智能·node.js·geo·品牌检测·ai诊断
damoluomu1 天前
Directus 换掉 GPL 之后,Node.js CMS 到底怎么选?(一)
node.js
guslegend2 天前
脚手架入门:必要性、核心功能与执行原理
前端·架构·node.js·脚手架·前端工程化
HaipengYu3 天前
深度解密 OpenCode 2 插件加载机制:Dual-Version (V1/V2) 适配实战与官方文档的“隐形陷阱”
node.js