The first Meteor 2.0 betas are now available with hot module replacement (HMR).
Hot module replacement updates the app while it is running, resulting in a better developer experience. It can apply updates to the client without reloading the page, most of the time completing before the rebuild has finished.
To try it, run these commands:
meteor update --release METEOR@2.0-beta.2
meteor add hot-module-replacement
HMR is only used in development, and doesn’t affect production builds.
HMR is currently enabled for app code in the modern client. Support for other client architectures and for packages will be implemented later. If a change can not be applied with HMR, it falls back to hot code push.
How it works
When an app depends on the hot-module-replacement
package, a HMR server is started in the meteor-tool. This provides a websocket server the app connects to to receive updates.
During a build, Meteor compares the current build with the previous build to identify any modified modules. It then immediately sends those to the app, even though the build is still in progress.
In the app, you can use the hot api to configure which modules are replaceable:
if (module.hot) {
module.hot.accept();
}
If a module accepts updates, it applies to updates to itself and any modules it imports.
When a module is modified, we run dispose functions so it can remove any timers, dom elements, or do anything else necessary for the module to no longer affect the app.
const interval = setInterval(doWork, 2000);
if (module.hot) {
module.hot.dispose(() => {
clearInterval(interval);
});
}
When a module is modified, we first check if it accepts the updates. If not, we look at the modules that import it, and so on until all paths lead to a module that accepts the updates. If it is accepted, we call the dispose functions on the modified module, the modules that accept the update, and the modules between those.
Then, we re-run the modules that accept the update, their dependencies that were disposed, and the updated modules if they are still imported by the app.
After the build is finished, hot code push is used if a change was not accepted or there were any changes that are not possible to update with HMR.
Integrations
Most of the time you don’t need to decide which modules accept updates or write your own dispose handlers. These integrations can handle it for your app.
React - Changes to react components are automatically handled by React Fast Refresh. Learn more in the React Native docs.
Svelte - replace svelte:compiler
with zodern:melte
.
PureAdmin - When a module is disposed, PureAdmin automatically removes any pages and menu items the module had added. You will still need to add module.hot.accept()
to the file or to a file that imports it for it to be updated with HMR.
We’ve been using HMR for a few apps, and it has been working well, though there are still many small details that need to be handled. We would appreciate any feedback on how reliable it works, and any issues with updating files that use Meteor’s core packages.
Learn more in the PR.
Also, I would like to thank e-Potek and @florianbienefelt for funding the initial implementation.