我目前正在研究从大型的仅基于jquery的旧代码库到vue单页应用程序的重构。这样做时,我希望将工作分解成可管理的块,按原样在代码中维护许多旧代码库,并慢慢地将其中的各个部分从中拉出,以重构为vue,并使用事件总线作为中介。
但是,由于遗留代码在导入时会产生副作用,因此我遇到了问题。这些副作用是由绑定到HTML的运行时jquery事件以及在导入时立即建立状态的其他HTML环绕而创建的对象和类实例引起的。这会导致SPA重构出现问题,因为我希望能够从页面导航离开然后返回到页面,但是javascript仍将保留缓存并且不会重新加载,由于vue已删除了,因此现在缺少所有HTML和状态更新html创建状态,然后在重新渲染上添加新的html。
我正在寻找解决此问题的最佳方法,以免我不得不两次重构代码-一次通过init调用进入模块化导入,然后进入一种反应式模块化Vue范例。为此,我想弄清楚如何使用Webpack的异步块导入来重新加载代码块。我知道这是有可能的,因为webpack会对文件进行热重载。我本质上是想在访问特定路由时强制对某些导入进行热重载。
这就是我想要做的:
async function reloadLegacyCodeOnSPARoutingChange(){
cleanAnyPolutingGlobals();
const initLegacyCode = await import(`./LegacyCode.js`); //somehow force it to reload this as if it were a fresh import
let thingId = this.$store.state.thingPage.thingId;
await initLegacyCode(thingId);
await EventBus.$emit('initLegacyCodeState'); //apply the properties from our reactive state system
}
从客户那里有有效的方法吗?
答案 0 :(得分:0)
热模块替换(HMR)并不是某种黑魔法(尽管我认为是)。想象一下一个客户机/服务器体系结构,其中客户机(您的应用程序)询问服务器(启用了HMR的Webpack)在您要导入的模块中是否有任何更改。如果是这样,它将重新加载模块。
// Add this to the file you are initially loading
if (module.hot) {
module.hot.accept('./LegacyCode.js', async function() {
console.log('Accepting the updated LegacyCode.js module!');
let thingId = this.$store.state.thingPage.thingId;
await initLegacyCode(thingId);
await EventBus.$emit('initLegacyCodeState');
})
}
webpack网站上有great guide,介绍HMR的工作原理和入门方法
注意:遗留代码在加载时会产生副作用(例如,它会使全局状态混乱)。我会特别小心,因为以确定性方式导入模块时,热重装效果最佳。
答案 1 :(得分:0)
如果标志useFresh
为true,则可以动态导入模块并将其从缓存中删除。
async function getFile (useFresh) {
try {
useFresh && delete require.cache[require.resolve('./Test')];
} catch (err) { }
let newModule = await require('./Test');
}
注意:如果要在动态导入的文件中使用export default
,则必须使用newModule.default
来访问其对象。