前言
你可能听说过 "Node.js 是 JS 的运行环境" ,但这玩意儿到底咋用?提到 JavaScript,你可能先想到它在浏览器里折腾网页特效的样子;但 Node.js 的出现,直接把 JS 从浏览器 "解放" 了出来,让它能像 Python、Java 一样,在操作系统上呼风唤雨 ------ 读写文件、操作终端、搭建后端服务都不在话下。而模块化 ,正是 Node.js 让代码变得整洁、可复用的核心秘诀。
今天咱从模块化 入手,再手把手写个小游戏,让你把Node.js玩明白!
一、先认识 Node.js 的 "自带工具":process、__dirname 这些都啥啊?
Node.js 刚启动时,就给我们准备了一堆 "开箱即用" 的工具。
JavaScript
// 最基础的控制台输出,和浏览器里的console.log用法一致
console.log('hello');
// Date对象:处理时间和日期,比如new Date()能获取当前时间
console.log(Date);
// 定时器方法:Node.js 里也能设置延时/重复执行的代码
console.log(setTimeout); // 延时执行(毫秒级)
console.log(setInterval); // 重复执行(毫秒级)
// console.log(requestAnimationFrame); // 适配浏览器/Node.js的帧动画(Node.js 16+支持)
// 路径相关:定位文件位置的"神器"
console.log(__dirname); // 打印当前文件所在文件夹的绝对路径
console.log(__filename); // 打印当前文件的完整绝对路径(包含文件名)
// 进程参数:获取终端执行命令时传的参数
console.log(process.argv);

二、Node.js 模块化:代码也能 "打包快递"
写代码像搭积木 ------ 把重复的功能拆成独立文件,要用的时候 "拼" 起来,这就是模块化 。Node.js 支持两种主流规范:
1. CommonJS:Node.js 自带的 "老牌规范"
就像你寄快递时填 "收件人信息" ,CommonJS 用 module.exports 打包功能,require() 取快递:
JavaScript
// lib.js(打包功能)
function add(x, y) {
return x + y;
}
function minus(x, y) {
return x - y;
}
// 把 add 和 munus 打包成 "快递"
module.exports = {
add,
minus
}
JavaScript
// index.js(取快递用功能)
// 用 require 拿到 lib.js 里的 add
const lib = require('./lib.js');
console.log(lib.add(1, 2)); // 输出 3
console.log(lib.minus(1, 2)); // 输出 -1


当然每次console.log都要写一遍lib.,会感到很烦,所以这里用解构的方法会更舒服点:
JavaScript
const {add, minus} = require('./lib.js');
console.log(add(1, 2));
console.log(minus(1, 2));

2. ESModule:前端圈的 "新潮流规范"
如果你的项目想和浏览器端代码 "互通" ,可以用 ESModule,但是但是但是重要的事情说三遍:得在 package.json 里加 "type": "module"(一般情况下是有的,直接修改type里的值即可)。
上图更清晰:

还是 common 文件夹的例子:
JavaScript
// lib.js(用 export default 打包)
function add(x, y){
return x + y;
}
function minus(x, y){
return x - y;
}
export default {
add,
minus
}
JavaScript
// index.js(用 import 导入)
import lib from './lib.js'
console.log(lib.add(1, 2)); // 输出 3
console.log(lib.minus(1, 2)); // 输出 -1

三、实战:用 Node.js 写 "石头剪刀布" 游戏
没错,"石头剪刀布" 怎么就不算小游戏了,这可不算欺骗哦😮。好了我知道你肯定会觉得很简单然后马上打开Steam的,但来都来了,那就👀看我如何用Node.js写出来的。
逻辑很简单:你在终端输入 "rock/scissor/paper",电脑随机出拳,然后比胜负~
第一步:先写 "游戏核心逻辑"(模块化拆分)
把 "出拳、比胜负" 的功能拆到 game/lib.js 里
JavaScript
// game/lib.js(游戏核心逻辑)
module.exports = function (playerAction) {
// 电脑随机出拳(rock/scissor/paper 三选一)
const arr = ['rock', 'scissor', 'paper'];
const index = Math.floor(Math.random() * 3); // 向下取整(0,1,2)
const computerAction = arr[index];
console.log(`我出了${computerAction}`);
// 比胜负,返回结果(0=平,-1=你赢,1=你输)
if (computerAction === playerAction) {
console.log('平局');
return 0;
} else if ((playerAction === 'rock' && computerAction === 'scissor') ||
(playerAction === 'scissor' && computerAction === 'paper') ||
(playerAction === 'paper' && computerAction === 'rock')) {
console.log('你赢了');
return -1;
} else {
console.log('你输了');
return 1;
}
}
第二步:写 "终端交互逻辑"(调用核心功能)
在 game/index.js 里,用 Node.js 的 process 模块获取你在终端的输入,再调用游戏逻辑:
JavaScript
// game/index.js(终端交互)
const game = require('./lib.js');
let count = 0; // 统计你赢的次数
// 监听终端输入(你输入的内容会传到 e 里)
process.stdin.on('data', e => {
// 把输入的内容转成字符串,去掉空格
const playerAction = e.toString().trim();
// 调用游戏逻辑,拿到结果
const result = game(playerAction);
if (result === -1) {
count++;
}
// 赢 3 次就结束游戏
if (count === 3) {
console.log('你太厉害了,我不玩了');
process.exit(); // 结束 Node.js 进程
}
});
第三步:跑起来!在终端玩游戏
打开终端,进入 game 文件夹,执行:
bash
node index.js
然后输入 rock/scissor/paper,就能和电脑 PK 啦~


占用你玩2分钟玩Steam的时间看完了我的石头剪刀布~ 😊 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
四、总结:Node.js 到底是啥?
一句话: 它不仅是 "JS 运行环境",更是让你用 JS 写 "能和操作系统互动" 代码的工具------ 比如读文件、监听终端输入、写后端服务... 而模块化是它的 "基本功",帮你把代码写得更整洁、更好维护~
结语
从模块化规范的拆解,到石头剪刀布游戏的落地,不难发现 Node.js 的魅力:它让 JavaScript 跳出了前端的局限,拥有了跨场景开发的能力。小小的 require 和 export 背后,是代码组织的大智慧;简单的终端交互游戏里,藏着后端开发的雏形。
希望这篇内容能让你对 Node.js 不再陌生,下次遇到复杂项目时,也能想起用模块化思维拆解问题,用 Node.js 敲出属于自己的有趣代码。
另外要查看Node.js详细资料的话,官网在这: