Solid Refresh
npm i -D solid-refresh
yarn add -D solid-refresh
pnpm add -D solid-refresh
This project aims to provide HMR for Solid for various bundlers. It comes with a babel plugin and a runtime. Over time I hope to add different bundlers. Today it supports:
- Vite (with option
bundler: "vite"
) - Snowpack (with option
bundler: "esm"
) - Webpack (for strict ESM, use option
bundler: "webpack5"
) - Nollup
Setup
Vite
solid-refresh
is already built into vite-plugin-solid
.
Webpack & Rspack
You can read the following guides first, respectively:
Note
Rspack has HMR already enabled by default. The guide only tells you how to disable it or run the dev server on a proxy server.
Requires the use of babel-loader
. Add the following to .babelrc
:
{
"env": {
"development": {
"plugins": ["solid-refresh/babel"]
}
}
}
If you're using strict ESM a.k.a. import.meta.webpackHot
:
{
"env": {
"development": {
"plugins": [["solid-refresh/babel", {
"bundler": "webpack5"
}]]
}
}
}
In your webpack config, be sure to have the following options:
devServer: {
liveReload: false,
hot: true,
}
Nollup
Requires the use of @rollup/plugin-babel
. Add the following to .babelrc
:
{
"env": {
"development": {
"plugins": ["solid-refresh/babel"]
}
}
}
Snowpack
Requires the use of @snowpack/plugin-babel
. Add the following to .babelrc
:
{
"env": {
"development": {
"plugins": ["solid-refresh/babel", { "bundler": "esm" }]
}
}
}
Other dev servers
Parcel
- ParcelJS doesn't support conditional exports yet, which makes ParcelJS load the production build of SolidJS instead of its development build. Solid Refresh requires the SolidJS development build to work.
wmr
- SolidJS is yet to be supported or isn't clear yet. It will use the same config as Snowpack.
rollup-plugin-hot
- The library uses almost an ESM HMR-like API however it behaves the same way as Parcel. Supporting this library is still unclear.
@web/dev-server
- The library supports HMR through their HMR Plugin. The HMR interface is basically the same as Snowpack's.
Development Environment
In any case, your build system needs to support conditional exports and have the development
condition set.
Warning
In some standard HMR implementations, this may cause your app to reload the full page if the development environment isn't properly set!
How it works
The babel plugin will transform components with matching Pascal-cased names (indicating that they are components). This detection is supported in variable declarations, function declarations and named exports:
function Foo() {
return <h1>Hello Foo</h1>;
}
const Bar = () => <h1>Hello Bar</h1>;
The components are wrapped and memoized. When the module receives an update, it replaces the old components from the old module with the new components.
Automatic Render Cleanup
The plugin automatically handles cleanups for unhandled render
and hydrate
calls from solid-js/web
.
You can disable this feature entirely through the option "fixRender": false
.
Pragma
On a per file basis, use comments at top of file to opt out(change moves up to parent):
Or force reload:
@refresh granular
By default, components from the old module are replaced with the new ones from the replacement module, which might cause components that hasn't really changed to unmount abruptly.
Adding @refresh granular
comment pragma in the file allows components to opt-in to granular replacement: If the component has changed code-wise, it will be replaced, otherwise, it will be retained, which allows unchanged ancestor components to preserve lifecycles.
Limitations
- Preserving state: The default mode does not allow preserving state through module replacement.
@refresh granular
allows this partially. - No HOC support.