Webpack 中的热模块替换到底是什么? [英] What exactly is Hot Module Replacement in Webpack?

查看:16
本文介绍了Webpack 中的热模块替换到底是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过

一个模块只有在你接受"它时才能更新.所以你需要 module.hot.accept 父模块或父模块的父模块......例如Router 是个好地方,或者是一个子视图.

如果你只想与 webpack-dev-server 一起使用,只需添加 webpack/hot/dev-server 作为入口点.否则你需要一些 HMR 管理代码来调用 checkapply.

意见:是什么让它如此酷?

  • 这是 LiveReload,但适用于每种模块类型.
  • 您可以在生产中使用它.
  • 更新尊重您的代码拆分,并且仅下载应用已使用部分的更新.
  • 您可以将其用于应用程序的一部分,而不会影响其他模块
  • 如果 HMR 被禁用,编译器会删除所有 HMR 代码(将其包装在 if(module.hot) 中).

注意事项

  • 它是实验性的,没有经过很好的测试.
  • 预计会出现一些错误.
  • 理论上可用于生产,但现在将其用于严肃的事情可能还为时过早.
  • 需要在编译之间跟踪模块 ID,因此您需要存储它们(records).
  • 优化器在第一次编译后无法再优化模块 ID.对捆绑包大小有一点影响.
  • HMR 运行时代码增加了包的大小.
  • 对于生产用途,需要额外的测试来测试 HMR 处理程序.这可能非常困难.

I've read a few pages about Hot Module Replacement in Webpack.
There's even a sample app that uses it.

I've read all of this and still don't get the idea.

What can I do with it?

  1. Is it supposed to only be used in development and not in production?
  2. Is it like LiveReload, but you have to manage it yourself?
  3. Is WebpackDevServer integrated with LiveReload in some way?

Suppose I want to update my CSS (one stylesheet) and JS modules when I save them to disk, without reloading the page and without using plugins such as LiveReload. Is this something Hot Module Replacement can help me with? What kind of work do I need to do, and what does HMR already provide?

解决方案

First I want to note that Hot Module Replacement (HMR) is still an experimental feature.

HMR is a way of exchanging modules in a running application (and adding/removing modules). You basically can update changed modules without a full page reload.

Documentation

Prerequirements:

It's not so much for HMR, but here are the links:

I'll add these answers to the documentation.

How does it work?

From the app view

The app code asks the HMR runtime to check for updates. The HMR runtime downloads the updates (async) and tells the app code that an update is available. The app code asks the HMR runtime to apply updates. The HMR runtime applies the updates (sync). The app code may or may not require user interaction in this process (you decide).

From the compiler (webpack) view

In addition to the normal assets, the compiler needs to emit the "Update" to allow updating from a previous version to this version. The "Update" contains two parts:

  1. the update manifest (json)
  2. one or multiple update chunks (js)

The manifest contains the new compilation hash and a list of all update chunks (2).

The update chunks contain code for all updated modules in this chunk (or a flag if a module was removed).

The compiler additionally makes sure that module and chunk ids are consistent between these builds. It uses a "records" json file to store them between builds (or it stores them in memory).

From the module view

HMR is a opt-in feature, so it only affects modules that contains HMR code. The documentation describes the API that is available in modules. In general, the module developer writes handlers that are called when a dependency of this module is updated. They can also write a handler that is called when this module is updated.

In most cases, it's not mandatory to write HMR code in every module. If a module has no HMR handlers, the update bubbles up. This means a single handler can handle updates for a complete module tree. If a single module in this tree is updated, the complete module tree is reloaded (only reloaded, not transferred).

From the HMR runtime view (technical)

Additional code is emitted for the module system runtime to track module parents and children.

On the management side, the runtime supports two methods: check and apply.

A check does a HTTP request to the update manifest. When this request fails, there is no update available. Elsewise the list of updated chunks is compared to the list of currently-loaded chunks. For each loaded chunk, the corresponding update chunk is downloaded. All module updates are stored in the runtime as updates. The runtime switches into the ready state, meaning an update has been downloaded and is ready to be applied.

For each new chunk request in the ready state, the update chunk is also downloaded.

The apply method flags all updated modules as invalid. For each invalid module, there needs to be a update handler in the module or update handlers in every parent. Else the invalid bubbles up and marks all parents as invalid too. This process continues until no more "bubble up" occurs. If it bubbles up to an entry point, the process fails.

Now all invalid modules are disposed (dispose handler) and unloaded. Then the current hash is updated and all "accept" handlers are called. The runtime switches back to the idle state and everything continues as normal.

What can I do with it?

You can use it in development as a LiveReload replacement. Actually the webpack-dev-server supports a hot mode which tries to update with HMR before trying to reload the whole page. You only need to add the webpack/hot/dev-server entry point and call the dev-server with --hot.

You can also use it in production as update mechanisms. Here you need to write your own management code that integrates HMR with your app.

Some loaders already generate modules that are hot-updateable. e.g. The style-loader can exchange the stylesheet. You don't need to do anything special.

Suppose I want to update my CSS (one stylesheet) and JS modules when I save them to disk, without reloading the page and without using plugins such as LiveReload. Is this something Hot Module Replacement can help me with?

Yes

What kind of work do I need to do, and what does HMR already provide?

Here is a little example: https://webpack.js.org/guides/hot-module-replacement/

A module can only be updated if you "accept" it. So you need to module.hot.accept the module in the parents or the parents of the parents... e.g. A Router is a good place, or a subview.

If you only want to use it with the webpack-dev-server, just add webpack/hot/dev-server as entry point. Else you need some HMR management code that calls check and apply.

Opinion: What makes it so cool?

  • It's LiveReload but for every module kind.
  • You can use it in production.
  • The updates respect your Code Splitting and only download updates for the used parts of your app.
  • You can use it for a part of your application and it doesn't affect other modules
  • If HMR is disabled, all HMR code is removed by the compiler (wrap it in if(module.hot)).

Caveats

  • It's experimental and not tested so well.
  • Expect some bugs.
  • Theoretically usable in production, but it may be too early to use it for something serious.
  • The module IDs need to be tracked between compilations so you need to store them (records).
  • The optimizer cannot optimize module IDs any more after the first compilation. A bit of an impact on bundle size.
  • HMR runtime code increases the bundle size.
  • For production usage, additional testing is required to test the HMR handlers. This could be pretty difficult.

这篇关于Webpack 中的热模块替换到底是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆