一、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。