强制重新加载Webpack异步导入

问题描述 投票:1回答:2

我目前正在研究从大型遗留jquery代码库到vue单页面应用程序的重构。在这样做的时候,我希望将我的工作分成可管理的块,在代码中保留大部分遗留代码库,然后慢慢地将片段和部分从其中拉出以重构为vue,使用事件总线作为中介。

但是,我遇到了问题,因为遗留代码在导入时会产生副作用。这些副作用是由绑定到HTML的运行时jquery事件引起的,并且正在创建的对象和类实例包含其他HTML,因为它在导入时立即建立状态。这会导致SPA重构出现问题,因为我希望能够离开页面然后返回到它,但javascript将保持缓存而不是重新加载,现在缺少所有HTML和状态更新,因为vue将删除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
}

有没有一种有效的方法从客户端做到这一点?

javascript vue.js webpack single-page-application hot-reload
2个回答
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');
  })
} 

网站上有一个关于HMR如何工作以及如何开始的great guide

注意:AFAICT您的遗留代码在加载时会产生副作用(例如,它会影响全局状态)。我会特别小心,因为当以确定的方式导入模块时,热重新加载最有效。


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来访问其对象。

© www.soinside.com 2019 - 2024. All rights reserved.