Angular HMR(热模块替换)功能实现方法
最近一个同事在使用Angular的时候,希望能像VUE那样,修改代码后浏览器不刷新,页面对应修改的组件自动更新的功能。这个功能的名字时HMR(hotmodulereplace)。
稍微研究了一下,发现在angular/cli创建的项目中,实现这个不算太难,步骤如下:
1、首先创建一个src/environments/environment.hmr.ts文件,内容如下
exportconstenvironment={ production:false, hmr:true };
当然,对应的environment.prod.ts和environment.ts需要增加一个hmr:false.
如果environment.ts里面的hmr设置为ture,那么ngserve--hmr也有同样效果。不过我对热替换功能还不是那么相信,重新刷新浏览器能保证状态更加干净一些,所以让environment.ts中的hmr为false.
2、在.angular-cli.json文件的环境中增加hmr的环境,大致如下:
"environments":{ ... "hmr":"environments/environment.hmr.ts", }
3、在package.json的scripts中增加一个新的命令。(当然也可以不增加,直接运行ngserve--hmr-e=hmr和运行npmrunhmr效果一样)
"scripts":{ ... "hmr":"ngserve--hmr-e=hmr" }
4、安装hmr模块,命令如下:
npminstall--save-dev@angularclass/hmr
5、创建src\hmr.ts文件,内容如下:
import{NgModuleRef,ApplicationRef}from'@angular/core'; import{createNewHosts}from'@angularclass/hmr'; exportconsthmrBootstrap=(module:any,bootstrap:()=>Promise>)=>{ letngModule:NgModuleRef ; module.hot.accept(); bootstrap().then(currentModule=>ngModule=currentModule); module.hot.dispose(()=>{ constappRef:ApplicationRef=ngModule.injector.get(ApplicationRef); constelements=appRef.components.map(c=>c.location.nativeElement); constremoveOldHosts=createNewHosts(elements); ngModule.destroy(); removeOldHosts(); }); };
这事热替换的关键,hmrBootstrap会替换原始的bootstrap(下面会看到),替换后,当有新的模块更新时,hmr会首先移除掉旧有的模块,然后接收新的模块。这些都是发生在浏览器里面。所以页面不会刷新。
6、更新src\main.ts文件如下:
import{enableProdMode}from'@angular/core'; import{platformBrowserDynamic}from'@angular/platform-browser-dynamic'; import{AppModule}from'./app/app.module'; import{environment}from'./environments/environment'; import{hmrBootstrap}from'./hmr'; if(environment.production){ enableProdMode(); } constbootstrap=()=>platformBrowserDynamic().bootstrapModule(AppModule); if(environment.hmr){ if(module['hot']){ hmrBootstrap(module,bootstrap); }else{ console.error('Ammm..HMRisnotenabledforwebpack'); } }else{ bootstrap(); }
这里替换就得启动文件,如果设置为hmr,那么调用hmrBootStrap来启动网页,否则就用过去的
7、现在运行npmrunhmr或者ngserve--hmr-e=hmr,就实现了热替换功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。