Node.js新手教程:从零开始学习服务器端JavaScript

LangChain路人
2025-06-25 18:38
阅读 288

从一个静态页面开始,我如何走上Node.js之路?

从一个静态页面开始,我如何走上Node.js之路?

大家好,我是林工,现在在一家电商公司负责前端开发。说起来可能有些惭愧,刚入职的时候我还是个只会写HTML/CSS/JS的“纯前端”,服务器那边的事儿基本没碰过。但随着时间推移,项目需求越来越复杂,尤其是我们接手了一个老系统重构的工作,让我不得不跨出舒适区,开始接触 Node.js。

今天这篇文章,我想和大家分享一下我当时是怎么从零开始学 Node.js 的,过程中踩了哪些坑,也希望能给正在学习或者打算入门 Node.js 的同学一些实用的经验。毕竟,作为一个走过了弯路的人,我觉得有些事早点知道,真的能少走很多冤枉路。


初识 Node.js:为什么我要学它?

记得当时我们要做一个商品详情页的优化项目,其中有一个功能是“商品浏览记录”——也就是用户访问过的商品会显示在侧边栏里,方便回看。

这个功能看起来很简单,但如果要实现持久化存储(比如刷新页面还能保留),就得通过后端保存数据。那时候我们团队的后端是 Java 组,接口对接需要排队、联调,效率很低。再加上当时的前端工程架构已经用上了 Webpack 和 Vue,整个流程都在 JS 体系下完成,我突然想到:“如果我能自己搞一个本地的服务把数据存起来,是不是可以先把功能跑通,再对接正式接口?”

于是,Node.js 就走进了我的视野。说白了,就是想找个 JS 写服务端的办法,不折腾别的语言。


第一次实践:搭建一个本地服务器

刚开始查资料的时候,网上一堆“Hello World”级别的示例,但真正上手才发现——这些例子离“生产级应用”差得远了。于是我决定先从基础做起:搭一个最简单的 HTTP 服务器,用来模拟后端返回商品信息。

// server.js
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ name: 'T恤', price: 99 }));
});

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

这段代码其实就用了 Node.js 原生的 http 模块,启动一个服务器,监听 3000 端口。浏览器访问这个地址就能拿到 JSON 数据了。

虽然很简单,但对我来说是个不小的突破。从此我知道,原来不用 PHP 或 Java,也可以写出响应请求的服务。


遇到的第一个挑战:路由管理太麻烦

不过问题很快来了:随着接口变多,我每次都要手动判断路径,比如 /product/list, /user/info 这些,每个都去 if-else 分发,代码很快就变得难以维护。

这时候我意识到一个问题——原生的 http 模块太底层了,不适合真实项目开发。那怎么办呢?社区推荐了很多框架,Express 是最流行的。所以我决定换 Express 来重构我的小项目。

npm install express

然后新建 app.js 文件:

const express = require('express');
const app = express();

app.get('/product/list', (req, res) => {
  res.json([
    { id: 1, name: 'T恤', price: 99 },
    { id: 2, name: '牛仔裤', price: 149 },
  ]);
});

app.get('/user/info', (req, res) => {
  res.json({ name: '林工', level: '高级前端' });
});

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

这下好了,路由清晰多了,也能按模块拆分逻辑。后来我还用 express.Router() 把不同功能拆分成子路由,结构更清晰。


更大的挑战:连接数据库,实现持久化

前面的例子都是模拟数据,但真正的业务场景中,肯定需要用到数据库。比如刚才提到的商品浏览记录功能,就需要将用户的访问记录存进数据库,而不是存在内存里。

我们选的是 MongoDB,因为它也是基于 JS 的,和 Node.js 结合起来比较自然。引入 Mongoose 库来操作数据库:

npm install mongoose

然后初始化数据库连接:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/shop', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
  console.log('Connected to MongoDB');
});

接着定义一个浏览记录模型:

const visitedSchema = new mongoose.Schema({
  productId: Number,
  timestamp: { type: Date, default: Date.now },
});

const Visited = mongoose.model('Visited', visitedSchema);

最后,在接口中处理数据:

app.post('/record/add', async (req, res) => {
  const newRecord = new Visited({ productId: req.body.productId });
  await newRecord.save();
  res.json({ success: true });
});

这样就能实现实时的用户行为记录了!


踩坑经验分享

1. Node.js 异步回调带来的混乱

一开始写接口的时候,我经常被异步回调搞得晕头转向。比如数据库插入之后要返回结果,但我写成了下面这样:

Visited.create({ productId }, function (err, doc) {
  // do something...
});
res.json({ success: true }); // 这行会先执行!

因为 Node.js 是异步非阻塞的,所以这种写法会导致还没插入完成就返回了结果。正确的做法应该是放在回调里面,或者用 async/await:

app.post('/record/add', async (req, res) => {
  const newRecord = new Visited({ productId: req.body.productId });
  await newRecord.save();
  res.json({ success: true });
});

2. 忘记加 CORS 中间件导致跨域失败

我们在前端是用 Vue + Axios 请求的,但 Node 服务在 localhost:3000,Vue 项目在 localhost:8080,这就导致了跨域问题。

解决方法是装一个中间件:

npm install cors

然后在入口文件加上:

const cors = require('cors');
app.use(cors());

一下子搞定,非常方便。

3. NODE_ENV 没设置清楚,开发环境暴露敏感信息

有一次我把数据库连接配置写死了,还在开发环境下输出错误堆栈信息,结果测试人员不小心访问到了报错页面,直接看到了数据库账号密码……吓坏了 QA。

后来我改成了:

if (process.env.NODE_ENV !== 'production') {
  app.use(express.json());
}

同时把数据库配置抽出来,统一用 .env 管理。


实际效果与收获

这套本地服务后来成为了我们内部工具的一部分,甚至后续还上线了一个小型的数据统计平台。更重要的是,它让我真正理解了前后端协作的本质。过去我一直觉得后端是黑盒子,但现在我明白了他们的工作原理,沟通也顺畅多了。

而且,有了 Node.js 的基础之后,我也能更好地参与构建工具链、脚本自动化等工作,比如写一个自动清理 CDN 缓存的脚本,或者搭建本地 Mock 服务,大大提高了开发效率。


我的一些建议

  1. 别一开始就学太多框架

    很多新手看到 Express、Koa、NestJS 等各种框架,容易选择困难。我的建议是先掌握 Express,它是社区最成熟、文档最多的一个。打好基础后再去尝试其他框架。

  2. 注重模块化设计,别写面条代码

    后期如果你要做中大型项目,模块化是必须的。把路由、控制器、服务、模型分离,用 Router 拆分功能模块,才能维护得下去。

  3. 尽早接入调试工具,比如 nodemon 和 VS Code Debugger

    开发过程中频繁重启服务很烦人,安装 nodemon 监听变化自动重启,提升效率;VS Code 的 Debugger 功能也非常强大,断点调试比 console.log() 高级得多。

  4. 注意安全性

    早期我完全没考虑安全问题,后来才明白输入验证的重要性,比如防止 SQL 注入(虽然 Node 多数是 NoSQL,但也要防注入)、限制 API 调用频率等。可以用像 Joi 或者 celebrate 这样的库做参数校验。

前端性能优化图表-1

  1. 拥抱 TypeScript

    如果你打算长期使用 Node.js,建议尽快迁移到 TypeScript。TS 能减少很多类型错误,也能提高团队协作的可维护性。

  2. 多关注性能与稳定性

    比如 Node.js 默认是单线程的,可以考虑配合 Cluster 模块或多进程部署来利用多核 CPU;也可以用 PM2 做进程管理和热更新,避免服务中断。


写在最后

学习 Node.js 并不是为了变成全栈工程师,而是为了让我们作为前端开发者,有更多的可能性和掌控力。在这个前后端融合的时代,了解服务端逻辑,不仅能提升你的开发能力,更能帮助你在团队中更有话语权。

希望这篇结合我个人经历的文章,对你们有用。如果你也有类似的故事或者踩过类似的坑,欢迎留言交流,我们一起成长。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝