在 commonjs 环境中需手动清除 require.cache 实现热更新,因 require 默认永久缓存模块;可通过 require.resolve() 获取绝对路径后删除缓存条目,支持单个或递归清除依赖模块,并配合文件监听实现简易热重载。

在 CommonJS 环境(如 Node.js 服务端开发或某些基于 Webpack 的 SSR/Node 模拟场景)中,热更新依赖于手动清除模块缓存,因为 require 默认会永久缓存模块导出对象。Webpack 的 HMR 主要面向浏览器端,不直接接管 Node.js 的 require.cache;若你在用 nodemon、ts-node-dev 或自研热重载逻辑,就需要主动干预缓存。
为什么需要手动清除 require.cache
Node.js 每次调用 require('./config') 时:
- 先查
require.cache中是否存在该模块的绝对路径键 - 存在则直接返回
module.exports,跳过文件读取与执行 - 这意味着即使文件已修改,
require仍返回旧对象 —— 热更新失效
如何安全清除单个模块缓存
使用 require.resolve() 获取模块绝对路径,再从缓存中删除对应条目:
const modulePath = require.resolve('./config');
delete require.cache[modulePath];
const config = require('./config'); // 此时重新加载并执行 config.js
注意:require.resolve() 必须传入相对或绝对路径(不能是变量拼接的字符串),否则解析失败;且路径需与最初 require() 时一致(比如都用 ./config,不要混用 ./config.js)。
批量清除多个相关模块缓存
当一个模块依赖其他模块(如 config/index.js → config/db.js),只清主模块不够。可递归清理其所有子依赖:
function clearModuleCache(modulePath) {
const absPath = require.resolve(modulePath);
const mod = require.cache[absPath];
if (mod) {
// 清除自身
delete require.cache[absPath];
// 清除所有被它引用的子模块
mod.children.forEach(child => {
delete require.cache[child.id];
});
}
}
clearModuleCache('./config');
这个方法能避免因子模块未更新导致的逻辑错乱,适合配置类、路由定义、策略集合等易变模块。
配合监听实现简易热重载
结合 fs.watch 或工具如 chokidar,监听文件变化后自动清缓存并重载:
- 监听
.js文件变更 - 触发
clearModuleCache(filePath) - 重新
require并应用新模块(例如更新 Express 路由、重置定时任务)
注意:不要在生产环境启用此逻辑;确保清除缓存后有兜底机制(如捕获 require 报错,防止服务中断)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











