在这篇文章中,我们将一起深入探讨如何使用 Express.js —— 这个 Node.js 生态中最流行的 Web 框架,来构建你的第一个 Web 服务。仅仅打印 "Hello, World!" 虽然看起来简单,但它是我们理解 HTTP 请求处理流程、路由机制以及中间件原理的绝佳起点。我们将不止步于简单的代码实现,还会一起学习这些代码背后的工作原理,以及在真实开发环境中需要注意的配置细节。
通过这篇文章,你将学会如何从零搭建一个 Express 服务器,掌握三种不同的响应处理方式,并了解在实际项目开发中如何组织代码、避免常见错误以及优化服务器性能。无论你是刚接触后端开发的新手,还是希望巩固基础知识的开发者,这篇文章都将为你提供扎实的实战经验。
环境准备与现代化开发工具链
在开始编写代码之前,我们需要确保本地开发环境已经就绪。这就像烹饪前要准备好厨具和食材一样重要。而在 2026 年,我们的“厨具”不仅仅是 Node.js,还包括了强大的 AI 辅助编程工具。
- 安装 Node.js:Express.js 是基于 Node.js 运行的,你需要访问 Node.js 官网下载并安装 LTS(长期支持)版本。建议使用 Node.js 的版本管理工具(如 INLINECODE07728983 或 INLINECODEb7605c54)来灵活切换版本。
- 初始化项目:打开你的终端或命令行工具,创建一个新文件夹并进入其中,然后运行以下命令来初始化一个新的 Node.js 项目:
mkdir express-hello-world
cd express-hello-world
npm init -y
这将会在你的项目根目录下生成一个 package.json 文件,用于管理项目的依赖和脚本。
- 安装 Express:接下来,我们需要安装 Express 框架。在终端中运行:
npm install express
- 拥抱 AI 辅助开发:在 2026 年,我们强烈建议使用 Cursor 或集成了 GitHub Copilot 的 VS Code 作为你的 IDE。作为开发者,我们经常利用这些工具进行“氛围编程”。当你输入
// Initialize express server时,AI 会自动补全后续的样板代码,这不仅提升了效率,还能让我们更专注于业务逻辑而非语法细节。
方法 1:使用基础路由 —— 理解 HTTP 的本质
这是最标准、最常见的一种方式。在 Web 开发中,“路由”指的是应用程序端点(URI)如何响应客户端请求。通过定义一个根 URL(即 "/")的路由,我们可以告诉服务器:“当用户访问网站首页时,应该做什么?”。
#### 代码实现
让我们创建一个名为 app.js 的文件,并写入以下代码:
// 引入 express 模块
const express = require(‘express‘);
// 创建应用实例
const app = express();
// 定义根路径 ‘/‘ 的 GET 请求路由
app.get(‘/‘, (req, res) => {
// 发送响应给客户端
res.send(‘目录
Hello, World!
‘);
});
// 启动服务器并监听 8000 端口
app.listen(8000, () => {
console.log(`应用程序正在运行,访问地址:http://localhost:8000`);
});
#### 深度解析
在这段代码中,我们首先引入了 Express 模块并创建了一个应用对象 INLINECODE2c72d14b。核心部分在于 INLINECODEc4595eee 这一行。
- INLINECODE828d7c03:这是一个用于监听 HTTP GET 请求的方法。第一个参数 INLINECODE5a94421a 代表路径,也就是网站的根目录。当用户在浏览器中输入
http://localhost:8000/时,就会触发这个回调函数。 - 回调函数
(req, res):这是处理请求的具体逻辑。
* req (Request):代表了 HTTP 请求对象,包含了请求头、查询参数、请求体等信息。虽然在这个简单的例子中我们没有用到它,但在处理用户提交数据(如表单)时,它是不可或缺的。
* INLINECODE07fdb4c4 (Response):代表了 HTTP 响应对象。我们调用 INLINECODEebc3145c 方法来向浏览器发送数据。这里我们发送了一个 HTML 字符串 ‘
Hello, World!
‘,浏览器会将其渲染为大标题。
方法 2:使用箭头函数与极简写法 —— 现代 JS 风格
随着 JavaScript 语言的发展(特别是 ES6 标准的引入),我们可以使用更简洁的语法来编写代码。箭头函数不仅代码量更少,而且在处理 this 关键词的绑定上具有词法作用域的特性,这让代码在特定场景下更易于阅读和维护。
#### 代码实现
让我们用更现代的风格重写上面的例子:
const express = require(‘express‘);
const app = express();
// 使用箭头函数定义路由,语法更紧凑
// 如果回调函数体只有一行,可以省略花括号 {}
app.get(‘/‘, (req, res) => res.send(‘Hello, World! from Arrow Function
‘));
// 同样,监听部分的回调函数也可以使用箭头函数简写
app.listen(8000, () => console.log(‘极简服务器正在运行在端口 8000‘));
// 实用见解:增加一个二级路由,展示灵活性
app.get(‘/about‘, (req, res) => {
res.send(‘关于我们页面
这是使用箭头函数创建的另一个页面。
‘);
});
方法 3:使用中间件机制 —— 构建可扩展的架构
中间件是 Express 的核心概念之一。你可以把它理解为 HTTP 请求处理流程中的“过滤器”或“关卡”。一个请求发送到服务器后,会经过一系列的中间件处理,最后才可能发送响应给客户端。
使用 INLINECODE718c9230 可以加载中间件。如果在 INLINECODE287e0f7d 中直接发送响应而不调用 next(),那么这个中间件就会拦截所有请求,直接结束响应流程。这对于实现自定义的 404 页面或者特定的拦截逻辑非常有用。
#### 代码实现
下面我们使用中间件来为所有路径(不仅仅是根路径)打印 "Hello, World!"。
const express = require(‘express‘);
const app = express();
// 定义一个中间件函数
// 这个函数会接收每一个到达服务器的请求
const loggerMiddleware = (req, res, next) => {
console.log(`[${new Date().toISOString()}] 收到请求: ${req.method} ${req.url}`);
// 调用 next() 将控制权交给下一个中间件或路由
next();
};
// 使用自定义中间件
app.use(loggerMiddleware);
// 使用中间件响应所有请求
// 这里没有指定路径,意味着无论是访问 /, /user, 还是 /api,都会执行这里
app.use((req, res) => {
res.send(‘Hello, World! from Middleware
‘);
});
app.listen(8000, () => console.log(‘服务器已启动,监听端口 8000‘));
2026 进阶实战:生产级代码与性能优化
仅仅让代码跑通是不够的,作为一名专业的开发者,我们还需要关注代码的健壮性和性能。随着 AI 原生应用和边缘计算的普及,Express 服务的性能优化和安全性变得前所未有的重要。下面让我们探讨一些在 2026 年依然适用的实战技巧。
#### 1. 环境变量与配置管理
在前面的例子中,我们将端口硬编码为 8000。在实际开发或部署到云服务器(如 Vercel, AWS Lambda, 或 Railway)时,端口通常是动态分配的。最佳实践是从环境变量中读取端口。
// 默认使用 3000 端口,但如果环境变量中定义了 PORT,则使用该端口
const PORT = process.env.PORT || 3000;
// 启用信任代理(这在云原生和反向代理环境下至关重要)
app.set(‘trust proxy‘, true);
app.listen(PORT, () => {
console.log(`生产服务器运行在端口 ${PORT}`);
});
#### 2. 安全性增强:防止常见攻击
在 2026 年,安全左移 是标准做法。即使是 Hello World 应用,我们也应该立即配置安全相关的 HTTP 头部。我们可以使用 helmet 中间件来自动处理这些复杂的配置。
首先安装 helmet:npm install helmet
const express = require(‘express‘);
const helmet = require(‘helmet‘); // 安全中间件
const app = express();
// 使用 Helmet 保护你的应用
// 它会设置各种 HTTP 头来防止跨站脚本攻击(XSS)、点击劫持等
app.use(helmet());
app.get(‘/‘, (req, res) => {
res.send(‘这是一个安全增强版的 Hello World!‘);
});
#### 3. 结构化日志与可观测性
随着系统复杂度的增加,简单的 console.log 已经无法满足调试需求。在生产环境中,我们需要结构化日志 以便通过日志分析工具(如 Datadog, New Relic 或 Loki)进行检索。
// 这是一个简单的日志中间件示例
const morgan = require(‘morgan‘); // 如果需要更详细的日志
app.use((req, res, next) => {
// 模拟一个结构化日志输出
const logData = {
timestamp: new Date().toISOString(),
method: req.method,
url: req.url,
ip: req.ip // 需要配合 trust proxy 使用
};
// 在实际项目中,这里会连接到日志流服务
console.log(JSON.stringify(logData));
next();
});
#### 4. 性能优化:启用压缩与缓存
网络传输成本始终是后端性能的瓶颈之一。利用 Express 的内置压缩功能,我们可以显著减少响应体的体积,加快页面加载速度。
const express = require(‘express‘);
const app = express();
// 启用内置的压缩中间件(Node.js 11+ 自带)
app.use(express.json()); // 用于解析 JSON 请求体
app.use(express.urlencoded({ extended: true })); // 用于解析表单数据
// 为了演示压缩,我们可以查看响应头
app.get(‘/api/data‘, (req, res) => {
const data = { message: ‘Hello, World!‘, data: ‘...‘.repeat(1000) };
// 如果客户端支持 gzip,这个响应会被压缩
res.json(data);
});
深入架构:模块化与 TypeScript 的引入
随着项目规模的增长,将所有代码写在一个文件中会让维护变成噩梦。在 2026 年,我们将路由和控制器进行分离是必须的。更进一步,使用 TypeScript 可以在编译阶段捕获大量错误,提升代码的健壮性。
#### 实战:构建模块化路由
我们可以将不同的功能拆分到不同的文件中。让我们创建一个简单的路由模块。
// routes/hello.js
const express = require(‘express‘);
const router = express.Router();
// 定义子路由
router.get(‘/‘, (req, res) => {
res.send(‘Hello from modular router!‘);
});
router.get(‘/advanced‘, (req, res) => {
res.json({ status: ‘success‘, message: ‘Advanced Hello World‘ });
});
module.exports = router;
然后在主文件中引入它:
// app.js
const express = require(‘express‘);
const helloRouter = require(‘./routes/hello‘);
const app = express();
// 挂载路由模块
app.use(‘/hello‘, helloRouter);
app.listen(3000, () => console.log(‘模块化服务器已启动‘));
这种分离关注点的方法让我们的代码库变得清晰,易于维护,也便于多人协作。
2026 视角下的技术决策:何时使用 Express?
虽然 Express 依然是事实上的标准,但在 2026 年,作为架构师的我们在选型时需要考虑更多因素。
- 继续使用 Express 的场景:如果你的项目需要高度定制化,或者依赖于庞大的旧有生态系统,Express 依然是稳健的选择。它的中间件模式极其灵活,适合构建传统的 RESTful API 或微服务。
- 考虑替代方案的场景:
* Bun (原生):如果你追求极致的性能和启动速度,Bun 内置的 HTTP 服务器比 Express 快数倍。
* Next.js / Nuxt:如果你构建的是全栈应用(RSC),直接使用这些元框架的 API 路由可能更高效。
* Serverless 函数:如果你只是写一个简单的 API 接口,直接使用云函数可能比维护一个 Express 容器更省钱。
总结
在这篇文章中,我们不仅学习了如何用三种不同的方式打印 "Hello, World!",更重要的是,我们深入探讨了这些方法背后的区别,并融入了 2026 年的开发视角。
- 基础路由 (
app.get):理解了 HTTP 请求响应模型的本质。 - 箭头函数:掌握了现代 JavaScript 的简洁写法。
- 中间件 (
app.use):领略了 Express 灵活的架构设计。 - 生产级实践:学会了配置环境变量、增强安全性、优化性能以及处理错误。
技术在不断演进,但底层原理往往保持不变。无论你是为了学习基础,还是为了构建下一个 AI 原生应用做准备,扎实掌握 Express 都是你职业生涯中宝贵的资产。让我们继续保持好奇心,去构建更多令人兴奋的应用吧!