-
-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Dev Server >> Plugins >> Hot Module Replacement | ||
|
||
Plugin for introducing HMR (hot module replacement) support. | ||
|
||
Modules can be written to consume the provided HMR API at development | ||
time, allowing for them to update without reloading the page. | ||
|
||
## Installation | ||
|
||
Install the package: | ||
|
||
``` | ||
npm i --save-dev @web/dev-server-hmr | ||
``` | ||
|
||
Add the plugin to your `web-dev-server-config.mjs` or `web-test-runner.config.js`: | ||
|
||
```ts | ||
import { hmrPlugin } from '@web/dev-server-hmr'; | ||
|
||
export default { | ||
plugins: [hmrPlugin()], | ||
}; | ||
``` | ||
|
||
## Basic usage | ||
|
||
When the plugin is loaded, any HMR-compatible module will have the HMR API | ||
made available to it via `import.meta.hot`. | ||
|
||
By default, it will effectively do nothing until you have written code | ||
which consumes this API. | ||
|
||
For example, take the following module: | ||
|
||
```ts | ||
/** Adds two numbers */ | ||
export let add = (a, b) => { | ||
return a + b; | ||
}; | ||
``` | ||
|
||
In its current state, it will _not_ be HMR-compatible as it does not reference | ||
the HMR API. This means if our `add` module changes, the HMR plugin will | ||
trigger a full page reload. | ||
|
||
To make it compatible, we must use the HMR API via `import.meta.hot`: | ||
|
||
```ts | ||
/** Adds two numbers */ | ||
export let add = (a, b) => { | ||
return a + b; | ||
}; | ||
|
||
if (import.meta.hot) { | ||
import.meta.hot.accept(({ module }) => { | ||
add = module.add; | ||
}); | ||
} | ||
``` | ||
|
||
The plugin will detect that your module uses the HMR API and will make the | ||
`import.meta.hot` object available. | ||
|
||
Do note that in our example we wrapped this in an `if` statement. The reason | ||
for this is to account for if the plugin has not been loaded. | ||
|
||
## Note about production | ||
|
||
In production it is highly recommended you remove any of these HMR related | ||
blocks of code as they will effectively be dead code. | ||
|
||
## API | ||
|
||
### `import.meta.hot.accept()` | ||
|
||
Calling `accept` without a callback will notify the plugin that your module | ||
accepts updates, but will not deal with the updates. | ||
|
||
This is only really useful if your module is one which has side-effects | ||
and does not need mutating on update (i.e. has no exports). | ||
|
||
### `import.meta.hot.accept(({ module }) => { ... })` | ||
|
||
If you pass a callback to `accept`, it will be passed the updated module | ||
any time an update occurs. | ||
|
||
At this point, you should usually update any exports to be those on the | ||
new module. | ||
|
||
### `import.meta.hot.accept(['./dep1.js', './dep2.js'], ({ deps, module }) => { ... }` | ||
|
||
If you specify a list of dependencies as well as a callback, your callback | ||
will be provided with the up-to-date version of each of those modules. | ||
|
||
This can be useful if your updates require access to dependencies of the | ||
current module. | ||
|
||
### `import.meta.hot.invalidate()` | ||
|
||
Immediately invalidates the current module which will then lead to reloading | ||
the page. | ||
|
||
### `import.meta.hot.decline()` | ||
|
||
Notifies the server that you do not support updates, meaning any updates | ||
will result in a full page reload. | ||
|
||
### `import.meta.dispose(() => { ... })` | ||
|
||
Specifies a callback to be called when the current module is disposed of, | ||
before the new module is loaded and passed to `accept()`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters