首页 / Node.js 教程 / 第一个 Node.js 程序

Node.js 教程

第一个 Node.js 程序

本教程共 76 篇 · 第 4 篇 · 更新于 2026-07-25 · 约 6 分钟阅读

Node.js入门REPLHello World脚本

4. 第一个 Node.js 程序

本节目标:写一个能跑的 HTTP 服务器,玩转 REPL 交互环境,读取命令行参数,还有开发时省事的 node --watch

你好,HTTP 服务器

别的语言入门先打印 “Hello World”,Node.js 咱们直接点,搭一个 HTTP 服务器。

在项目目录下建一个 server.js

import { createServer } from 'node:http';

const hostname = '127.0.0.1';
const port = 3000;

createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
}).listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
Warning

上面代码用的是 ESM(import 语法)。如果你直接 node server.js 报错,说不能用 import,那是因为 Node.js 默认按 CommonJS 解析。解决办法:把文件重命名为 server.mjs,或者在同级目录建一个 package.json 写上 { "type": "module" }。本教程全程 ESM 优先,后面默认你配好了模块类型。

运行:

node server.js

看到 Server running at http://127.0.0.1:3000/ 后,打开浏览器访问这个地址。一个活的服务器就起来了。

代码拆解:

  • import { createServer } from 'node:http' —— 加载内置 http 模块。node: 前缀表示这是 Node.js 内置模块,自 v16 起推荐这么写,能避免和 npm 包重名。
  • createServer(callback) —— 创建一个 HTTP 服务器,每次有请求进来就执行回调。
  • req(请求对象)和 res(响应对象)—— 分别携带了客户端发来的信息和你要回传的内容。
  • res.end('Hello World') —— 结束响应,把文字发回浏览器。
  • listen(port, hostname, callback) —— 让服务器开始监听端口,启动成功后执行最后的回调。
Tip

127.0.0.1 意味着只有本机能访问。如果你希望局域网里的手机或其他电脑也能访问,把 hostname 改成 '0.0.0.0'。但注意,公网部署时别裸奔,前面要加 Nginx 或防火墙。


REPL:边想边试

REPL 全称 Read-Eval-Print Loop,就是交互式命令行。你不用建文件,直接敲 node 进 REPL:

$ node
> 1 + 1
2
> const arr = [1, 2, 3]
undefined
> arr.map(x => x * 2)
[ 2, 4, 6 ]
>

输入代码,立刻看到结果。适合验证表达式、试 API、算点数学题。

几个实用技巧:

  • 上箭头 翻历史记录,不用重写。
  • 输入 _ 获取上一个表达式的结果。
  • 多行代码(比如函数定义)直接回车,REPL 会自动识别并进入续行模式,提示符变成 ...
  • .help 查看所有点命令,.exit 退出,.save session.js 把本次输入保存到文件。
Note

REPL 里的变量是全局的,跟写在文件里不完全一样。有些异步行为在 REPL 里的表现也可能有细微差别。验证核心逻辑可以,但正式功能还是写到文件里跑。


命令行参数

你的程序可能需要从命令行接收输入,比如指定端口号、配置文件路径。Node.js 通过 process.argv 暴露所有参数。

建一个 args.js

console.log('完整参数列表:', process.argv);
console.log('脚本路径:', process.argv[1]);
console.log('用户传入的参数:', process.argv.slice(2));

运行:

node args.js hello world --port=8080

输出:

完整参数列表: [
  '/usr/local/bin/node',
  '/home/you/args.js',
  'hello',
  'world',
  '--port=8080'
]
用户传入的参数: [ 'hello', 'world', '--port=8080' ]

process.argv 是个数组:

  • 第 0 项是 node 可执行文件的路径
  • 第 1 项是你运行的脚本路径
  • 从第 2 项开始才是你真正传的参数

自己解析字符串太麻烦,生产环境一般用专门的 CLI 解析库,比如 minimistcommander。但底层原理就是 process.argv,你得先知道。

Tip

环境变量用 process.env 读取。比如 NODE_ENV=production node app.js,代码里 process.env.NODE_ENV 就是 'production'。这是区分开发/生产环境最常用的手段。


开发利器:node —watch

以前改一行代码就要手动 Ctrl+C 再重新 node server.js,很烦。从 Node.js v18 开始,内置了 --watch 模式,文件一改自动重启。

node --watch server.js

终端会显示:

Server running at http://127.0.0.1:3000/
Completed running 'server.js'

你修改 server.js 保存后,它会自动重启并打印 Restarting 'server.js'

Note

node --watch 自 v18 起可用,v24 LTS 已完全稳定。比第三方的 nodemon 省事的地方在于不用额外装包,开箱即用。但 nodemon 配置更灵活(比如忽略某些文件),复杂场景还是用得着。

你也可以同时 watch 多个文件或目录:

node --watch-path=./src --watch-path=./config server.js

如果只想检查语法不执行:

node --check server.js

这在提交代码前快速扫一遍语法错误很方便。


在终端输出点花样

console.log 你肯定熟悉,但 Node.js 的 console 模块比浏览器里丰富得多。

格式化输出:

const user = { name: 'Tom', age: 25 };
console.log('User: %o', user);        // %o 格式化对象
console.log('Count: %d', 42);         // %d 数字
console.log('Hello, %s', 'world');    // %s 字符串

计时:

console.time('query');
// ... 执行某些操作
console.timeEnd('query');  // 输出: query: 23.456ms

追踪调用栈:

function inner() {
  console.trace('这里被调用了');
}
function outer() {
  inner();
}
outer();

自 v22 起,还可以用 util.styleText 给终端文字上色:

import { styleText } from 'node:util';

console.log(styleText(['red', 'bold'], '错误!'));
console.log(styleText('green', '一切正常'));
Tip

颜色输出在 CI 日志里有时会变成乱码。写库或者 CLI 工具时,建议检测 process.stdout.isTTY,非终端环境不输出颜色,或者给用户一个 --no-color 选项。


动手练一下

  1. 把上面的 HTTP 服务器跑起来,试着把 text/plain 改成 text/html,返回一段带标签的 HTML。
  2. 用 REPL 算一下 Array.from({ length: 5 }, (_, i) => i * i),看看结果是什么。
  3. 写一个 greet.js,接收命令行参数作为名字,输出 Hello, 名字!。没传名字时默认输出 Hello, stranger!
  4. node --watch 启动服务器,改代码看会不会自动重启。

下一章我们拆开 Node.js 的引擎盖,看看里面是怎么转的。