我要做动态下载爬虫,动态卸载的功能
在 Electron 中实现动态加载/卸载模块的核心技术方案:
require()
动态加载(需配合缓存清理)import()
实现 ES Module 动态加载推荐文件存储路径:
const userDataPath = app.getPath('userData')
const pluginPath = path.join(userDataPath, 'plugins')
安全卸载实现
// 清除模块缓存
function unloadModule(modulePath) {
const resolvedPath = require.resolve(modulePath)
delete require.cache[resolvedPath]
}
// 完整卸载示例
function safeUnload(module) {
// 执行模块的清理钩子
if (module.cleanup) module.cleanup()
// 清除事件监听器
if (module.eventListeners) {
module.eventListeners.forEach(([emitter, event, handler]) => {
emitter.removeListener(event, handler)
})
}
// 清除定时器
if (module.timers) {
module.timers.forEach(timer => clearInterval(timer))
}
unloadModule(module.path)
}
进程隔离方案(建议)
// 在主进程中
const { fork } = require('child_process')
class PluginManager {
constructor() {
this.plugins = new Map()
}
async loadPlugin(pluginPath) {
const pluginProcess = fork(pluginPath)
this.plugins.set(pluginPath, {
process: pluginProcess,
status: 'running'
})
// IPC 通信设置
pluginProcess.on('message', (msg) => {
// 处理插件消息
})
}
unloadPlugin(pluginPath) {
const plugin = this.plugins.get(pluginPath)
if (plugin) {
plugin.process.kill()
this.plugins.delete(pluginPath)
}
}
}
动态下载实现
const downloader = async (url, savePath) => {
const response = await fetch(url)
const buffer = await response.buffer()
// 安全校验
if (!validateHash(buffer)) throw new Error('Invalid checksum')
fs.writeFileSync(savePath, buffer)
return savePath
}
// 使用示例
const pluginPath = await downloader('https://example.com/plugin.js', path.join(pluginDir, 'v1.0.0.js'))
每个插件应实现标准接口:
// 插件模板
module.exports = {
initialize: (config) => {
// 初始化逻辑
return {
cleanup: () => { /* 清理逻辑 */ },
timers: [intervalId],
eventListeners: [[emitter, 'event', handler]]
}
}
}
使用 VM 模块创建沙箱环境
const { VM } = require('vm2')
const vm = new VM({
timeout: 1000,
sandbox: {
require: (mod) => {
// 白名单控制
if (!allowedModules.includes(mod)) throw new Error('Forbidden module')
return require(mod)
}
}
})
vm.run(pluginCode)
注意事项:
典型工作流程:
这种架构可以实现插件动态加载/卸载,同时保证主进程稳定性。建议优先考虑子进程方案,虽然有一定性能开销,但安全性和稳定性更好。
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答5.2k 阅读✓ 已解决
1 回答3.3k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决