请写一篇关于【Node.js新手教程:从零开始学习服务器端JavaScript】的技术文章

需求别再变
2025-12-16 19:21
阅读 561

上周五晚上11点,我刚改完线上一个诡异的内存泄漏 bug,瘫在杭州出租屋的沙发上,手机突然震动。是我老婆发来的消息:“这周又见不到了吧?”

我心里一沉。又是这样。我们异地快一年了,她在成都做产品,我在杭州一家大厂当后端开发。说好每周五晚高铁见面,结果最近项目上线,连续三周爽约。她语气里没有责备,但那种克制的失望比直接骂我还难受。

我叹了口气,回了个“对不起”,然后打开 VS Code,新建了一个 server.js 文件。不是为了工作,而是想给自己找点事做——转移注意力,也顺便学点新东西。毕竟,去年十月被上一家公司“优化”后,我深刻意识到:技术栈不能只靠公司教,得自己卷起来。


被裁员那晚,我重装了 Node.js

那是2022年10月18号,周三下午3点。HR把我叫进小会议室,桌上放着一杯没加糖的美式(后来才知道这是“裁员咖啡”的暗号)。她说:“公司战略调整……N+1……希望理解。”

我表面冷静,心里却像被掏空。当时月薪15k,房租3500,异地恋开销不小,存款只够撑4个月。回家路上,地铁上刷脉脉,满屏都是“大厂裁员潮”“35岁危机”。那一刻,我真的慌了。

当晚,我没睡。翻出尘封已久的 MacBook,卸载了那些花里胡哨的 IDE 插件,重新装了最新版 Node.js。为什么是 Node.js?因为我知道,前端同事早就用 Express 写接口玩得飞起,而我这个所谓“后端老油条”,还只会 Java + Spring Boot 那一套。

讽刺的是,被裁的理由之一,就是“技术栈单一,缺乏全栈视野”。

于是,我给自己定了个目标:一个月内,用 Node.js 写一个能跑的 REST API,部署上线,最好还能防住常见的安全漏洞。


console.log('Hello World') 开始的血泪史

说实话,一开始真不顺。虽然会 JavaScript,但服务器端完全是另一套逻辑。第一个坑就是模块系统——CommonJS 和 ES Module 混用,报错信息还特别晦涩:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module

我对着屏幕骂了句“草”,差点想放弃。但想到下个月房租还没着落,咬咬牙继续查文档。后来才知道,Node.js 14 之后默认支持 ES Module,但需要在 package.json 里加 "type": "module"。这种细节,没人告诉你,全靠踩坑。

第二个坑更致命:安全。

我照着网上教程,用 Express 写了个简单的用户注册接口:

app.post('/register', (req, res) => {
  const { username, password } = req.body;
  // 直接插入数据库!
  db.query(`INSERT INTO users (username, password) VALUES ('${username}', '${password}')`);
  res.send('注册成功');
});

现在看简直头皮发麻——典型的 SQL 注入漏洞!要是被人传个 username=admin'; DROP TABLE users;--,整个用户表就没了。更别提密码明文存储这种低级错误。

那天晚上,我老婆视频问我进展,我说:“我差点把‘生产事故’写在 demo 里。”她笑出声:“你以前不是总说‘代码即正义’吗?”
我苦笑:“现在知道,代码即责任。”


开发心得:安全不是附加题,是必答题

从那以后,我逼自己养成几个习惯:

  1. 永远不信任用户输入
    express-validator 做参数校验,哪怕只是个测试接口。

    const { body, validationResult } = require('express-validator');
    
    app.post('/register',
      body('username').isLength({ min: 3 }).matches(/^[a-zA-Z0-9_]+$/),
      body('password').isLength({ min: 8 }),
      (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
          return res.status(400).json({ errors: errors.array() });
        }
        // ...后续逻辑
      }
    );
    
  2. 密码必须哈希
    别再存明文!用 bcrypt

    const bcrypt = require('bcrypt');
    const saltRounds = 12;
    const hashedPassword = await bcrypt.hash(password, saltRounds);
    
  3. SQL 查询用参数化
    别拼字符串!用 mysql2 的占位符:

    db.execute('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword]);
    
  4. 环境变量管理
    敏感信息(如数据库密码)绝不写死在代码里。用 .env 文件 + dotenv,但记得加到 .gitignore

这些看似基础,但多少人栽过跟头?包括我自己。安全意识不是天赋,是用教训换来的肌肉记忆。


代码人生:从“能跑就行”到“稳如老狗”

去年12月,我靠着这个 Node.js 项目,成功跳槽到现在的公司。面试官看到我的 GitHub 仓库,特意问了安全设计。我说:“我知道你们用 NestJS,但底层原理一样——输入验证、权限控制、日志审计,一个都不能少。”

他点点头:“很多候选人只讲性能、高并发,却忘了系统首先要‘活下来’。”

入职后,我负责一个内部工具链的重构。团队原本用 Python Flask,我想推 Node.js。有人质疑:“JS 不适合后端吧?单线程扛不住。”
我直接甩出压测报告:用 cluster 模块 + PM2,QPS 稳定在 3000+,内存占用比 Flask 还低。关键是我加了完整的安全中间件——防 XSS、CSRF、速率限制,连请求头里的 X-Forwarded-For 都做了 IP 白名单校验。

上个月,我晋升了。月薪从15k涨到22k。发薪日那天,我给老婆转了5200,备注:“下次见面,我请你吃火锅,鸳鸯锅,你点辣我不拦。”

她回:“终于不用视频啃泡面了?”


给 Node.js 新手的真心话

如果你正打算学 Node.js,听我一句劝:

  • 别只看“快速上手”教程
    那些 10 分钟搭建 API 的视频,99% 忽略了安全。先学会怎么“防住”,再学怎么“跑快”。

  • 从 Express 开始,但别止步于 Express
    它简单,适合入门。但生产环境要考虑 Koa、Fastify,甚至 NestJS。架构能力比语法更重要。

  • 日志和监控不是可选项
    winston 记日志,用 Prometheus + Grafana 监控。线上问题,90% 靠日志定位。

  • 写测试!写测试!写测试!
    Jest + Supertest,覆盖核心路径。别等上线才后悔。

最重要的是:别怕犯错,但要从错误里长记性。 我那个 SQL 注入的 demo,现在还留着,作为团队新人培训的反面教材。


异地、裁员、35岁…我们到底在焦虑什么?

写这篇文章时,窗外下着杭州的梅雨。我租的房子隔音很差,隔壁情侣在吵架,声音断断续续。突然想起被裁那天,也是这样的雨天。

很多人说程序员吃青春饭,35岁就被淘汰。但我觉得,真正淘汰你的,不是年龄,而是停止进化的心态

Node.js 对我而言,不只是一个技术栈,而是一次自救。它让我明白:

代码人生,从来不是写得多漂亮,而是扛得住风雨。

我和老婆商量好了,年底争取结束异地。要么她来杭州,要么我回成都。技术在哪都能做,但人不能一直隔着屏幕说“我想你”。

下周六,我订了早班高铁。这次,无论如何都要见到她。
至于代码?等我回来再 debug 吧。


最后送大家一句我工牌背面写的字:
“Secure by default, resilient by design.”
(默认安全,设计即韧性)

共勉。

评论 0

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