UNPKG

28.2 kBMarkdownView Raw
1# React Hot Loader
2
3[![Build Status][build-badge]][build] [![version][version-badge]][package]
4[![Code Coverage][coverage-badge]][coverage]
5[![MIT License][license-badge]][license]
6
7[![PRs Welcome][prs-badge]][prs] [![Chat][chat-badge]][chat]
8[![Backers on Open Collective][oc-backer-badge]](#backers)
9[![Sponsors on Open Collective][oc-sponsor-badge]](#sponsors)
10
11[![Watch on GitHub][github-watch-badge]][github-watch]
12[![Star on GitHub][github-star-badge]][github-star]
13
14Tweak React components in real time ⚛️⚡️
15
16Watch
17**[Dan Abramov's talk on Hot Reloading with Time Travel](https://www.youtube.com/watch?v=xsSnOQynTHs).**
18
19## Install
20
21```
22npm install react-hot-loader
23```
24
25> Note: You can safely install react-hot-loader as a regular dependency instead
26> of a dev dependency as it automatically ensures it is not executed in
27> production and the footprint is minimal.
28
29## 🔥 HOT-LABS 🔥
30
31Latest (4.5.0+, beta) version of React-Hot-Loader could be quite 🔥!
32
33> RHL will patch React, replace React-DOM by React-🔥-DOM and work with fiber directly
34
35* (required) [use webpack plugin](https://github.com/gaearon/react-hot-loader#webpack-plugin) to let RHL patch React-DOM for you.
36* (alternative) [use react-🔥-dom](https://github.com/gaearon/react-hot-loader#react--dom) to use already patched React-DOM.
37* (optional) [set configuration](https://github.com/gaearon/react-hot-loader#setconfigconfig) to `ignoreSFC:true` (this will fix `hook`)
38* (optional) [set configuration](https://github.com/gaearon/react-hot-loader#setconfigconfig) to `pureRender:true` (this will remove side effect from Classes)
39
40```js
41import { setConfig } from 'react-hot-loader'
42
43setConfig({
44 ignoreSFC: true, // RHL will be __completely__ disabled for SFC
45 pureRender: true, // RHL will not change render method
46})
47```
48
49## Getting started
50
511. Add `react-hot-loader/babel` to your `.babelrc`:
52
53```js
54// .babelrc
55{
56 "plugins": ["react-hot-loader/babel"]
57}
58```
59
602. Mark your root component as _hot-exported_:
61
62```js
63// App.js
64import { hot } from 'react-hot-loader/root'
65const App = () => <div>Hello World!</div>
66export default hot(App)
67```
68
69There is also old version of `hot`, used prior version 4.5.4. **Please use a new one**,
70as it is much more resilient to js errors you may make during development.
71
72```js
73import { hot } from 'react-hot-loader'
74const App = () => <div>Hello World!</div>
75export default hot(module)(App)
76```
77
783. [Run webpack with Hot Module Replacement](https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr):
79
80```sh
81webpack-dev-server --hot
82```
83
84## Limitations
85
86* (that's the goal) React-Hot-Loader would not change the past, only update the present - no lifecycle event would be called on component update.
87 As a result - all the code changes, you may made among `componentWillUnmount` or `componentDidMount`, would be ignored for
88 already created components.
89* (that's the goal) React-Hot-Loader would not update any object, including component `state`.
90* (1%) React-Hot-Loader could not reply some changes you may made in components `constructors`. As long as
91 components would not be recreated - RHL have to _inject_ new data onto existing components, but there is no way to detect the actual change and the way reply it.
92 React-Hot-Loader knows what class method is, not how you created it. See #1001 for details.
93
94## Recipes
95
96### Migrating from [create-react-app](https://github.com/facebookincubator/create-react-app)
97
981. Run `npm run eject`
992. Install React Hot Loader (`npm install --save-dev react-hot-loader`)
1003. In `config/webpack.config.dev.js`, add `'react-hot-loader/babel'` to Babel
101 loader configuration. The loader should now look like:
102
103```js
104 {
105 test: /\.(js|jsx)$/,
106 include: paths.appSrc,
107 loader: require.resolve('babel-loader'),
108 options: {
109 // This is a feature of `babel-loader` for webpack (not Babel itself).
110 // It enables caching results in ./node_modules/.cache/babel-loader/
111 // directory for faster rebuilds.
112 cacheDirectory: true,
113 plugins: ['react-hot-loader/babel'],
114 },
115 }
116```
117
1184. Mark your App (`src/App.js`) as _hot-exported_:
119
120```js
121// ./containers/App.js
122import React from 'react'
123import { hot } from 'react-hot-loader'
124
125const App = () => <div>Hello World!</div>
126
127export default hot(module)(App)
128```
129
130### Migrating from [create-react-app](https://github.com/facebookincubator/create-react-app) without ejecting
131
132Users [report](https://github.com/gaearon/react-hot-loader/pull/729#issuecomment-354097936), that it is possible to use [react-app-rewire-hot-loader](https://github.com/cdharris/react-app-rewire-hot-loader) to setup React-hot-loader without ejecting.
133
134### TypeScript
135
136As of version 4, React Hot Loader requires you to pass your code through [Babel](http://babeljs.io/) to transform it so that it can be hot-reloaded. This can be a pain point for TypeScript users, who usually do not need to integrate Babel as part of their build process.
137
138Fortunately, it's simpler than it may seem! Babel will happily parse TypeScript syntax and can act as an alternative to the TypeScript compiler, so you can safely replace `ts-loader` or `awesome-typescript-loader` in your Webpack configuration with `babel-loader`. Babel won't typecheck your code, but you can use [`fork-ts-checker-webpack-plugin`](https://github.com/Realytics/fork-ts-checker-webpack-plugin) (and/or invoke `tsc --noEmit`) as part of your build process instead.
139
140A sample configuration:
141
142```js
143{
144 // ...you'll probably need to configure the usual Webpack fields like "mode" and "entry", too.
145 resolve: { extensions: [".ts", ".tsx", ".js", ".jsx"] },
146 module: {
147 rules: [
148 {
149 test: /\.(j|t)sx?$/,
150 exclude: /node_modules/,
151 use: {
152 loader: "babel-loader",
153 options: {
154 cacheDirectory: true,
155 babelrc: false,
156 presets: [
157 [
158 "@babel/preset-env",
159 { targets: { browsers: "last 2 versions" } } // or whatever your project requires
160 ],
161 "@babel/preset-typescript",
162 "@babel/preset-react"
163 ],
164 plugins: [
165 // plugin-proposal-decorators is only needed if you're using experimental decorators in TypeScript
166 ["@babel/plugin-proposal-decorators", { legacy: true }],
167 ["@babel/plugin-proposal-class-properties", { loose: true }],
168 "react-hot-loader/babel"
169 ]
170 }
171 }
172 }
173 ]
174 },
175 plugins: [
176 new ForkTsCheckerWebpackPlugin()
177 ]
178};
179```
180
181For a full example configuration of TypeScript with React Hot Loader and newest beta version of Babel, check [here](https://github.com/gaearon/react-hot-loader/tree/master/examples/typescript).
182
183As an alternative to this approach, it's possible to chain Webpack loaders so that your code passes through Babel and then TypeScript (or TypeScript and then Babel), but this approach is not recommended as it is more complex and may be significantly less performant. Read more [discussion here](https://github.com/gaearon/react-hot-loader/issues/884).
184
185### Parcel
186
187Parcel supports Hot Module Reloading out of the box, just follow step 1 and 2 of [Getting Started](https://github.com/gaearon/react-hot-loader/tree/master#getting-started).
188
189We also have a [full example running Parcel + React Hot Loader](https://github.com/gaearon/react-hot-loader/tree/master/examples/parcel).
190
191### Electron
192
193You need something to mark your modules as hot in order to use React Hot Loader.
194
195One way of doing this with Electron is to simply use webpack like any web-based project might do and the general guide above describes. See also [this example Electron app](https://github.com/s-h-a-d-o-w/rhl-electron-quick-start).
196
197A webpack-less way of doing it to use `electron-compile` (which is also used by [`electron-forge`](https://electronforge.io)) - see [this example](https://github.com/rllola/hmr-example-issue-2). While it requires less configuration, something to keep in mind is that `electron-compile`'s HMR will always reload all modules, regardless of what was actually edited.
198
199### Source Maps
200
201If you use `devtool: 'source-map'` (or its equivalent), source maps will be
202emitted to hide hot reloading code.
203
204Source maps slow down your project. Use `devtool: 'eval'` for best build
205performance.
206
207Hot reloading code is just one line in the beginning and one line at the end of
208each module so you might not need source maps at all.
209
210## Preact
211
212React-hot-loader should work out of the box with `preact-compat`, but, in case of pure preact, you will need
213to configure it:
214
215* create configuration file (setupHotLoader.js)
216
217```js
218import reactHotLoader from 'react-hot-loader'
219import preact from 'preact'
220
221reactHotLoader.preact(preact)
222```
223
224* dont forget to import it
225
226#### Preact limitations
227
228* HOCs and Decorators as not supported yet. For Preact React-Hot-Loader v4 behave as v3.
229
230## React Native
231
232React Native
233**[supports hot reloading natively](https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html)**
234as of version 0.22.
235
236Using React Hot Loader with React Native can cause unexpected issues (see #824) and is not recommended.
237
238## Webpack plugin
239
240We recommend to use `babel` plugin, but there are situations when you are unable to use it, then - try webpack loader (as seen in v3)
241to have at least _something_.
242Remember - it is **not compatible** with class-based components - as long as babel plugin
243would inject a special methods to the every class, to make `class members`(like onClick) hot-updatable,
244while webpack-plugin would leave classes as is, without any _instrumentation_.
245
246```js
247class MyComponent extends React.Component {
248 onClick = () => this.setState() // COULD NOT UPDATE
249 variable = 1 // this is ok
250 render() {} // this is ok
251}
252```
253
254But webpack-loader could help with TypeScript or _spreading_ "cold API" [to all node_modules](https://github.com/gaearon/react-hot-loader#disabling-a-type-change-for-all-node_modules).
255
256> It is safe to enable this loader for all the files. But place it after babel-loader, if babel-loader is present.
257
258```js
259// webpack.config.js
260module.exports = {
261 module: {
262 rules: [
263 {
264 test: /\.jsx?$/,
265 include: /node_modules/,
266 use: ['react-hot-loader/webpack'],
267 },
268 ],
269 },
270}
271```
272
273Webpack plugin will also land a "hot" patch to react-dom, making React-Hot-Loader more compliant to [the principles](https://github.com/gaearon/react-hot-loader/issues/1118).
274
275## React-🔥-Dom
276
277Another way to make RHL more compliant is to use _our_ version of React-Dom - [hot-loader/react-dom](https://github.com/hot-loader/react-dom)
278
279It is the same React-Dom, with the same version, just with our patches already landed inside.
280
281There is 2 ways to install it:
282
283* Use **yarn** name resolution, so `@hot-loader/react-dom` would be installed instead of `react-dom`
284
285```
286yarn add react-dom@npm:@hot-loader/react-dom
287```
288
289* Use webpack **aliases**
290
291```js
292// webpack.conf
293...
294resolve: {
295 alias: {
296 'react-dom': '@hot-loader/react-dom'
297 }
298}
299...
300```
301
302### Code Splitting
303
304If you want to use Code Splitting + React Hot Loader, the simplest solution is to pick one of our compatible library:
305
306* [Loadable Components](https://github.com/smooth-code/loadable-components/)
307* [Imported Component](https://github.com/theKashey/react-imported-component)
308* [React Universal Component](https://github.com/faceyspacey/react-universal-component)
309* [React-Loadable](https://github.com/jamiebuilds/react-loadable)
310
311If you use a non-yet-friendly library, like [react-async-component](github.com/ctrlplusb/react-async-component) you have to mark all your "loaded components" as _hot-exported_:
312
313```js
314// AsyncHello.js
315import { asyncComponent } from 'react-async-component'
316
317// asyncComponent could not `hot-reload` itself.
318const AsyncHello = asyncComponent({
319 resolve: () => import('./Hello'),
320})
321
322export default AsyncHello
323```
324
325```js
326// Hello.js
327import { hot } from 'react-hot-loader'
328
329const Hello = () => 'Hello'
330
331export default hot(module)(Hello) // <-- module will reload itself
332```
333
334### Checking Element `type`s
335
336Because React Hot Loader creates proxied versions of your components, comparing
337reference types of elements won't work:
338
339```js
340const element = <Component />
341console.log(element.type === Component) // false
342```
343
344React Hot Loader exposes a function `areComponentsEqual` to make it possible:
345
346```js
347import { areComponentsEqual } from 'react-hot-loader'
348const element = <Component />
349areComponentsEqual(element.type, Component) // true
350```
351
352Another way - compare "rendered" element type
353
354```js
355const element = <Component />
356console.log(element.type === <Component />.type) // true
357
358// better - precache rendered type
359const element = <Component />
360const ComponentType = <Component />.type
361console.log(element.type === ComponentType) // true
362```
363
364But you might have to provide all required props. See [original issue](https://github.com/gaearon/react-hot-loader/issues/304).
365This is most reliable way to compare components, but it will not work with required props.
366
367Another way - compare Component name.
368
369> Not all components has a name. **In production displayName could not exists.**
370
371```js
372const element = <Component />
373console.log(element.displayName === 'Component') // true
374```
375
376This is something we did not solve yet. Cold API could help keep original types.
377
378### Webpack ExtractTextPlugin
379
380webpack ExtractTextPlugin is not compatible with React Hot Loader. Please disable it in development:
381
382```js
383new ExtractTextPlugin({
384 filename: 'styles/[name].[contenthash].css',
385 disable: NODE_ENV !== 'production',
386})
387```
388
389#### Disabling a type change (❄️)
390
391It is possible to disable React-Hot-Loader for a specific component, especially to
392enable common way to type comparison.
393See #991 for the idea behind ⛄️, and #304 about "type comparison" problem.
394
395```js
396import { cold } from 'react-hot-loader';
397
398cold(SomeComponent) // this component will ignored by React-Hot-Loader
399<SomeComponent />.type === SomeComponent // true
400```
401
402If you will update `cold` component React-Hot-Loader will complain (on error level), and then
403React will cold-replace Component with a internal state lose.
404
405> Reach-Hot-Loader: cold element got updated
406
407##### Disabling a type change for all node_modules
408
409You may _cold_ all components from node_modules. This will not work for HOC(like Redux) or dynamically created Components, but might help in most of situations, when type changes
410are not welcomed, and modules are not expected to change.
411
412```js
413import { setConfig, cold } from 'react-hot-loader'
414setConfig({
415 onComponentRegister: (type, name, file) =>
416 file.indexOf('node_modules') > 0 && cold(type),
417
418 // some components are not visible as top level variables,
419 // thus its not known where they were created
420 onComponentCreate: (type, name) => name.indexOf('styled') > 0 && cold(type),
421})
422```
423
424! To be able to "cold" components from 'node_modules' you have to apply babel to node_modules, while this
425folder is usually excluded.
426You may add one more babel-loader, with only one React-Hot-Loader plugin inside to solve this.
427**Consider using webpack-loader** for this.
428
429##### React-Hooks
430
431* React-Hooks should work out of the box if you are using version 4.6.0 or above (`pureSFC` is enabled by default).
432* Having dom-patch enabled would solve any possible issue (`ignoreSFC` option is enabled)
433
434You can always `cold` component, but any update then would cause a state loss.
435
436* _cold_ components using hooks.
437
438```js
439import { setConfig, cold } from 'react-hot-loader'
440setConfig({
441 onComponentCreate: (type, name) =>
442 (String(type).indexOf('useState') > 0 ||
443 String(type).indexOf('useEffect') > 0) &&
444 cold(type),
445})
446```
447
448## API
449
450### `hot(Component, options)`
451
452Mark a component as hot.
453
454#### Babel plugin
455
456Right now babel plugin has only one option, enabled by default.
457
458* `safetyNet` - will help you properly setup ReactHotLoader.
459
460You may disable it to get more control on the module execution order.
461
462```js
463//.babelrc
464{
465 "plugins": [
466 [
467 "react-hot-loader/babel",
468 {
469 "safetyNet": false
470 }
471 ]
472 ]
473}
474```
475
476#### Important
477
478**!!** Use `hot` only for module `exports`, not for module `imports`. **!!**
479
480```js
481import { hot } from 'react-hot-loader/root'
482
483const App = () => 'Hello World!'
484
485export default hot(App)
486```
487
488Keep in mind - by importing `react-hot-loader/root` you are setting up a boundary for update event propagation.
489
490The higher(in module hierarchy) you have it - the more stuff would be updated on Hot Module Replacement.
491
492To make RHL more reliable and safe, please place `hot` _below_ (ie somewhere in _imported_ modules):
493
494* react-dom
495* redux store creation
496* any data, you want to preserve between updates
497* big libraries
498
499You may(but it's not required) place `hot` to the every route/page/feature/lazy chunk, thus make updates more scoped.
500
501You don't need to wrap every component with `hot`, application work work fine with a single one.
502
503### (old)`hot(module, options)(Component, options)`
504
505Mark a component as hot. The "new" hot is just hidding the first part - `hot(module)`, giving you
506only the second `(App)`. The "new" hot is using old API.
507
508```js
509import { hot } from 'react-hot-loader'
510
511const App = () => 'Hello World!'
512
513export default hot(module)(App)
514```
515
516### `AppContainer`
517
518Mark application as hot reloadable. (**Prefer** using `hot` helper)
519
520This low-level approach lets you make **hot **imports\_\_, not exports.
521
522```js
523import React from 'react'
524import ReactDOM from 'react-dom'
525import { AppContainer } from 'react-hot-loader'
526import App from './containers/App'
527
528const render = Component => {
529 ReactDOM.render(
530 <AppContainer>
531 <Component />
532 </AppContainer>,
533 document.getElementById('root'),
534 )
535}
536
537render(App)
538
539// webpack Hot Module Replacement API
540if (module.hot) {
541 // keep in mind - here you are configuring HMR to accept CHILDREN MODULE
542 // while `hot` would configure HMR for the CURRENT module
543 module.hot.accept('./containers/App', () => {
544 // if you are using harmony modules ({modules:false})
545 render(App)
546 // in all other cases - re-require App manually
547 render(require('./containers/App'))
548 })
549}
550```
551
552### areComponentsEqual(Component1, Component2)
553
554Test if two components have the same type.
555
556```js
557import { areComponentsEqual } from 'react-hot-loader'
558import Component1 from './Component1'
559import Component2 from './Component2'
560
561areComponentsEqual(Component1, Component2) // true or false
562```
563
564### setConfig(config)
565
566Set a new configuration for React Hot Loader.
567
568Available options are:
569
570* `logLevel`: specify log level, default to `"error"`, available values are: `['debug', 'log', 'warn', 'error']`
571* `pureSFC`: enable Stateless Functional Component. If disabled they will be converted to React Components.
572 Default value: false.
573* `ignoreSFC`: skip "patch" for SFC. "Hot loading" could still work, wit webpack-patch present
574* `pureRender`: do not amend `render` method of any component.
575* for the rest see [react-hot-loader.d.ts](https://github.com/gaearon/react-hot-loader/blob/master/react-hot-loader.d.ts#L57).
576
577```js
578// rhlConfig.js
579import { setConfig } from 'react-hot-loader'
580
581setConfig({ logLevel: 'debug' })
582```
583
584**It is important** to set configuration before any other action will take a place
585
586```js
587// index.js
588import './rhlConfig' // <-- extract configuration to a separate file, and import it in the beggining
589import React from 'react'
590....
591```
592
593## Migrating from v3
594
595### AppContainer vs hot
596
597Prior v4 the right way to setup React Hot Loader was to wrap your Application
598with `AppContainer`, set setup module acceptance by yourself. This approach is
599still valid but only for advanced use cases, prefer using `hot` helper.
600
601**React Hot Loader v3:**
602
603```js
604// App.js
605import React from 'react'
606
607const App = () => <div>Hello world!</div>
608
609export default App
610```
611
612```js
613// main.js
614import React from 'react'
615import ReactDOM from 'react-dom'
616import { AppContainer } from 'react-hot-loader'
617import App from './containers/App'
618
619const render = Component => {
620 ReactDOM.render(
621 <AppContainer>
622 <Component />
623 </AppContainer>,
624 document.getElementById('root'),
625 )
626}
627
628render(App)
629
630// webpack Hot Module Replacement API
631if (module.hot) {
632 module.hot.accept('./containers/App', () => {
633 // if you are using harmony modules ({modules:false})
634 render(App)
635 // in all other cases - re-require App manually
636 render(require('./containers/App'))
637 })
638}
639```
640
641**React Hot Loader v4:**
642
643```js
644// App.js
645import React from 'react'
646import { hot } from 'react-hot-loader'
647
648const App = () => <div>Hello world!</div>
649
650export default hot(module)(App)
651```
652
653```js
654// main.js
655import React from 'react'
656import ReactDOM from 'react-dom'
657import App from './containers/App'
658
659ReactDOM.render(<App />, document.getElementById('root'))
660```
661
662### No patch required
663
664Code is automatically patched, you can safely remove `react-hot-loader/patch`
665from your webpack config.
666
667### Error Boundary is inside every component
668
669> Since 4.5.4
670
671On Hot Module Update we will inject `componentDidCatch` and a _special_ `render`
672to every Class-based component you have, making [Error Boundaries](https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries) more local.
673
674After update we will remove all sugar, keeping only Boundaries you've created.
675
676You can provide your own `errorReporter`, via `setConfig({errorReporter})` or opt-out from
677root ErrorBoundaries setting `errorBoundary={false}` prop on `AppContainer` or `hot`.
678However - this option affects only SFC behavior, and any ClassComponent would boundary itself.
679
680```js
681import { setConfig } from 'react-hot-loader'
682import ErrorBoundary from './ErrorBoundary'
683
684// ErrorBoundary will be given error and errorInfo prop.
685setConfig({ errorReporter: ErrorBoundary })
686```
687
688If `errorReporter` is not set - full screen error overlay would be shown.
689
690#### Setting global Error Reporter
691
692Global Error Reporter would, created a fixed overlay on top the page,
693would be used to display errors, not handled by `errorReporter`, and
694any HMR error.
695
696You may change, or disable this global error overlay
697
698```js
699// to disable
700setConfig({ ErrorOverlay: () => null })
701
702// to change
703setConfig({ ErrorOverlay: MyErrorOverlay })
704```
705
706The UX of existing overlay is a subject to change, and we are open to any proposals.
707
708## Known limitations and side effects
709
710### Note about `hot`
711
712`hot` accepts only React Component (Stateful or Stateless), resulting the `HotExported` variant of it.
713The `hot` function will setup current module to _self-accept_ itself on reload, and will **ignore** all the changes, made for non-React components.
714You may mark as many modules as you want. But `HotExportedComponent` **should be the only used export** of a _hot_-module.
715
716> Note: Please note how often we have used `exported` keyword. `hot` is for exports.
717
718> Note: Does nothing in production mode, just passes App through.
719
720### New Components keep executing the old code
721
722There is no way to hot-update constructor code, as result even new components
723will be born as the first ones, and then grow into the last ones. As of today, this issue cannot be solved.
724
725## Troubleshooting
726
727If it doesn't work, in 99% of cases it's a configuration issue. A missing option, a
728wrong path or port. webpack is very strict about configuration, and the best way
729to find out what's wrong is to compare your project to an already working setup,
730check out
731**[examples](https://github.com/gaearon/react-hot-loader/tree/master/examples)**,
732bit by bit.
733
734If something doesn't work, in 99% of cases it's an issue with your code. The Component
735didn't get registered, due to HOC or Decorator around it, which is making it
736invisible to the Babel plugin or webpack loader.
737
738We're also gathering
739**[Troubleshooting Recipes](https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md)**
740so send a PR if you have a lesson to share!
741
742### Switch into debug mode
743
744Debug mode adds additional warnings and can tells you why React Hot Loader is
745not working properly in your application.
746
747```js
748import { setConfig } from 'react-hot-loader'
749setConfig({ logLevel: 'debug' })
750```
751
752## Contributors
753
754This project exists thanks to all the people who contribute. [Contribute](CONTRIBUTING.md).
755[![contributors][oc-contributors-img]](https://github.com/gaearon/react-hot-loader/graphs/contributors)
756
757## Backers
758
759Thank you to all our backers! 🙏 [Become a backer][oc-backer-link]
760[![backers][oc-backer-img]][oc-backer-link]
761
762## Sponsors
763
764Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor][oc-sponsor-link]
765
766<a href="https://opencollective.com/react-hot-loader/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/0/avatar.svg"></a>
767<a href="https://opencollective.com/react-hot-loader/sponsor/1/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/1/avatar.svg"></a>
768<a href="https://opencollective.com/react-hot-loader/sponsor/2/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/2/avatar.svg"></a>
769<a href="https://opencollective.com/react-hot-loader/sponsor/3/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/3/avatar.svg"></a>
770<a href="https://opencollective.com/react-hot-loader/sponsor/4/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/4/avatar.svg"></a>
771<a href="https://opencollective.com/react-hot-loader/sponsor/5/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/5/avatar.svg"></a>
772<a href="https://opencollective.com/react-hot-loader/sponsor/6/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/6/avatar.svg"></a>
773<a href="https://opencollective.com/react-hot-loader/sponsor/7/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/7/avatar.svg"></a>
774<a href="https://opencollective.com/react-hot-loader/sponsor/8/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/8/avatar.svg"></a>
775<a href="https://opencollective.com/react-hot-loader/sponsor/9/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/9/avatar.svg"></a>
776
777## License
778
779MIT
780
781[build-badge]: https://img.shields.io/travis/gaearon/react-hot-loader.svg?style=flat-square
782[build]: https://travis-ci.org/gaearon/react-hot-loader
783[coverage-badge]: https://img.shields.io/codecov/c/github/gaearon/react-hot-loader.svg?style=flat-square
784[coverage]: https://codecov.io/github/gaearon/react-hot-loader
785[version-badge]: https://img.shields.io/npm/v/react-hot-loader.svg?style=flat-square
786[package]: https://www.npmjs.com/package/react-hot-loader
787[license-badge]: https://img.shields.io/npm/l/react-hot-loader.svg?style=flat-square
788[license]: https://github.com/gaearon/react-hot-loader/blob/next/LICENSE
789[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
790[prs]: http://makeapullrequest.com
791[chat]: https://gitter.im/gaearon/react-hot-loader
792[chat-badge]: https://img.shields.io/gitter/room/gaearon/react-hot-loader.svg?style=flat-square
793[github-watch-badge]: https://img.shields.io/github/watchers/gaearon/react-hot-loader.svg?style=social
794[github-watch]: https://github.com/gaearon/react-hot-loader/watchers
795[github-star-badge]: https://img.shields.io/github/stars/gaearon/react-hot-loader.svg?style=social
796[github-star]: https://github.com/gaearon/react-hot-loader/stargazers
797[oc-backer-badge]: https://opencollective.com/react-hot-loader/backers/badge.svg
798[oc-sponsor-badge]: https://opencollective.com/react-hot-loader/sponsors/badge.svg
799[oc-contributors-img]: https://opencollective.com/react-hot-loader/contributors.svg?width=890&button=false
800[oc-backer-img]: https://opencollective.com/react-hot-loader/backers.svg?width=890
801[oc-backer-link]: https://opencollective.com/react-hot-loader#backers
802[oc-sponsor-link]: https://opencollective.com/react-hot-loader#sponsor