实现自定义热加载模块

58 阅读1分钟

下面是一个更完善的自定义热加载模块示例,支持事件监听和错误处理:

const fs = require('fs'); 
const path = require('path'); 
class ModuleReloader { 
    constructor(modulePath) { 
        this.modulePath = path.resolve(modulePath); 
        this.module = null; 
        this.listeners = []; 
        this.loadedAt = null; 
        // 初始加载模块 
        this.loadModule(); 
        // 监听文件变化 
        this.watchFile(); 
    } 
    loadModule() { 
        try { 
        // 从缓存中删除旧模块 
            delete require.cache[this.modulePath]; 
            // 加载新模块 
            this.module = require(this.modulePath); 
            this.loadedAt = new Date(); 
            // 触发加载事件 
            this.emit('loaded', this.module); 
            console.log(`模块已加载: ${this.modulePath}`); 
        } catch (err) { 
            this.emit('error', err); 
            console.error(`模块加载失败: ${this.modulePath}`, err); 
        } 
    } 
    watchFile() { 
        fs.watchFile(this.modulePath, { interval: 200 }, (curr, prev) => { 
            if (curr.mtime > prev.mtime) { 
                console.log(`模块文件已修改: ${this.modulePath}`); 
                this.loadModule(); 
            } 
        }); 
    } 
    on(event, callback) { 
        this.listeners.push({ event, callback }); 
    } 
    emit(event, data) { 
        this.listeners.forEach(listener => { 
            if (listener.event === event) { 
                listener.callback(data); 
            } 
        }); 
    } 
    getModule() { 
        return this.module; 
    } 
} 
module.exports = ModuleReloader;

使用方法如下:

const ModuleReloader = require('./module-reloader'); 
const reloader = new ModuleReloader('./your-module.js'); 
reloader.on('loaded', (module) => { 
    console.log('新模块已加载,准备更新应用...'); 
}); 
reloader.on('error', (err) => { 
    console.error('模块加载出错:', err); 
}); 
// 在需要使用模块的地方 
function doSomething() { 
    const module = reloader.getModule(); 
    if (module) { 
        module.someFunction(); 
    } 
}