| [9af201e] | 1 | # React Refresh Webpack Plugin
|
|---|
| 2 |
|
|---|
| 3 | [actions]: https://github.com/pmmmwh/react-refresh-webpack-plugin/actions/workflows/ci.yml
|
|---|
| 4 | [actions:badge]: https://img.shields.io/github/actions/workflow/status/pmmmwh/react-refresh-webpack-plugin/ci.yml?branch=main
|
|---|
| 5 | [license:badge]: https://img.shields.io/github/license/pmmmwh/react-refresh-webpack-plugin
|
|---|
| 6 | [npm:latest]: https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/latest
|
|---|
| 7 | [npm:latest:badge]: https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/latest
|
|---|
| 8 | [npm:next]: https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/next
|
|---|
| 9 | [npm:next:badge]: https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/next
|
|---|
| 10 |
|
|---|
| 11 | [![GitHub Actions][actions:badge]][actions]
|
|---|
| 12 | [![License][license:badge]](./LICENSE)
|
|---|
| 13 | [![Latest Version][npm:latest:badge]][npm:latest]
|
|---|
| 14 | [![Next Version][npm:next:badge]][npm:next]
|
|---|
| 15 |
|
|---|
| 16 | An **EXPERIMENTAL** Webpack plugin to enable "Fast Refresh" (also known as _Hot Reloading_) for React components.
|
|---|
| 17 |
|
|---|
| 18 | > This plugin is not 100% stable.
|
|---|
| 19 | > We're hoping to land a v1 release soon - please help us by reporting any issues you've encountered!
|
|---|
| 20 |
|
|---|
| 21 | ## Getting Started
|
|---|
| 22 |
|
|---|
| 23 | ### Prerequisites
|
|---|
| 24 |
|
|---|
| 25 | Ensure that you are using at least the minimum supported versions of this plugin's peer dependencies -
|
|---|
| 26 | older versions unfortunately do not contain code to orchestrate "Fast Refresh",
|
|---|
| 27 | and thus cannot be made compatible.
|
|---|
| 28 |
|
|---|
| 29 | We recommend using the following versions:
|
|---|
| 30 |
|
|---|
| 31 | | Dependency | Version |
|
|---|
| 32 | | --------------- | ---------------------------- |
|
|---|
| 33 | | `react` | `16.13.0`+, `17.x` or `18.x` |
|
|---|
| 34 | | `react-dom` | `16.13.0`+, `17.x` or `18.x` |
|
|---|
| 35 | | `react-refresh` | `0.10.0`+ |
|
|---|
| 36 | | `webpack` | `4.46.0`+ or `5.2.0`+ |
|
|---|
| 37 |
|
|---|
| 38 | <details>
|
|---|
| 39 | <summary>Minimum requirements</summary>
|
|---|
| 40 | <br />
|
|---|
| 41 |
|
|---|
| 42 | | Dependency | Version |
|
|---|
| 43 | | --------------- | -------- |
|
|---|
| 44 | | `react` | `16.9.0` |
|
|---|
| 45 | | `react-dom` | `16.9.0` |
|
|---|
| 46 | | `react-refresh` | `0.10.0` |
|
|---|
| 47 | | `webpack` | `4.43.0` |
|
|---|
| 48 |
|
|---|
| 49 | </details>
|
|---|
| 50 |
|
|---|
| 51 | <details>
|
|---|
| 52 | <summary>Using custom renderers (e.g. <code>react-three-fiber</code>, <code>react-pdf</code>, <code>ink</code>)</summary>
|
|---|
| 53 | <br />
|
|---|
| 54 |
|
|---|
| 55 | To ensure full support of "Fast Refresh" with components rendered by custom renderers,
|
|---|
| 56 | you should ensure the renderer you're using depends on a recent version of `react-reconciler`.
|
|---|
| 57 |
|
|---|
| 58 | We recommend version `0.25.0` or above, but any versions above `0.22.0` should work.
|
|---|
| 59 |
|
|---|
| 60 | If the renderer is not compatible, please file them an issue instead.
|
|---|
| 61 |
|
|---|
| 62 | </details>
|
|---|
| 63 |
|
|---|
| 64 | ### Installation
|
|---|
| 65 |
|
|---|
| 66 | With all prerequisites met, you can install this plugin using your package manager of choice:
|
|---|
| 67 |
|
|---|
| 68 | ```sh
|
|---|
| 69 | # if you prefer npm
|
|---|
| 70 | npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
|
|---|
| 71 |
|
|---|
| 72 | # if you prefer yarn
|
|---|
| 73 | yarn add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
|
|---|
| 74 |
|
|---|
| 75 | # if you prefer pnpm
|
|---|
| 76 | pnpm add -D @pmmmwh/react-refresh-webpack-plugin react-refresh
|
|---|
| 77 | ```
|
|---|
| 78 |
|
|---|
| 79 | The `react-refresh` package (from the React team) is a required peer dependency of this plugin.
|
|---|
| 80 | We recommend using version `0.10.0` or above.
|
|---|
| 81 |
|
|---|
| 82 | <details>
|
|---|
| 83 | <summary>Support for TypeScript</summary>
|
|---|
| 84 | <br />
|
|---|
| 85 |
|
|---|
| 86 | TypeScript support is available out-of-the-box for those who use `webpack.config.ts`.
|
|---|
| 87 |
|
|---|
| 88 | Our exported types however depends on `type-fest`, so you'll have to add it as a `devDependency`:
|
|---|
| 89 |
|
|---|
| 90 | ```sh
|
|---|
| 91 | # if you prefer npm
|
|---|
| 92 | npm install -D type-fest
|
|---|
| 93 |
|
|---|
| 94 | # if you prefer yarn
|
|---|
| 95 | yarn add -D type-fest
|
|---|
| 96 |
|
|---|
| 97 | # if you prefer pnpm
|
|---|
| 98 | pnpm add -D type-fest
|
|---|
| 99 | ```
|
|---|
| 100 |
|
|---|
| 101 | > **:memo: Note**:
|
|---|
| 102 | >
|
|---|
| 103 | > `type-fest@4.x` only supports Node.js v16 or above,
|
|---|
| 104 | > `type-fest@3.x` only supports Node.js v14.16 or above,
|
|---|
| 105 | > and `type-fest@2.x` only supports Node.js v12.20 or above.
|
|---|
| 106 | > If you're using an older version of Node.js, please install `type-fest@1.x`.
|
|---|
| 107 |
|
|---|
| 108 | </details>
|
|---|
| 109 |
|
|---|
| 110 | ### Usage
|
|---|
| 111 |
|
|---|
| 112 | For most setups, we recommend integrating with `babel-loader`.
|
|---|
| 113 | It covers the most use cases and is officially supported by the React team.
|
|---|
| 114 |
|
|---|
| 115 | The example below will assume you're using `webpack-dev-server`.
|
|---|
| 116 |
|
|---|
| 117 | If you haven't done so, set up your development Webpack configuration for Hot Module Replacement (HMR).
|
|---|
| 118 |
|
|---|
| 119 | ```js
|
|---|
| 120 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 121 |
|
|---|
| 122 | module.exports = {
|
|---|
| 123 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 124 | devServer: {
|
|---|
| 125 | hot: true,
|
|---|
| 126 | },
|
|---|
| 127 | };
|
|---|
| 128 | ```
|
|---|
| 129 |
|
|---|
| 130 | <details>
|
|---|
| 131 | <summary>Using <code>webpack-hot-middleware</code></summary>
|
|---|
| 132 | <br />
|
|---|
| 133 |
|
|---|
| 134 | ```js
|
|---|
| 135 | const webpack = require('webpack');
|
|---|
| 136 |
|
|---|
| 137 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 138 |
|
|---|
| 139 | module.exports = {
|
|---|
| 140 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 141 | plugins: [isDevelopment && new webpack.HotModuleReplacementPlugin()].filter(Boolean),
|
|---|
| 142 | };
|
|---|
| 143 | ```
|
|---|
| 144 |
|
|---|
| 145 | </details>
|
|---|
| 146 |
|
|---|
| 147 | <details>
|
|---|
| 148 | <summary>Using <code>webpack-plugin-serve</code></summary>
|
|---|
| 149 | <br />
|
|---|
| 150 |
|
|---|
| 151 | ```js
|
|---|
| 152 | const { WebpackPluginServe } = require('webpack-plugin-serve');
|
|---|
| 153 |
|
|---|
| 154 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 155 |
|
|---|
| 156 | module.exports = {
|
|---|
| 157 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 158 | plugins: [isDevelopment && new WebpackPluginServe()].filter(Boolean),
|
|---|
| 159 | };
|
|---|
| 160 | ```
|
|---|
| 161 |
|
|---|
| 162 | </details>
|
|---|
| 163 |
|
|---|
| 164 | Then, add the `react-refresh/babel` plugin to your Babel configuration and this plugin to your Webpack configuration.
|
|---|
| 165 |
|
|---|
| 166 | ```js
|
|---|
| 167 | const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
|---|
| 168 |
|
|---|
| 169 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 170 |
|
|---|
| 171 | module.exports = {
|
|---|
| 172 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 173 | module: {
|
|---|
| 174 | rules: [
|
|---|
| 175 | {
|
|---|
| 176 | test: /\.[jt]sx?$/,
|
|---|
| 177 | exclude: /node_modules/,
|
|---|
| 178 | use: [
|
|---|
| 179 | {
|
|---|
| 180 | loader: require.resolve('babel-loader'),
|
|---|
| 181 | options: {
|
|---|
| 182 | plugins: [isDevelopment && require.resolve('react-refresh/babel')].filter(Boolean),
|
|---|
| 183 | },
|
|---|
| 184 | },
|
|---|
| 185 | ],
|
|---|
| 186 | },
|
|---|
| 187 | ],
|
|---|
| 188 | },
|
|---|
| 189 | plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
|
|---|
| 190 | };
|
|---|
| 191 | ```
|
|---|
| 192 |
|
|---|
| 193 | > **:memo: Note**:
|
|---|
| 194 | >
|
|---|
| 195 | > Ensure both the Babel transform (`react-refresh/babel`) and this plugin are enabled only in `development` mode!
|
|---|
| 196 |
|
|---|
| 197 | <details>
|
|---|
| 198 | <summary>Using <code>ts-loader</code></summary>
|
|---|
| 199 | <br />
|
|---|
| 200 |
|
|---|
| 201 | > **:warning: Warning**:
|
|---|
| 202 | > This is an un-official integration maintained by the community.
|
|---|
| 203 |
|
|---|
| 204 | Install [`react-refresh-typescript`](https://github.com/Jack-Works/react-refresh-transformer/tree/main/typescript).
|
|---|
| 205 | Ensure your TypeScript version is at least 4.0.
|
|---|
| 206 |
|
|---|
| 207 | ```sh
|
|---|
| 208 | # if you prefer npm
|
|---|
| 209 | npm install -D react-refresh-typescript
|
|---|
| 210 |
|
|---|
| 211 | # if you prefer yarn
|
|---|
| 212 | yarn add -D react-refresh-typescript
|
|---|
| 213 |
|
|---|
| 214 | # if you prefer pnpm
|
|---|
| 215 | pnpm add -D react-refresh-typescript
|
|---|
| 216 | ```
|
|---|
| 217 |
|
|---|
| 218 | Then, instead of wiring up `react-refresh/babel` via `babel-loader`,
|
|---|
| 219 | you can wire-up `react-refresh-typescript` with `ts-loader`:
|
|---|
| 220 |
|
|---|
| 221 | ```js
|
|---|
| 222 | const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
|---|
| 223 | const ReactRefreshTypeScript = require('react-refresh-typescript');
|
|---|
| 224 |
|
|---|
| 225 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 226 |
|
|---|
| 227 | module.exports = {
|
|---|
| 228 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 229 | module: {
|
|---|
| 230 | rules: [
|
|---|
| 231 | {
|
|---|
| 232 | test: /\.[jt]sx?$/,
|
|---|
| 233 | exclude: /node_modules/,
|
|---|
| 234 | use: [
|
|---|
| 235 | {
|
|---|
| 236 | loader: require.resolve('ts-loader'),
|
|---|
| 237 | options: {
|
|---|
| 238 | getCustomTransformers: () => ({
|
|---|
| 239 | before: [isDevelopment && ReactRefreshTypeScript()].filter(Boolean),
|
|---|
| 240 | }),
|
|---|
| 241 | transpileOnly: isDevelopment,
|
|---|
| 242 | },
|
|---|
| 243 | },
|
|---|
| 244 | ],
|
|---|
| 245 | },
|
|---|
| 246 | ],
|
|---|
| 247 | },
|
|---|
| 248 | plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
|
|---|
| 249 | };
|
|---|
| 250 | ```
|
|---|
| 251 |
|
|---|
| 252 | > It is recommended to run `ts-loader` with `transpileOnly` is set to `true`.
|
|---|
| 253 | > You can use `ForkTsCheckerWebpackPlugin` as an alternative if you need typechecking during development.
|
|---|
| 254 |
|
|---|
| 255 | </details>
|
|---|
| 256 |
|
|---|
| 257 | <details>
|
|---|
| 258 | <summary>Using <code>swc-loader</code></summary>
|
|---|
| 259 | <br />
|
|---|
| 260 |
|
|---|
| 261 | > **:warning: Warning**:
|
|---|
| 262 | > This is an un-official integration maintained by the community.
|
|---|
| 263 |
|
|---|
| 264 | Ensure your `@swc/core` version is at least `1.2.86`.
|
|---|
| 265 | It is also recommended to use `swc-loader` version `0.1.13` or above.
|
|---|
| 266 |
|
|---|
| 267 | Then, instead of wiring up `react-refresh/babel` via `babel-loader`,
|
|---|
| 268 | you can wire-up `swc-loader` and use the `refresh` transform:
|
|---|
| 269 |
|
|---|
| 270 | ```js
|
|---|
| 271 | const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
|---|
| 272 |
|
|---|
| 273 | const isDevelopment = process.env.NODE_ENV !== 'production';
|
|---|
| 274 |
|
|---|
| 275 | module.exports = {
|
|---|
| 276 | mode: isDevelopment ? 'development' : 'production',
|
|---|
| 277 | module: {
|
|---|
| 278 | rules: [
|
|---|
| 279 | {
|
|---|
| 280 | test: /\.[jt]sx?$/,
|
|---|
| 281 | exclude: /node_modules/,
|
|---|
| 282 | use: [
|
|---|
| 283 | {
|
|---|
| 284 | loader: require.resolve('swc-loader'),
|
|---|
| 285 | options: {
|
|---|
| 286 | jsc: {
|
|---|
| 287 | transform: {
|
|---|
| 288 | react: {
|
|---|
| 289 | development: isDevelopment,
|
|---|
| 290 | refresh: isDevelopment,
|
|---|
| 291 | },
|
|---|
| 292 | },
|
|---|
| 293 | },
|
|---|
| 294 | },
|
|---|
| 295 | },
|
|---|
| 296 | ],
|
|---|
| 297 | },
|
|---|
| 298 | ],
|
|---|
| 299 | },
|
|---|
| 300 | plugins: [isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
|
|---|
| 301 | };
|
|---|
| 302 | ```
|
|---|
| 303 |
|
|---|
| 304 | > Starting from version `0.1.13`, `swc-loader` will set the `development` option based on Webpack's `mode` option.
|
|---|
| 305 | > `swc` won't enable fast refresh when `development` is `false`.
|
|---|
| 306 |
|
|---|
| 307 | </details>
|
|---|
| 308 |
|
|---|
| 309 | For more information on how to set up "Fast Refresh" with different integrations,
|
|---|
| 310 | please check out [our examples](examples).
|
|---|
| 311 |
|
|---|
| 312 | ### Overlay Integration
|
|---|
| 313 |
|
|---|
| 314 | This plugin integrates with the most common Webpack HMR solutions to surface errors during development -
|
|---|
| 315 | in the form of an error overlay.
|
|---|
| 316 |
|
|---|
| 317 | By default, `webpack-dev-server` is used,
|
|---|
| 318 | but you can set the [`overlay.sockIntegration`](docs/API.md#sockintegration) option to match what you're using.
|
|---|
| 319 |
|
|---|
| 320 | The supported versions are as follows:
|
|---|
| 321 |
|
|---|
| 322 | | Dependency | Version |
|
|---|
| 323 | | ------------------------ | -------------------------- |
|
|---|
| 324 | | `webpack-dev-server` | `3.6.0`+ or `4.x` or `5.x` |
|
|---|
| 325 | | `webpack-hot-middleware` | `2.x` |
|
|---|
| 326 | | `webpack-plugin-serve` | `0.x` or `1.x` |
|
|---|
| 327 |
|
|---|
| 328 | ## API
|
|---|
| 329 |
|
|---|
| 330 | Please refer to [the API docs](docs/API.md) for all available options.
|
|---|
| 331 |
|
|---|
| 332 | ## FAQs and Troubleshooting
|
|---|
| 333 |
|
|---|
| 334 | Please refer to [the Troubleshooting guide](docs/TROUBLESHOOTING.md) for FAQs and resolutions to common issues.
|
|---|
| 335 |
|
|---|
| 336 | ## License
|
|---|
| 337 |
|
|---|
| 338 | This project is licensed under the terms of the [MIT License](/LICENSE).
|
|---|
| 339 |
|
|---|
| 340 | ## Special Thanks
|
|---|
| 341 |
|
|---|
| 342 | <a href="https://jb.gg/OpenSource?from=ReactRefreshWebpackPlugin" target="_blank">
|
|---|
| 343 | <img
|
|---|
| 344 | alt="JetBrains Logo"
|
|---|
| 345 | src="https://user-images.githubusercontent.com/9338255/132110580-61d3dba5-f5c7-4479-bd8e-39cd65b42fc5.png"
|
|---|
| 346 | width="120"
|
|---|
| 347 | />
|
|---|
| 348 | </a>
|
|---|