What(什么是HMR?)我们下面讨论的HMR是基于vite自己实现的一套HMR系统。vite实现的HMR是按照ESMHMR规范实现的。HMR:HotModuleReload模块热更新。之前我们在编辑器中更新代码的时候,会触发浏览器的页面刷新,但是这次刷新是全量刷新,相当于CMD+R。这时候页面的状态会被重置,总之体验不好。模块热更新就是为了解决这样的问题,只刷新我们编辑的代码对应的模块,保持页面的状态。可以看到我们这里编辑代码的时候,下面count的状态被保存了。刚刚热更新了上面文本部分的模块。Why(WhydoyouneedHMR?)其实每一个技术的诞生都是为了解决之前已经强调过的问题。HMR也是如此,其实原因上面已经说了。总结如下:为什么需要HMR?解决修改代码后页面全量更新问题,体验差的问题解决全量更新导致状态丢失的问题How(HMR怎么用?)vite中实现的HMR系统其实就是一层封装ESMHMR规范中的API。vite会主动监听文件的变化,然后触发相应的API,实现模块的热更新。那么首先我们简单的看一下APIAPIhmr这套规范中的API都是注入到import.meta的hot中的。我们访问的时候只需要import.meta.hot.[name]import.meta是浏览器内置的对象。【MDN】interfaceImportMeta{readonlyhot?:{readonlydata:any//======触发更新=====accept():void//accept(cb:(mod:any)=>void):voidaccept(dep:string,cb:(mod:any)=>void):voidaccept(deps:string[],cb:(mods:any[])=>void):void//==================prune(cb:()=>void):voiddispose(cb:(data:any)=>void):voiddecline():voidinvalidate():void//=====监听hmrevent====on(event:string,cb:(...args:any[])=>void):void//===================}}accept(cb)accept翻译为接受。在hmr中,他也是这个意思:接受这个热更新,接受这个热更新的模块称为HMR边界。当我们在文件中加入这行代码,就是手动开启文件模块的热更新。当这个文件中的代码更新时,它会收到本次热更新的结果。if(import.meta.hot){import.meta.hot.accept((mod)=>{console.log(mod,'==')})}:::dangeraccept中的mod是更新后的模块exported内容。:::比如我们的文件如下,exportingrenderandother:exportconstrender=()=>{//...}exportconstother=()=>{//...}if(import.meta.hot){import.meta.hot.accept((mod)=>{console.log(mod,'==')})}那么当我们更新这个文件里面的代码,在这个地方接受热更新time在mod中是:如果我们需要接受其中一个导出模块的更新,那么直接调用mod.render()或mod.other()更新页面最新的内容。如果你文件中的导出方式默认是exportdefaultxxx,那么mod就是mod.default上面代码中我们通过一个回调函数accept来主动触发热更新模块中的函数。因为我们的文件只声明了render等函数,并没有执行,所以需要在accpet回调中手动触发。事实上,在某些情况下,不需要传递回调函数。accept将执行当前更改文件中的最新内容。比如我们的文件是可执行文件(类似于自执行函数)。当我们导入这个文件时,会执行文件中的代码,比如下面这种情况://render.tsconstrender=()=>{constapp=document.querySelectorHelloVite12
