<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                HMR 全稱是 Hot Module Replacement,即模塊熱替換。在這個概念出來之前,我們使用過 Hot Reloading,當代碼變更時通知瀏覽器刷新頁面,以避免頻繁手動刷新瀏覽器頁面。HMR 可以理解為增強版的 Hot Reloading,但不用整個頁面刷新,而是局部替換掉部分模塊代碼并且使其生效,可以看到代碼變更后的效果。所以,HMR 既避免了頻繁手動刷新頁面,也減少了頁面刷新時的等待,可以極大地提高前端頁面開發效率。 ## 配置使用 HMR HMR 是 webpack 提供的非常有用的一個功能,跟我們之前提到的一樣,安裝好 webpack-dev-server, 添加一些簡單的配置,即在 webpack 的配置文件中添加啟用 HMR 需要的兩個插件: ``` const webpack = require('webpack') module.exports = { // ... devServer: { hot: true // dev server 的配置要啟動 hot,或者在命令行中帶參數開啟 }, plugins: [ // ... new webpack.NamedModulesPlugin(), // 用于啟動 HMR 時可以顯示模塊的相對路徑 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件 ], } ``` > 筆者覺得 HMR 應該是 development mode 默認啟動的功能,這個希望 webpack 后續能有優化。 ## HMR 運行原理 HMR 的實現和運行相對復雜,需要多個部分協同配合,這里稍微介紹一下 HRM 的運行原理。 首先我們要知道一個概念:webpack 內部運行時,會維護一份用于管理構建代碼時各個模塊之間交互的表數據,webpack 官方稱之為 **Manifest**,其中包括入口代碼文件和構建出來的 bundle 文件的對應關系。可以使用 [WebpackManifestPlugin](https://github.com/danethurber/webpack-manifest-plugin) 插件來輸出這樣的一份數據。 了解這個概念后,我們來看一下 HMR 的大致運行流程圖。 ![](https://img.kancloud.cn/ce/f4/cef46b55fb9c762af7510b47d85c8727_1267x884.jpg) 當你使用前面的配置啟動了支持 HMR 的 webpack-dev-server,然后在瀏覽器打開頁面時,你也可以從控制臺看到大概的 HMR 執行流程: ![](https://img.kancloud.cn/3d/89/3d8953b3584a804848b0bbb2ad84ec52_390x120.jpg) 開啟了 hot 功能的 webpack 會往我們應用的主要代碼中添加 WS 相關的代碼,用于和服務器保持連接,等待更新動作。 當你配置了 HMR 的插件時,會往應用代碼中添加 HMR 運行時的代碼,主要用于定義代碼模塊應用更新時的 API,后面會詳細介紹。 > 有興趣可以查看源碼:[HotModuleReplacement.runtime.js](https://github.com/webpack/webpack/blob/master/lib/HotModuleReplacement.runtime.js)。 有了這兩個部分就可以支持整個 HMR 的功能了。我們先忽略流程圖的右上角部分,左下角的流程相對容易理解:當有更新時,webpack-dev-server 發送更新信號給 HMR 運行時,然后 HMR 再請求所需要的更新數據,請求的更新數據沒有問題的話就應用更新。 如果 HMR 只是簡單替換了代碼模塊的內容,如替換掉所謂的 `installedModules` 中需要更新的部分,那么這樣并沒有辦法把更新后的結果實時地在瀏覽器上顯示出來,所以才會需要流程圖的右上角部分。 > 如果無法理解 `installedModules`,可以參考第 13 小節中的「bundler 的基礎流程」這一部分的內容 前面提到的 HMR 運行時代碼會提供定義代碼模塊應用更新時執行的 API,這些 API 可以讓我們在模塊中定義接收到 HMR 更新應用信號時,需要額外做什么工作。例如, [style-loader](https://github.com/webpack-contrib/style-loader) 就需要實現 HMR 接口,當收到更新時,使用新的樣式替換掉舊的樣式,大概是這樣: ``` if (module.hot) { module.hot.accept('/some/path', function() { // ... 用新樣式替換舊樣式 }) } ``` 詳情可以參考 [style-loader](https://github.com/webpack-contrib/style-loader) 中的代碼實現:[HMR interface implemention in style-loader](https://github.com/webpack-contrib/style-loader/blob/master/index.js#L36)。 HMR 應用更新時是使用 `webpackHotUpdate` 來處理的: ``` webpackHotUpdate(id, { 'modulePath': function() { // 模塊更新后的代碼 } }) ``` 執行 `webpackHotUpdate` 時如發現模塊代碼實現了 HMR 接口,就會執行相應的回調或者方法,從而達到應用更新時,模塊可以自行管理自己所需要額外做的工作。不過,并不是所有的模塊都需要做相關的處理,當遇見沒有實現 HMR 接口的模塊時,就會往上層冒泡,如本節開頭部分的流程圖所示。 這里還有一個問題是,webpack 如何保證 HMR 接口中的引用是最新的模塊代碼?我們看一個簡單的例子: ``` import './index.css' import hello from './bar' hello() if (module.hot) { module.hot.accept('./bar', () => { // console.log('Accepting the updated bar module!') hello() }) } ``` 從代碼上看,hello 都是同一個,這樣的話并沒有辦法引用最新的模塊代碼,但是我們看一下上述代碼在 webpack 構建后的結果: ``` if (true) { module.hot.accept("./src/bar.js", function(__WEBPACK_OUTDATED_DEPENDENCIES__) { /* harmony import */ __WEBPACK_IMPORTED_MODULE_1__bar__ = __webpack_require__("./src/bar.js"); (() => { // console.log('Accepting the updated bar module!') Object(__WEBPACK_IMPORTED_MODULE_1__bar__["default"])() })(__WEBPACK_OUTDATED_DEPENDENCIES__); }) } ``` 其他代碼比較雜,我們集中看 `module.hot` 的處理部分。這里可以發現,我們的 hello 已經重新使用 `__webpack_require__` 來引用了,所以可以確保它是最新的模塊代碼。 基本上 HMR 的執行原理就是這樣,更具體的實現部分就不展開講解了。在日常開發中,我們需要更多的工具來幫助我們實現 HMR 的接口,避免編寫過多 HMR 需要的代碼。例如,React 在組件代碼更新時可能需要觸發重新 render 來實現實時的組件展示效果,官方提供了一些現有的工具,需要的可以參考一下:[hot module replacement tools](https://webpack.js.org/guides/hot-module-replacement/#other-code-and-frameworks)。 ## module.hot 常見的 API 前面 HMR 實現部分已經講解了實現 HMR 接口的重要性,下面來看看常見的 `module.hot` API 有哪些,以及如何使用。 之前已經簡單介紹過,`module.hot.accept` 方法指定在應用特定代碼模塊更新時執行相應的 callback,第一個參數可以是字符串或者數組,如: ``` if (module.hot) { module.hot.accept(['./bar.js', './index.css'], () => { // ... 這樣當 bar.js 或者 index.css 更新時都會執行該函數 }) } ``` `module.hot.decline` 對于指定的代碼模塊,拒絕進行模塊代碼的更新,進入更新失敗狀態,如 `module.hot.decline('./bar.js')`。這個方法比較少用到。 `module.hot.dispose` 用于添加一個處理函數,在當前模塊代碼被替換時運行該函數,例如: ``` if (module.hot) { module.hot.dispose((data) => { // data 用于傳遞數據,如果有需要傳遞的數據可以掛在 data 對象上,然后在模塊代碼更新后可以通過 module.hot.data 來獲取 }) } ``` `module.hot.accept` 通常用于指定當前依賴的某個模塊更新時需要做的處理,如果是當前模塊更新時需要處理的動作,使用 `module.hot.dispose` 會更加容易方便。 `module.hot.removeDisposeHandler` 用于移除 `dispose` 方法添加的 callback。 關于 `module.hot` 的更多 API 詳情可以參考官方文檔:[Hot Module Replacement APIs](https://doc.webpack-china.org/api/hot-module-replacement)。 ## 小結 Hot Module Replacement 是 webpack 具備的一個相當重要的特性,用于提升開發效率和體驗。在這一小節中,我們介紹了: * 在 webpack 中配置使用 HMR * HMR 的運行原理 * 模塊中的 HMR 接口 API ## 例子 本小節提及的一些簡單的 Demo 可以在 [webpack-examples](https://github.com/teabyii/webpack-examples) 找到。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看