node repl 是验证 commonjs 模块加载行为最直接的工具,可快速验证路径解析(优先 .js→.json→.node)、缓存机制(require.cache 复用模块)、相对路径与 node_modules 查找逻辑、以及 module.exports 与 exports 赋值差异。

Node REPL 是验证 CommonJS 模块加载行为最直接的工具之一。它无需创建文件、不涉及构建流程,输入即执行,特别适合探索 require() 的路径解析、缓存机制和模块导出规则。
确认模块查找路径和文件扩展名补全
Node 会按固定顺序尝试加载文件:先找 .js,再 .json,最后 .node;若路径不含扩展名,还会自动补全。在 REPL 中可快速验证:
- 输入
require('./utils')(假设当前目录有utils.js),成功返回模块对象 - 若同时存在
utils.js和utils.json,require('./utils')优先加载.js -
require('./config')会依次尝试./config.js→./config.json→./config.node
观察模块缓存(require.cache)的实际表现
同一模块多次 require 不会重复执行,而是返回缓存中的 exports 对象。在 REPL 中可直观验证:
- 执行
const m = require('./counter')(假设counter.js中有console.log('loaded')),只输出一次 - 再次执行
require('./counter'),无日志输出,且m === require('./counter')为 true - 查看缓存:
Object.keys(require.cache)显示已加载模块的绝对路径
测试相对路径与 node_modules 查找逻辑
REPL 的当前工作目录(process.cwd())是路径解析的基准点。可快速区分不同写法的行为差异:
-
require('lodash'):从node_modules向上逐级查找,直到根目录或遇到node_modules中有该包 -
require('./lib/utils'):相对于当前工作目录解析,必须存在对应文件或目录 -
require('util'):命中 Node 内置模块,不会读取文件系统,require.cache中无其路径记录
验证 module.exports 与 exports 的赋值差异
在 REPL 中动态修改模块导出,能清晰看到两者区别:
- 若模块中写
exports.a = 1,再require得到{ a: 1 } - 若写
exports = { b: 2 },则require仍返回空对象(因未修改module.exports引用) - 若写
module.exports = { c: 3 },则require正确返回{ c: 3 }
不复杂但容易忽略:每次在 REPL 中 require 都基于当前 process.cwd(),不是 REPL 启动脚本所在目录;退出并重启 REPL 可清空缓存,方便重新测试。










