Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 8, 2019. It is now read-only.
/docsPublic archive

hot module replacement

Jauco Noordzij edited this pageJul 6, 2016 ·14 revisions

"Hot Module Replacement" (HMR) is a feature to inject updated modules into the active runtime.

It's like LiveReload for every module.

HMR is "opt-in", so you need to put some code at chosen points of your application. The dependencies are handled by the module system.

I. e. you place your hot replacement code in module A. Module A requires module B and B requires C. If module C is updated, and module B cannot handle the update, modules B and C become outdated. Module A can handle the update and new modules B and C are injected.

Examples

Example 1: hot replace request handler of http server

varrequestHandler=require("./handler.js");varserver=require("http").createServer();server.on("request",requestHandler);server.listen(8080);// check if HMR is enabledif(module.hot){// accept update of dependencymodule.hot.accept("./handler.js",function(){// replace request handler of serverserver.removeListener("request",requestHandler);requestHandler=require("./handler.js");server.on("request",requestHandler);});}

Example 2: hot replace css

// addStyleTag(css: string) => HTMLStyleElementvaraddStyleTag=require("./addStyleTag");varelement=addStyleTag(".rule { attr: name }");module.exports=null;// check if HMR is enabledif(module.hot){// accept itselfmodule.hot.accept();// removeStyleTag(element: HTMLStyleElement) => voidvarremoveStyleTag=require("./removeStyleTag");// dispose handlermodule.hot.dispose(function(){// revoke the side effectremoveStyleTag(element);});}

Example 3: Hot module replace with require.context

varcontext=require.context("./filesToLoad",false,/\.js$/);//filesToLoad is a directory with .js filesvarmodules={};context.keys().forEach(function(key){varmodule=context(key);modules[key]=module;customReloadLogic(key,module,false);})if(module.hot){module.hot.accept(context.id,function(){//You can't use context here. You _need_ to call require.context again to//get the new version. Otherwise you might get errors about using disposed//modulesvarreloadedContext=require.context("./filesToLoad",false,/\.js$/);//To find out what module was changed you just compare the result of the//require call with the version stored in the modules hash using strict//equality. Equal means it is unchanged.varchangedModules=reloadedContext.keys().map(function(key){return[key,reloadedContext(key)];}).filter(function(reloadedModule){returnmodules[reloadedModule[0]]!==reloadedModule[1];});changedModules.forEach(function(module){modules[module[0]]=module[1];customReloadLogic(module[0],module[1],true);});});}functioncustomReloadLogic(name,module,isReload){console.log("module "+name+(isReload ?" re" :" ")+"loaded");}

(seehttps://github.com/jauco/webpack-hot-module-reload-with-context-example for a full working version)

API

If HMR is enabled for a modulemodule.hot is an object containing these properties:

accept

accept(dependencies:string[],callback:(updatedDependencies)=>void)=>voidaccept(dependency:string,callback:()=>void)=>void

Accept code updates for the specified dependencies. The callback is called when dependencies were replaced.

accept([errHandler])=>void

Accept code updates for this module without notification of parents. This should only be used if the module doesn't export anything. TheerrHandler can be used to handle errors that occur while loading the updated module.

decline

decline(dependencies:string[])=>voiddecline(dependency:string)=>void

Do not accept updates for the specified dependencies. If any dependencies is updated, the code update fails with code"decline".

decline()=>void

Flag the current module as not update-able. If updated the update code would fail with code"decline".

dispose/addDisposeHandler

dispose(callback:(data:object)=>void)=>voidaddDisposeHandler(callback:(data:object)=>void)=>void

Add a one time handler, which is executed when the current module code is replaced. Here you should destroy/remove any persistent resource you have claimed/created. If you want to transfer state to the new module, add it todata object. Thedata will be available atmodule.hot.data on the new module.

removeDisposeHandler

removeDisposeHandler(callback:(data:object)=>void)=>void

Remove a handler.

This can useful to add a temporary dispose handler. You could i. e. replace code while in the middle of a multi-step async function.

Management API

Also on themodule.hot object.

check

check([autoApply],callback:(err:Error,outdatedModules:Module[])=>void

Throws an exceptions ifstatus() is notidle.

Check all currently loaded modules for updates and apply updates if found.

If no update was found, the callback is called withnull.

IfautoApply is truthy the callback will be called with all modules that were disposed.apply() is automatically called withautoApply asoptions parameter.

IfautoApply is not set the callback will be called with all modules that will be disposed onapply().

apply

apply([options],callback:(err:Error,outdatedModules:Module[])=>void

Ifstatus() != "ready" it throws an error.

Continue the update process.

options can be an object containing these options:

  • ignoreUnaccepted: If true the update process continues even if some modules are not accepted (and would bubble to the entry point).

status

status()=>string

Return one ofidle,check,watch,watch-delay,prepare,ready,dispose,apply,abort orfail.

idle

The HMR is waiting for your call thecheck(). When you call it the status will change tocheck.

check

The HMR is checking for updates. If it doesn't find updates it will change back toidle.

If updates were found it will go through the stepsprepare,dispose andapply. Than back toidle.

watch

The HMR is in watch mode and will automatically be notified about changes. After the first change it will change towatch-delay and wait for a specified time to start the update process. Any change will reset the timeout, to accumulate more changes. When the update process is started it will go through the stepsprepare,dispose andapply. Than back towatch orwatch-delay if changes were detected while updating.

prepare

The HMR is prepare stuff for the update. This may means that it's downloading something.

ready

An update is available and prepared. Callapply() to continue.

dispose

The HMR is calling the dispose handlers of modules that will be replaced.

apply

The HMR is calling the accept handlers of the parents of replaced modules, than it requires the self accepted modules.

abort

A update cannot apply, but the system is still in a (old) consistent state.

fail

A update has thrown an exception in the middle of the process, and the system is (maybe) in a inconsistent state. The system should be restarted.

status/addStatusHandler

status(callback:(status:string)=>void)=>voidaddStatusHandler(callback:(status:string)=>void)=>void

Register a callback on status change.

removeStatusHandler

removeStatusHandler(callback:(status:string)=>void)=>void

Remove a registered status change handler.

How to deal with ...

... a module without side effects (the standard case)

Nothing to do in the module. Any parent can accept it.

... a module with side effects

The module needs a dispose handler, then any parent can accept it.

... a module with only side effects and no exports

The module needs a dispose handler and can accept itself. No action is required in the parent.

If the module's code is not in your hand, the parent can accept the module with some custom dispose logic.

... the application entry module

As it doesn't export it can accept itself. A dispose handler can pass the application state on replacement.

... external module with not handleable side effects

In the nearest parent you decline the dependency. This makes your application throw on update. But as it's an external module, an update is very rare.

webpack 👍

Clone this wiki locally


[8]ページ先頭

©2009-2025 Movatter.jp