Angular开发实践(二):HRM运行机制
引言
在angular-start项目中启用了模块热替换(HMR - Hot Module Replacement)
功能,关于如何在angular-cli
启用HRM
,请查看HRM配置
那HMR
是个什么东西呢?
HMR
是webpack
提供的一个功能,angular-cli
使用了它,它会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:
- 保留在完全重新加载页面时丢失的应用程序状态
- 只更新变更内容,以节省宝贵的开发时间
- 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式
这一切是如何运行的?
我们先看看具体的效果:
1、启动angular-start
项目,在控制台你可以看到HRM
已经启用的消息:
image
2、然后通过浏览器控制台可以看到,第一次加载请求了所有的资源:
image
3、此时,修改一处代码保存,浏览器并未刷新就自动显示修改之后的效果,再看浏览器控制台只请求了新修改的js:
image
下面让我们从一些不同的角度观察,以了解HMR
的工作原理……
在应用程序中
通过以下步骤,可以做到在应用程序中置换(swap in and out
)模块:
- 应用程序代码要求 HMR runtime 检查更新
- HMR runtime(异步)下载更新,然后通知应用程序代码
- 应用程序代码要求 HMR runtime 应用更新
- HMR runtime(异步)应用更新
在编译器中
除了普通资源,编译器(compiler
)需要发出update
,以允许更新之前的版本到新的版本。update
由两部分组成:
- 更新后的
manifest (JSON)
- 一个或多个更新后的
chunk (JavaScript)
manifest
包括新的编译hash
和所有的待更新chunk
目录。每个更新chunk
都含有对应于此chunk
的全部更新模块(或一个flag
用于表明此模块要被移除)的代码。
编译器确保模块ID
和chunk ID
在这些构建之间保持一致。通常将这些ID
存储在内存中(例如,使用webpack-dev-server
时),但是也可能将它们存储在一个JSON
文件中。
在模块中
HMR
是可选功能,只会影响包含HMR
代码的模块。举个例子,通过style-loader
为style
样式追加补丁。为了运行追加补丁,style-loader
实现了HMR
接口;当它通过HMR
接收到更新,它会使用新的样式替换旧的样式。
类似的,当在一个模块中实现了HMR
接口,你可以描述出当模块被更新后发生了什么。然而在多数情况下,不需要强制在每个模块中写入HMR
代码。如果一个模块没HMR
处理函数,更新就会冒泡。这意味着一个简单的处理函数能够对整个模块树(complete module tree)
进行更新。如果在这个模块树中,一个单独的模块被更新,那么整组依赖模块都会被重新加载。
有关 module.hot 接口的详细信息,请查看HMR API页面。
在HMR Runtime中
对于模块系统的runtime
,附加的代码被发送到parents
和children
跟踪模块。在管理方面,runtime
支持两个方法check
和apply
。
check
发送HTTP
请求来更新manifest
。如果请求失败,说明没有可用更新。如果请求成功,待更新chunk
会和当前加载过的chunk
进行比较。对每个加载过的chunk
,会下载相对应的待更新chunk
。当所有待更新chunk
完成下载,就会准备切换到ready
状态。
apply
方法将所有被更新模块标记为无效。对于每个无效模块,都需要在模块中有一个更新处理函数,或者在它的父级模块们中有更新处理函数。否则,无效标记冒泡,并也使父级无效。每个冒泡继续直到到达应用程序入口起点,或者到达带有更新处理函数的模块(以最先到达为准)。如果它从入口起点开始冒泡,则此过程失败。
之后,所有无效模块都被(通过dispose
处理函数)处理和解除加载。然后更新当前hash
,并且调用所有accept
处理函数。runtime
切换回闲置状态,一切照常继续。
- 云端架构师养成之三:微信也在用的消息队列服务
- 现在 tensorflow和mxnet 很火,是否还有必要学习 scikit-learn 等框架?
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
- 改进版CodeTimer及XCode性能测试
- 常见测试术语解析
- 秦俊:开放 DevOps 敏捷开发套件,助力开发者驰骋云端
- 开源组件NanUI一周年-使用HTML/CSS/JS来构建.Net Winform应用程序界面
- 邱寒:新零售笔记(四)基于区块链大数据的人工智能
- 腾讯云GAME-TECH沙龙干货回顾:网龙《英魂之刃口袋版》开发经验分享
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
- 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络AlexNet
- 黄荣奎:如何快速、便捷开发小程序
- 熊普江: BGP网络架构助力开发者快速构建、优化业务
- 唐良:云端架构给电商行业带来创新力
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法