我知道可以使用delete
清除require缓存,但是每次我使用外部模块时都没有运行删除,有没有人做过检测文件被更改的方法(例如通过修改时间? )如果缓存有变化,只会使缓存无效?即而不是:
var ext = require(filename);
ext.do_stuff();
delete require.cache[require.resolve(filename)];
有些事情:
if(PSEUDO_is_file_changed(filename)){
delete require.cache[require.resolve(filename)];
}
var ext = require(filename);
ext.do_stuff();
我正在考虑fs.stat
的内容,只是跟踪mtime
,但文件名路径解析可能会有问题......
编辑这比我预期的更容易......完整路径是通过require.resolve(filename)
然后使用fs.statSync
。我只是将mtime
直接放入缓存对象:
var ext_fn = require.resolve(filename);
var ext_info = fs.statSync(ext_fn);
if (ext_fn in require.cache && require.cache[ext_fn]._x_modtime != ext_info.mtime.getTime()) {
delete require.cache[ext_fn];
}
var ext = require(filename);
require.cache[ext_fn]._x_modtime = ext_info.mtime.getTime();
答案 0 :(得分:0)
如果您知道何时更改文件,则可以向节点发送POSIX信号 并注册一个信号处理程序,以防止您不得不继续检查。 http://nodejs.org/api/process.html#process_signal_events 只选择最合适的一个
process.on('SIGINT', function() {
watcher.find_modified_files();
});
/ **
*模块在需要时缓存在此对象中。 *通过删除此对象的键值,下一个require将重新加载模块 * @type {Object}
* /require.cache = {};
所以删除条目就足够了,现在你需要做的就是重新加载文件 你可以在任何地方制作一些你需要的文件,并让它导出一个需要函数调用中所需资源的方法
创建一些模块,我将其命名为watcher.js
var fs = require('fs');
var path = require('path');
var watchlist = {};
var local_require = function (root, mod) {
mod = require.resolve(path.join(root, mod));
fs.stat(mod, function (err, stats) {
watchlist[mod] = stats.mtime.getTime();
});
require(mod);
};
var update = function (path) {
delete require.cache[path];
require(path);
};
var find_modified_files = function () {
Object.keys(watchlist).forEach(function (key) {
fs.stat(key, function (err, stats) {
var time = stats.mtime.getTime();
if (watchlist[key] !== time) {
watchlist[key] = time;
update(key);
}
});
});
};
module.exports = {
require: local_require,
update: update,
find_modified_files: find_modified_files
};
使用它:
var watcher = require('./lib/watcher');
var mod_a = watcher.require(__dirname, './mod-a');
您必须提供__dirname
,因此要求可以找到相对于您导入的模块的文件,否则将搜索文件相对于观察者模块的位置。
由于require是由nodejs本身提供的glboal,并且被锁定,因此无法更改全局require调用,因此无法跟踪所有需求。
即使这样有效,也可能不是你对它的期望。
如果你持有对所需模块的引用,你需要采用一种特殊的方式与你所观看的模块进行交互,然后,即使在重新加载并从内存中删除之后,你的引用仍将保留以前的版本模块。
作为引用的结果,您将使用的大多数库都无法以这种方式重新加载。
示例:
var watcher = require('./lib/watcher');
var mod_a = watcher.require(__dirname, './mod-a');
var applier = function (ref, scoped) {
return function (arg) {
return ref.x(scoped, arg);
}
}
var closure = closure(mod_a, 'piccle me');
closure('test');
在应用程序返回的函数内部,“ref”变量保存当前的mod_a 它会永远保持它,即使重新加载mod_a,所以相应地改变你的编码风格