一、Plugins://插件javascript
webpack has a rich plugin interface.Most of the features are internal plugins using this interface.This makes webpack very flexible.css
//webpack有一个丰富的插件接口。大部分的功能是使用这个接口的内部插件。这使webpack很是灵活。html
二、Performance://性能前端
webpack uses async I/ O and has multiple caching levels.This makes webpack fast and incredibly fast on incremental compilation.java
//Webpack使用异步I / O并具备多个缓存级别。这使得Webpack在增量编译时快速而使人难以置信。node
三、Loaders://加载器react
webpack supports pre- processing files via loaders.This allows you to bundle any static resource not only javascript.You can easily write your own loaders running in Node.js.webpack
//webpack支持经过装载程序预处理文件。 这容许您捆绑任何静态资源不只JavaScript。 您能够轻松地编写在Node.js中运行的本身的加载程序。git
四、Support://支持github
Webpack supports AMD and CommonJs module styles.It performs clever static analysis on the AST of your code.It even has an evaluation engine to evaluate simple expressions.This allow you to support most existing libraries.
//Webpack支持AMD和CommonJs模块样式。对代码的AST执行智能静态分析。它甚至有一个评估引擎来评估简单的表达式。这容许您支持大多数现有的库。
五、Code Splitting://代码分割
webpack allows you to split your codebase into chunks.Chunks are loaded on demand.This reduces initial loading time.
//webpack容许您将您的代码库拆分红chunks.Chunks是按需加载的。这减小了初始加载时间。
六、Optimizations://最优化
webpack can do many optimizations to reduce the output size.It also cares about request caching by using hashes.
//webpack能够进行许多优化来减小输出大小。它也关心经过使用散列值的请求缓存。
七、Development Tools://开发工具
webpack supports SourceUrls and SourceMaps for simple debugging.It can watch your files and comes with a development middleware and a development server for automatic reloading.
//webpack支持SourceUrls和SourceMaps进行简单的调试。它能够观看您的文件,并附带开发中间件和开发服务器进行自动从新加载。
八、Multiple targets://多重目标
webpack's main target is the web, but it also supports generating bundles for WebWorkers and Node.js.
//webpack的主要目标是web,但它也支持为Web Workers和Node.js生成bundle。
核心概念
webpack是用于现代JavaScript应用程序的模块绑定器。 当Webpack处理您的应用程序时,它递归地构建一个包含应用程序所需的每一个模块的依赖关系图,而后将全部这些模块打包到少许的捆绑(一般只有一个),由浏览器加载。
这是很是可配置的,但要开始,您只须要了解四核心概念:输入,输出,加载程序和插件。
本文档旨在对这些概念进行高级概述,同时提供详细概念具体用例的连接。
入口
webpack建立了全部应用程序依赖关系的图形。 该图的起始点被称为入口点。 入口点告诉webpack在哪里启动并遵循依赖关系的图表,以了解要捆绑的内容。 您能够将应用程序的入口点视为上下文根或第一个启动应用程序的文件。在webpack中,咱们使用webpack配置对象中的entry属性来定义入口点。
例子以下:
webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
有多种方式来声明您的输入属性,这些特定于应用程序的须要。
输出
将全部资源捆绑在一块儿后,您仍然须要告知webpack在何处捆绑应用程序。 webpack输出属性告诉webpack如何处理捆绑的代码。
webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
在上面的例子中,咱们使用output.filename和output.path属性来告诉webpack咱们的bundle的名称以及咱们但愿它被发射到哪里。
您可能会在整个文档和插件API中看到排除或排放的术语。 这是“生产”或“释放”的花哨术语。
输出属性具备更多可配置的功能,可是让咱们花一些时间了解输出属性的一些最多见的用例。
加载器
目标是使您的项目中的全部资产都是webpack的关注点,而不是浏览器(尽管如此,这并不意味着它们都必须捆绑在一块儿)。 webpack将每一个文件(.css,.html,.scss,.jpg等)视为一个模块。 可是,webpack自己只能理解JavaScript。
webpack中的装载器将这些文件转换成模块,由于它们被添加到依赖关系图中。
在高层次上,装载机在您的webpack配置中有两个目的。 他们服务于:
webpack.config.js
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
上述配置为具备两个必需属性的单个模块定义了一个规则属性:test和use。 这告诉webpack的编译器以下:
“嘿webpack编译器,当你遇到一个解决到一个'.txt'文件里面的一个require()/ import语句的路径,使用raw-loader来转换它,而后再把它添加到bundle中。
重要的是要记住,在Webpack配置中定义规则时,您须要在module.rules中定义它们,而不是规则。为了您的利益,若是这样作不正确,webpack会对你大喊大叫。
在咱们还没有涵盖的装载机上还有其余更具体的属性。
虽然Loader仅在每一个文件的基础上执行转换,但插件最经常使用于对捆绑模块的“compilations”或“chunks”执行操做和自定义功能(以及更多!)。 webpack插件系统很是强大,可定制。
为了使用插件,您只须要require()并将其添加到plugins数组。 大多数插件可经过选项进行自定义。 因为您能够在配置中屡次使用插件进行不一样的目的,所以您须要经过使用新建来建立一个实例。
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
网路包提供开箱即用的许多插件! 查看咱们的插件列表了解更多信息。
在webpack配置中使用插件是很简单的 - 可是有不少用例值得进一步探讨。Learn more!
如“入门”中所述,有多种方法能够在Webpack配置中定义条目属性。 咱们将向您介绍如何配置条目属性,以及解释为何它可能对您有用。.
Usage: entry: string|Array<string>
webpack.config.js
const={config
:'./path/to/my/entry/file.js' entry
};
.=;moduleexportsconfig
入口属性的单入口语法是一个缩写:
const={config
:{ entry
:'./path/to/my/entry/file.js' main
}
};
当您将数组传递到条目时会发生什么?将一系列文件路径传递给entryproperty建立一个所谓的“多主条目”。当您要将多个相关文件一块儿注入并将其依赖关系映射到一个“块”中时,这颇有用。
Usage: entry: {[entryChunkName: string]: string|Array<string>}
webpack.config.js
const={config
:{ entry
:'./src/app.js', app
:'./src/vendors.js' vendors
}
};
对象语法更详细。 可是,这是在应用程序中定义条目/条目的最可扩展的方式。
“可扩展Webpack配置”是可重复使用并与其余部分配置组合的配置。这是一种流行的技术,用于分离环境,构建目标和运行时间。而后使用专门的工具(如webpack-merge)将它们合并。
下面列出了入门配置及其真实用例:
webpack.config.js
const={config
:{ entry
:'./src/app.js', app
:'./src/vendors.js' vendors
}
};
这是作什么的? 在面值上,这告诉webpack从app.js和vendors.js开始建立依赖关系图。 这些图是彻底独立的,彼此独立(每一个包中都会有一个webpack引导)。 单页应用程序一般只有一个入口点(不包括供应商)。
为何? 此设置容许您利用CommonsChunkPlugin并将应用程序包中的任何供应商引用提取到供应商捆绑包中,并使用__webpack_require __()调用替换它们。若是您的应用程序包中没有供应商代码,那么您能够在Webpack中实现一种称为长期供应商缓存的常见模式。
考虑删除这种状况,有利于DllPlugin,从而提供更好的供应商分割。
webpack.config.js
const={config
:{ entry
:'./src/pageOne/index.js', pageOne
:'./src/pageTwo/index.js', pageTwo
:'./src/pageThree/index.js' pageThree
}
};
这是作什么的? 咱们告诉webpack咱们想要3个独立的依赖关系图(像上面的例子)。
为何? 在多页面应用程序中,服务器将为您提供一个新的HTML文档。 该页面从新加载此新文档,并从新下载资产。 然而,这给了咱们独特的机会来作多件事情:
配置输出配置选项告诉webpack如何将编译的文件写入磁盘。 请注意,虽然能够有多个入口点,但只指定一个输出配置.
在webpack配置中,输出属性的最低要求是将其值设置为一个对象,包括如下两件事:
webpack.config.js
const={config
:{ output
:'bundle.js', filename
:'/home/proj/public/assets' path
}
};
.=;moduleexportsconfig
此配置将将一个bundle.js文件输出到/ home / proj / public / assets目录中.
若是您的配置建立多个单独的“块”(如多个入口点或使用像CommonsChunkPlugin这样的插件),您应该使用替换来确保每一个文件具备惟一的名称.
{
:{ entry
:'./src/app.js', app
:'./src/search.js' search
},
:{ output
:'[name].js', filename
:+'/dist' path__dirname
}
}
// writes to disk: ./dist/app.js, ./dist/search.js
这是一个更复杂的使用CDN和assets的哈希表的例子:
config.js
:{output
:"/home/proj/cdn/assets/[hash]", path
:"http://cdn.example.com/assets/[hash]/" publicPath
}
若是输出文件的最终publicPath在编译时未知,则能够在运行时在入口点文件中保留空白并动态设置。 若是在编译时不知道publicPath,能够省略它,并在入口点设置__webpack_public_path__.
=__webpack_public_path__myRuntimePublicPath
// rest of your application entry
装载机是应用于模块源代码的转换。 它们容许您在导入或“加载”时预处理文件。 所以,装载机在其余构建工具中相似于“任务”,并提供了处理前端构建步骤的强大方法。 加载程序能够将文件从不一样的语言(如TypeScript)转换为JavaScript,或将内联图像转换为数据URL。 装载器甚至容许您直接从JavaScript模块执行导入CSS文件的事情!
例如,您可使用加载器告诉webpack加载一个CSS文件或将打印文件转换为JavaScript。要作到这一点,首先须要安装您须要的加载器:
installnpm--save-dev css-loader
installnpm--save-dev ts-loader
而后指示webpack为每一个.css文件和全部.ts文件的ts-loader
使用css-loader
:
webpack.config.js
.={moduleexports
:{ module
:[ rules
{:/\.css$/,:'css-loader'}, testuse
{:/\.ts$/,:'ts-loader'} testuse
]
}
};
你能够在应用程序中经过如下三种方式使用加载器:
module.rules
容许您在Webpack配置中指定多个加载程序。 这是显示加载程序的简明方法,有助于维护干净的代码。 它还为您提供每一个相应加载器的完整概述:
:{ module
:[ rules
{
:/\.css$/, test
:[ use
{:}, loader'style-loader'
{
:, loader'css-loader'
:{ options
:true modules
}
}
]
}
]
}
能够在import语句中指定加载器,也可使用任何等效的“importing”方法。 使用!分开装载机与资源。 每一个部分都相对于当前目录进行解析。
importfrom'style-loader!css-loader?modules!./styles.css';Styles
能够经过预修复整个规则来覆盖配置中的任何加载器!
选项能够经过查询参数传递,例如。 ?key = value&foo = bar,或JSON对象,例如{"key":"value","foo":"bar"
}.
使用模块。尽量的规则,由于这将减小源代码中的样板文件,并容许您更快地调试或定位加载器
你也能够经过命令行使用装载机:
'css=style-loader!css-loader'webpack --module-bind jade-loader --module-bind
这使用.jade文件的jade-loader和.cssfiles的style-loader
和css-loader
.
加载器能够连接。 它们被应用于资源管道。 一系列装载机按时间顺序编排。 加载器链中的第一个加载器将返回值。 在最终装入程序中,webpack但愿返回JavaScript。
加载器经过预处理功能(加载器)在JavaScript生态系统中提供更多的动力。 用户如今有更多的灵活性,包括细粒度的逻辑,如压缩,打包,语言翻译等.
加载器遵循标准模块解析。 在大多数状况下,它将是模块路径的加载程序(think npm install,node_modules)。
装载器模块预计导出一个函数并写入Node.js兼容的JavaScript。 它们最经常使用npm进行管理,但您也能够将自定义加载程序做为应用程序中的文件。 按照惯例,加载器一般被命名为xxx-loader(例如json-loader)。 请参阅“如何编写装载机?” 了解更多信息.
插件是webpack的backbone 。 webpack自己是创建在您在Webpack配置中使用的同一个插件系统上的!
它们也用于作任何loader 不能作的事情.
插件是一个具备apply
属性的JavaScript对象。 该应用程序属性由webpack编译器调用,能够访问整个编译生命周期.
ConsoleLogOnBuildWebpackPlugin.js
functionConsoleLogOnBuildWebpackPlugin(){
};
..=function(){ConsoleLogOnBuildWebpackPluginprototypeapplycompiler
.plugin('run',function(,){ compilercompilercallback
.log("The webpack build process is starting!!!"); console
callback();
});
};
做为一个聪明的JavaScript开发人员,您能够记住Function.prototype.apply方法。因为这种方法,您能够传递任何函数做为插件(这将指向编译器)。您可使用此样式在配置中内联自定义插件。
因为插件能够引用参数/选项,所以必须将新实例传递到Webpack配置中的plugins属性。
根据您使用webpack的方式,有多种方法可使用插件。
webpack.config.js
const=require('html-webpack-plugin');//installed via npmHtmlWebpackPlugin
const=require('webpack');//to access built-in pluginswebpack
const=require('path');path
const={config
:'./path/to/my/entry/file.js', entry
:{ output
:'my-first-webpack.bundle.js', filename
:.resolve(,'dist') pathpath__dirname
},
:{ module
:[ rules
{
:/\.(js|jsx)$/, test
:'babel-loader' use
}
]
},
:[ plugins
newwebpack.optimize.UglifyJsPlugin(),
newHtmlWebpackPlugin({:'./src/index.html'}) template
]
};
.=;moduleexportsconfig
即便使用Node API,用户也能够经过配置中的plugins属性传递插件。使用compiler.apply不该该是推荐的方法。
some-node-script.js
const=require('webpack');//to access webpack runtime webpack
const=require('./webpack.config.js'); configuration
let=webpack(); compilerconfiguration
.apply(newwebpack.ProgressPlugin()); compiler
.run(function(,){ compilererrstats
// ...
});
你知道吗:上面看到的例子与webpack runtime itself! 很是类似!有不少很棒的使用示例隐藏在webpack source code中,您能够将其应用于您本身的配置和脚本!
您可能已经注意到不多的webpack配置看起来是彻底同样的。 这是由于webpack的配置文件是一个导出对象的JavaScript文件。 该对象而后由webpack根据其定义的属性进行处理.
由于它是一个标准的Node.js CommonJS模块,您能够执行如下操做:
require
(...)
导入其它文件。
require(...)
在
npm
上使用实用程序。
虽然技术上可行,但应避免如下作法:
--env
). 取消此文档的最重要的部分是有多种不一样的格式和样式您的Webpack配置的方式。关键是坚持一致的方式,让您和您的团队可以理解和维护。
如下如下示例描述了Webpack的配置对象是否能够表现和配置,由于它是代码:
webpack.config.js
var=require('path');path
.={moduleexports
:'./foo.js', entry
:{ output
:.resolve(,'dist'), pathpath__dirname
:'foo.bundle.js' filename
}
};
查看: 导出多个配置
接受以多种编程和数据语言编写的配置文件.
在模块化编程中,开发人员将程序分解成称为模块的独立功能块.
每一个模块具备比完整程序更小的表面积,使验证,调试和测试变得微不足道。 精心编写的模块提供了坚实的抽象和封装边界,使得每一个模块在整个应用程序中具备一致的设计和明确的目的。
Node.js自成立以来就一直支持模块化编程。 然而,在网络上,对模块的支持速度很慢。 存在支持Web上模块化JavaScript的多种工具,具备各类优势和限制。 webpack基于从这些系统学到的经验教训,并将模块的概念应用于项目中的任何文件.
与Node.js modules相反,webpack模块能够经过各类方式表达其依赖关系。 几个例子是:
require()
语句define
和 require
语句@import
statement 里面的一个css/sass/less 文件.url(...)
) 或html(<img src=...>
)文件.webpack 1须要一个特定的加载程序来转换ES2015导入,可是这能够经过webpack 2开箱便可
支持经过加载程序以各类语言和预处理器编写的模块。 Loaders描述了webpack如何处理非JavaScript模块,并将这些依赖项包含在您的包中。 Webpack社区已经为各类流行语言和语言处理器构建了加载器,包括:
还有不少人! 总的来讲,Webpack提供了一个功能强大的API,用于定制,可让任何堆栈使用webpack,同时对开发,测试和生产工做流程保持不了解。
查看所有清单,请看 the list of loaders or write your own
解析器是一个库,它有助于经过其绝对路径定位模块。 一个模块能够被要求做为另外一个模块的依赖关系:
importfrom'path/to/module'foo
// or
require('path/to/module')
依赖关系模块能够来自应用程序代码或第三方库。 解析器帮助webpack找到须要包含在每一个这样的require / import语句的bundle中的模块代码.在捆绑模块时使用加强解决方案来解析文件路径.
使用加强解决方案,webpack能够解析三种文件路径:
import"/home/me/file";
import"C:\\Users\\me\\file";
由于咱们已经有了文件的绝对路径,因此不须要进一步的解决方案。
import"../src/file1";
import"./file2";
在这种状况下,导入或要求发生的资源文件的目录被认为是上下文目录。 在import / require中指定的相对路径被链接到该上下文路径以产生模块的绝对路径。
import"module";
import"module/lib/file";
在resolve.modules
中指定的全部目录中搜索模块。 您可使用resolve.alias
选项为备用路径替换原始模块路径,方法是为其建立别名。
一旦根据上述规则解决路径,解析器检查路径是否指向文件或目录。 若是路径指向一个文件:
若是路径指向一个文件夹,则采起如下步骤来查找具备正确扩展名的正确文件:
这遵循与为文件解析指定的规则相同的规则。 可是, resolveLoader
配置选项可用于为装载程序分别设置分辨率规则。
每一个文件系统访问都被缓存,以便对同一个文件的多个并行或串行请求发生得更快。 在监视模式下,只有修改过的文件才从缓存中逐出。 若是监视模式为关闭,则在每次编译以前都会清除缓存。
请参阅 Resolve API以了解有关上述配置选项的更多信息。
任什么时候候一个文件依赖于另外一个文件,webpack将其视为依赖关系。 这容许Webpack采起非代码资产(如图像或Web字体),并将它们提供为应用程序的依赖关系。
当Webpack处理您的应用程序时,它将从在命令行或其配置文件中定义的模块列表开始。 从这些入口点开始,webpack递归地构建一个依赖图,包括应用程序所需的每一个模块,而后将全部这些模块都封装成少许的捆绑(一般只有一个),由浏览器加载。捆绑您的应用程序对于HTTP / 1.1客户端特别强大,由于它能够最大限度地减小您的应用在浏览器启动新请求时等待的次数。 对于HTTP / 2,您还可使用代码分割和经过webpack捆绑进行最佳优化。
由于能够为服务器和浏览器编写JavaScript,因此Webpack提供了能够在Webpack配置中设置的多个部署目标。
webpack target属性不会与output.libraryTarget属性混淆。有关更多信息,请参阅咱们的输出属性指南。
要设置目标属性,您只需在webpack config中设置目标值便可:webpack.config.js
.={moduleexports
:'node' target
};
在上面的示例中,使用节点webpack将编译为在相似Node.js的环境中使用(使用Node.js须要加载块,而不要接触任何内置的模块,如fs或路径)。
每一个目标都有各类部署/环境特定的添加,支持以知足其需求。 查看可用的目标。
进一步扩大其余受欢迎的目标值
Although webpack does not support multiple strings being passed into the target
property, you can create an isomorphic library by bundling two separate configurations:
webpack.config.js
var=require('path');path
var={serverConfig
:'node', target
:{ output
:.resolve(,'dist'), pathpath__dirname
:'lib.node.js' filename
}
//…
};
var={clientConfig
:'web',// <=== can be omitted as default is 'web' target
:{ output
:.resolve(,'dist'), pathpath__dirname
:'lib.js' filename
}
//…
};
.=[,];moduleexportsserverConfigclientConfig
The example above will create a lib.js
and lib.node.js
file in your dist
folder.
As seen from the options above there are multiple different deployment targets that you can choose from. Below is a list of examples, and resources that you can refer to.
Need to find up to date examples of these webpack targets being used in live code or boilerplates.
在使用webpack构建的典型应用程序或站点中,有三种主要的代码类型:
本文将重点介绍这三个部分中的最后一个,运行时,特别是清单.
如上所述,咱们只会简单介绍一下。 运行时以及清单数据基本上都是在浏览器中运行时链接模块化应用程序所需的代码webpack。 它包含与模块相互链接所需的加载和解析逻辑。 这包括已经加载到浏览器中的链接模块以及延迟加载的模块。
那么,一旦您的应用程序以index.html文件,一些捆绑包和各类其余资产的形式访问浏览器,它的外观如何? 那个你精心布置的/ src目录如今已经没了,那么webpack如何管理全部模块之间的交互? 这是清单资料来的地方...
当编译器进入,解析和映射您的应用程序时,它会保留全部模块的详细说明。 数据集合称为“清单”,运行时将用于解析和加载模块,一旦捆绑并发送到浏览器。 不管您选择哪一种模块语法,那些import或require语句如今都成为__webpack_require__指向模块标识符的方法。 使用清单中的数据,运行时将可以找出在标识符后面检索模块的位置。
因此如今你有一些关于webpack如何在幕后工做的洞察力。 “可是,这怎么会影响我呢?”你可能会问。 简单的答案是大部分时间没有。 运行时将使用清单来执行其操做,而且一旦应用程序访问浏览器,全部内容就会出现神奇的工做。 可是,若是您决定经过使用浏览器缓存来改善项目的性能,这个过程将忽然变得重要。
经过使用您的包文件名中的内容散列,您能够在浏览器中指示文件的内容发生变化,从而使缓存无效。 一旦你开始这样作,你会当即注意到一些有趣的行为。 即便他们的内容显然没有,某些哈希也会改变。 这是因为注入运行时和清单而致使的,每次构建都会发生变化。
请参阅咱们的管理构建文件指南的清单部分,了解如何提取清单,并阅读如下指南,以了解有关长期缓存复杂度的更多信息。
热模块更换(HMR)在应用程序运行时交换,添加或删除模块,而不须要彻底从新加载。 这能够经过几种方式大大加快开发速度:
让咱们经过一些不一样的观点来了解HMR的工做原理.....
下面的步骤容许模块在应用程序中进行交换:
您能够设置HMR,以便自动执行此过程,或者您能够选择要求用户进行交互以进行更新。
除正常的资产以外,编译器须要发出一个“更新”来容许从之前版本更新到新版本。 “更新”由两部分组成:
清单包含新的编译哈希和全部更新的块的列表。 这些块中的每个都包含全部更新模块的新代码(或指示模块已被删除的标志)。
编译器确保模块ID和块ID在这些构建之间是一致的。 它一般将这些ID存储在内存中(例如使用webpack-dev-server),但也能够将它们存储在JSON文件中。
HMR是一个选择加入功能,仅影响包含HMR代码的模块。 一个例子是经过样式装载器修补样式。 为了修补工做,样式加载器实现了HMR接口; 当它经过HMR接收到更新时,它会用新的样式替换旧样式。
相似地,当在模块中实现HMR接口时,能够描述更新模块时应该发生的状况。 然而,在大多数状况下,在每一个模块中都没必要写入HMR代码。 若是一个模块没有HMR处理程序,更新会起起来。 这意味着单个处理程序能够更新完整的模块树。 若是树中的单个模块已更新,则将从新加载整个依赖关系。
有关module.hot接口的详细信息,请参阅HMR API页面。
这里的东西有一些技术更多...若是您对内部不感兴趣,请随时跳到HMR API page或HMR guide.。
对于模块系统运行时,会发出附加代码跟踪模块父母和子项。在管理方面,运行时支持两种方法:检查和应用。
检查会向更新清单发出HTTP请求。若是此请求失败,则没有可用的更新。若是成功,将更新的块的列表与当前加载的块的列表进行比较。对于每一个加载的块,下载相应的更新块。全部模块更新都存储在运行时。当全部更新块都已经下载并准备应用时,运行时切换到就绪状态。
apply方法将全部更新的模块标记为无效。对于每一个无效模块,模块或其父代都须要一个更新处理程序。不然,无效标志也会起泡并使父代无效。每一个气泡继续,直到应用程序的入口点或具备更新处理程序的模块达到(以先到者为准)。若是从入口点起泡,过程将失败。
以后,全部无效模块都经过处理处理程序进行处理并卸载。而后更新当前的哈希,并调用全部接受的处理程序。运行时切换回空闲状态,一切正常。
HMR能够在开发中用做LiveReload替换。 webpack-dev-server支持在尝试从新加载整个页面以前尝试使用HMR进行更新的热模式。 有关详细信息,请参阅热模块更换指南。
与许多其余功能同样,webpack的优点在于其可定制性。根据特定项目的须要,有许多配置HMR的方法。然而,对于大多数目的而言,webpack-dev-server是一个很好的配合,可让您快速入门HMR。