Node.js Express服务运行时如何实现.js模块路由的自动更新
问题根因
Node.js 的require模块加载机制会将已加载的模块内容缓存到require.cache对象中,修改路由、中间件代码后,服务不会主动拉取新版本代码,默认必须重启服务才能生效。
方案1:开发环境极简自动重启方案
无需修改现有业务代码,通过工具自动监听文件变更重启服务,重启速度极快几乎无感知,是开发阶段最常用的方案:
- 安装nodemon依赖:
npm install nodemon -D - 在项目
package.json的scripts字段中新增启动命令:"dev": "nodemon server.js" - 后续启动服务直接执行
npm run dev即可,所有.js文件修改后都会自动触发服务重启,无需手动操作。
方案2:无重启路由热更新方案
如果你需要完全不重启服务实现路由生效,可以通过监听文件变更、清除模块缓存、动态替换挂载路由实现,仅建议在开发环境使用:
- 安装文件监听依赖:
npm install chokidar -D - 修改
server.js代码如下:
var express = require('express'); var app = express(); var chokidar = require('chokidar'); // 路由入口文件路径 const ROUTES_ENTRY = './routes/routes.js'; // 首次加载挂载路由 let routes_module = require(ROUTES_ENTRY); app.use(routes_module); // 监听routes目录下所有js文件的变更 const watcher = chokidar.watch('./routes/**/*.js', { ignoreInitial: true }); watcher.on('all', (event, filePath) => { console.log(`检测到路由文件${filePath}变更,开始更新路由配置`); // 清除所有路由相关模块的缓存 Object.keys(require.cache).forEach(cacheKey => { if (cacheKey.includes('/routes/')) { delete require.cache[cacheKey]; } }); // 移除之前挂载的旧路由中间件 app._router.stack = app._router.stack.filter(layer => { return layer.handle !== routes_module; }); // 加载新路由并挂载 routes_module = require(ROUTES_ENTRY); app.use(routes_module); console.log('路由配置更新完成,无需重启服务即可生效'); }); module.exports = app; var server = app.listen(process.env.port || 8081 ,function() { var host = server.address().address; var port = server.address().port; console.log('PHPExpress app listening at http://%s:%s', host, port); });
注意:该方案仅适配开发环境,生产环境不要开启热更新,避免运行时逻辑不稳定、内存泄漏等问题,生产环境建议使用PM2等进程管理工具做平滑重启。
内容的提问来源于stack exchange,提问作者Jirayut Watcharinrat
相关产品推荐
相关产品推荐

