React Hot Loader 3.0 beta demo

A Big Update Is Coming
React Hot Loader 3 is on the horizon, and you can try it today. It fixes some long-standing issues with both React Hot Loader and React Transform, and is intended as a replacement for both.
Some nice things about it:

Editing functional components preserves state
Works great with higher order components
Little configuration
Disabled in production
Works with or without Babel (you can remove react-hot-loader/babel from .babelrc and instead add react-hot-loader/webpack to loaders)

The docs are not there yet, but they will be added before the final release.
For now, this commit is a good reference to upgrading your project from React Hot Loader 1 to React Hot Loader 3 alpha. Then see another commit as a reference for upgrading from React Hot Loader 3 alpha to React Hot Loader 3 beta.

With lessons learned both from RHL and RT, here is a demo of a unified approach.
This is really undocumented for now, and we might change API later, so feel free to play with it at your own risk. 😉
react-hot-loader/webpack is intended to be optional. We will provide a complementary react-hot-loader/babel that detects unexported components as well. You will be able to use either, depending on whether you already use Babel or not.

Known Issues

Server rendering AppContainer crashes (https://github.com/gaearon/react-hot-loader/issues/283). Until fixed, a workaround is to render the app directly on the server instead.
Error reporting only works for initial mount, but this should be fixed when facebook/react#6020 lands.
RedboxReact sometimes fails to display an error message due to https://github.com/stacktracejs/stackframe/issues/11.
Hot reloading doesn’t currently work with React.createFactory or React.DOM.* factories. It works either with JSX or with React.createElement. (https://github.com/gaearon/react-hot-loader/issues/277)

This looks great! Without the babel part of the loader, this won't yet work for HOC-wrapped components (because the original isn't exported), right?

Without the babel part of the loader, this won't yet work for HOC-wrapped components (because the original isn't exported), right?

Correct.

React.createElement will be patched before any user code is ran, preventing issues with code like this https://github.com/reactjs/react-router/blob/master/modules/RouterContext.js#L29?

Just to get this straight, react-hot-loader was superseded by react-transform-hmr right? Do you want to go back to react-hot-loader as favorite once v3.0.0 is done?

React.createElement will be patched before any user code is ran, preventing issues with code like this https://github.com/reactjs/react-router/blob/master/modules/RouterContext.js#L29?

Yes (presuming the configuration is correct). In this example I just put react-hot-loader/patch in entry as the first item.

Just to get this straight, react-hot-loader was superseded by react-transform-hmr right? Do you want to go back to react-hot-loader as favorite once v3.0.0 is done?

The existing implementations of both React Transform / React Hot Loader are going away. The new implementation will be branded as React Hot Loader 3, but will internally use a combination of their approaches. It will also not be webpack-specific. “Loader” originally meant a Webpack transform but since it’s a project for “hot reloading” I think it’s fine that we expand the scope, and react-hot-loader will contain opt-in react-hot-loader/webpack, react-hot-loader/babel, and potentially other integrations.

Here is an example repo with jspm/SystemJS used in place of webpack: https://github.com/tyscorp/react-hot-boilerplate/tree/jspm
The proxying stuff does not currently work as no exports have __source attached.
It seems like react-hot-loader/babel would work fine with jspm/SystemJS for those using plugin-babel.
I did experiment with creating react-hot-loader/systemjs by patching SystemJS' _export function with mixed results. I did manage to get ES6 class-based components to successfully hot reload while maintaining state. It looks like the "instantiate" hook (as opposed to "translate") might be more suited for this task but I was unable to write a plugin that even worked using it. Perhaps @guybedford could weigh in on the most appropriate way to write such a plugin?

I added Babel plugin in case you’d like to try it.

I'm getting a _len is not defined. As described here Any idea where that might come from?

@0x80 Seems like a Babel bug (https://phabricator.babeljs.io/T7298). I just pushed a workaround in 3.0.0-alpha.9, please update.

Are there any special steps to get this to work with react-router? I'm getting Warning: [react-router] You cannot change <Router routes>; it will be ignored when I update a component

Are there any special steps to get this to work with react-router? I'm getting Warning: [react-router] You cannot change ; it will be ignored when I update a component

Eh, you’re right, I can’t get this working. Looks like it’s time for https://github.com/reactjs/react-router/issues/2182 to gain some momentum!

@nfcampos @gaearon A workaround for ReactRouter is to put the code that stores an instance of your router into a leaf module in your dependency tree. Then when the modules are busted by the hmr process the router instance isn't recreated. I did this quite simply by creating a module allowing you to cache arbitrary functions across module replacements.
acrossReload.js
import {once} from 'lodash'

const acrossReloadStore = {}
export const acrossReload = (name, func) => {
    if(! (name in acrossReloadStore)) acrossReloadStore[name] = once(func)
    return acrossReloadStore[name]
}

router.js
export const router = acrossReload("router", () => createElement(Router, {history}, ...routes))()

I know it looks weird having the this as a function, basically just because I didn't extend the acrossReload function to accept values. But this is easily achievable.
Also, this will not replace update the router, so if you add a route or remove one you will need to refresh. However since this doesn't happen often, it's ok.

@alexisvincent
I’m not sure it would be enough for this particular approach though. React Hot Loader specifically relies on createElement being called which I don’t think would happen here.
@nfcampos
I found a really hacky workaround. If you just want to play around with this in your project, add this patch to <Router> component:
Router.prototype.componentWillReceiveProps = function(nextProps) {
  let components = [];
  function grabComponents(element) {
    if (element.props && element.props.component) {
      components.push(element.props.component);
    }
    if (element.props && element.props.children) {
      React.Children.forEach(element.props.children, grabComponents);
    }
  }
  grabComponents(nextProps.routes || nextProps.children);
  components.forEach(React.createElement);
};

This works in my testing. It requires 3.0.0-alpha.11 to work.

@gaearon I don't mean for react hot loader internals, it was meant as a workaround for @nfcampos. Also, this is what I was doing in react-transform. It's possible it will no longer work, but I don't see why not. createElement would be called the first time the router was constructed. But since the router instance doesn't change often. Calling a proxy.update(Comp) on lower components would update things imported by react router. Am I missing something?

@gaearon thanks, i'll try that

@alexisvincent Unlike React Transform, RHL3 doesn’t wrap your components where they are defined, so just re-executing those files won’t do anything. If some files importing them call createElement with their new versions, it’ll be fine, but RR keeps a reference to old versions and won’t createElement the new route components, so the proxies never get a chance to update.

Oh right. I see the issue. How are you planning to tell components to call createElement once they're been replaced?

I get patch.dev.js?f09d:40 Uncaught TypeError: createProxy is not a function
On this line
https://github.com/gaearon/react-hot-loader/pull/240/files#diff-8be7b0cf5cd0de13e69f70bcf3a11143R48
I use webpack-hot-middleware so my webpack entry looking like
  entry: [
    'webpack-hot-middleware/client',
    'react-hot-loader/patch',
    path.join(__dirname, '../client.js'),
  ],

@alexisvincent

Oh right. I see the issue. How are you planning to tell components to call createElement once they're been replaced?

Normally this just happens as part of the render process. Component tree gets forcefully re-rendered by AppContainer, and so any component that is currently rendered will update. Those that aren’t rendered right now, will use the new code the next time they are rendered. So it naturally gets eventually consistent. And for things like static properties, HMR is good enough and most of the code directly interfaces with the real class anyway.
@istarkov

I get patch.dev.js?f09d:40 Uncaught TypeError: createProxy is not a function

Any chance you have an old version of react-proxy? react-hot-loader requires 3.x, maybe something’s wrong in your node_modules. Try removing it and running npm install again?

@gaearon Ok I see, so essentially a forceUpdate might be worth building in here. At least into the client side implementation.

@gaearon Because my expectation would be immediate consistency. This is essentially why I would use HMR

@alexisvincent

Ok I see, so essentially a forceUpdate might be worth building in here.

It’s right there.

Because my expectation would be immediate consistency. This is essentially why I would use HMR

Sorry, I didn’t explain it clear enough. The currently mounted components are updated immediately. The “lazy” nature refers to components that are not currently mounted. Like when you edit a <Button> but there is not a single <Button> on the page. In this case, it will be updated next time it’s rendered, which is indistinguishable from the developer’s point of view from if it was immediately updated. “If a tree falls in a forest...”

Thank you @gaearon
Looks like I forgot to remove hmre from package.json and got two different react-proxy versions.
Even on clean install (rm -rf node_modules && npm install)

@istarkov Cool, let us know how it goes! I need some more real world usage to catch issues before this goes stable so I really appreciate your help.

@gaearon Oh Brilliant :D

@alexisvincent Yeah, it’s pretty crazy. I was convinced this wouldn’t work the first couple of times I considered it (back in October!) But counter-intuitively, it does 😄 .

The big problem as I use react-router-relay - hack above removes router warning, but components does not updated. Any thoughts?
hack above for relay router
let Router = require('react-router/lib/Router');
Router.prototype.componentWillReceiveProps = function (nextProps) {
  // Blabla as above
};
const { RelayRouter } = require('react-router-relay');

Feel free to dig in 😄 . I haven’t checked why this might be the case.

@gaearon really impressed man, this is fantastic work. This approach definitely feels clean, if you know what I mean. As a comment on your medium post. Your style and format of writing is great. Presenting the problem, and then following your thought process. Especially valuable was your explanation of failed attempts. I think we need more of this kind of writing generally in the industry.

@nfcampos I added a hacky but harmless workaround for React Router in 3.0.0-alpha.12 so it should just work now. (The warning is still printed but you can ignore it.)

@gaearon it works now! Thanks! I'll let you know if I run into any other issues.

Anyone has made this work with webpack-hot-middleware? I've just followed the diff to migrate from the hmre implementation but module.hot.accept are never called anymore, worked fined before so the webpack side should be ok, any ideas?

@mgcrea I did, my entry in webpack was
  entry: [
    'webpack-hot-middleware/client',
    'react-hot-loader/patch',
    path.join(__dirname, '../client.js'),
  ],

@gaearon If I understand correctly a similar hacky workaround as you did for react-router is also required for any other library which renders components that don't output elements in a normal fashion?
For example in my code I'm getting an error on MediaQuery from react-responsive.

If I understand correctly a similar hacky workaround as you did for react-router is also required for any other library which renders components that don't output elements in a normal fashion?

We would very much like to avoid that. The problem with React Router is that it doesn’t really handle receiving new props. Most components should handle this well, as it’s part of React component contract.

For example in my code I'm getting an error on MediaQuery from react-responsive.

What kind of error? Can you show a usage example that reproduces it?

If anyone else found some of your components unmounted and mounted again instead of re-rendered in place, here's my hint: You always need to export your Component somewhere. This is because React-Hot-Reload can only hook itself to exported stuff (via webpack). It does not actively search your code for Components.

Yeah. This is what react-hot-loader/babel solves.

I introduced RHL3 to my project with react-router and works perfect excluding one situation. It doesn't update component from IndexRoute. I mean when I update AccountOverview component, I can't see changes without manual reload. Below content of my App.js file.
import React, { Component } from 'react';
import { Router, Route, IndexRoute, IndexRedirect, browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';

import UserPanel from '../pages/user-panel/UserPanel.js';
import AccountOverview from './../pages/user-panel/account-overview/AccountOverview.js';
import EditProfile from './../pages/user-panel/edit-profile/EditProfile.js';
import Login from '../pages/login/Login.js';

const store = createStore(
  combineReducers({
    ui,
    routing: routerReducer,
  })
);
const history = syncHistoryWithStore(browserHistory, store);

const MainApp = ({children}) => (
  <div>
    {children}
  </div>
);

const App = (props) => (
  <Provider store={store}>
    <Router history={history} onUpdate={() => window.scrollTo(0, 0) }>
      <Route path="/" component={MainApp}>
        <Route component={UserPanel}>
          <IndexRoute component={AccountOverview} />
          <Route path="edit-profile" component={EditProfile} />
        </Route>
        <Route path="login" component={Login} />
      </Route>
    </Router>
  </Provider>
);

export default App;

As a work around I replaced this line
<IndexRoute component={AccountOverview} />
with these
<IndexRedirect to="/account-overview" />
<Route path="account-overview" component={AccountOverview} />

it's not exactly the same but enough in my case.

Good point, I forgot React Router has many kinds of routes. Would you like to send a PR against the next branch? https://github.com/gaearon/react-hot-loader/commit/005c32ddbf9929980a315d30691ed6c8f7a8a8b6 should give you an idea of how to do it.

Sure. Done.

@gaearon is it possible to pass props to the app component?
Use case: Do some work before rendering to the dom, work is then used by app:
doSomeWork(...).then((x) => {
  ReactDOM.render(<App x={x} />, rootEl)
})

@danilobuerger
Yes, <AppContainer component={App} props={{ x: x }} />. We’ll be changing this to <AppContainer><App x={x} /></AppContainer> in the next beta, but you can use this for now.

If i initialize a redux store outside of App though, will i still get hot loading of reducers?

@danilobuerger You get it by explicitly handling module.hot.accept for the reducers, like here. So this is unrelated.

I got it working by following the linked commit, but I'm confused on one thing, if I cause a javascript error somewhere, eg. in one of my render() methods, by calling a non-existent function, the hot reloading stops, until I do a full reload (and I am notified of this fact in the console).
I thought one of the additions coming in 3.0 is that hot reloading is able to recover even if there were javascript errors? Is that not implemented yet, or did I misunderstood that feature, or a misconfiguration on my part?

Yes, it is related.

For what it's worth, I ported the counter example app from the redux-devtools repo to use RHL3 in combination with commonly used libraries. See https://github.com/rybon/counter-hmr. This repo uses React 15, Redux, React Router, React Redux, React Router Redux, Immutable, Reselect and CSS in JS inline styles.
HMR works fine. Hope this helps someone.

@gaearon For the react router workaround that you posted.
Router.prototype.componentWillReceiveProps = function(nextProps) {
  let components = [];
  function grabComponents(element) {
    // This only works for JSX routes, adjust accordingly for plain JS config
    if (element.props && element.props.component) {
      components.push(element.props.component);
    }
    if (element.props && element.props.children) {
      React.Children.forEach(element.props.children, grabComponents);
    }
  }
  grabComponents(nextProps.routes || nextProps.children);
  components.forEach(React.createElement); // force patching
};

This doesn't work for me. You mention that it only works for JSX routes? I'm using POJO's. Thoughts?

@alexisvincent, I don't use react-router nor have I followed that thread, but, if your routes are in objects, there's a good chance that what I wrote in https://github.com/gaearon/react-hot-loader/issues/259 might help you.  You'll need an extra hot.modules.accept(..) section as described there in the file where you assemble that object.  But as said I'm not really sure of the specifics of the routing issue, personally.

POJOs with React Router will work after https://github.com/gaearon/react-hot-loader/pull/253 is merged. Still a hack, and should ideally be solved on RR side, but better than nothing.

Is it possible to get this working with react-router's async routes and webpack code splitting using match on the client as described in: react-router/ServerRendering.md
I have tried without success. Any help is appreciated.

@chrisblossom No, this hack only works for sync routes. The only solution to hot reloading with async routes is fixing https://github.com/reactjs/react-router/issues/2182.

Great improvement, I'm finally able to use react hot-reload from Haxe, another compile-to-JS language.
Only limitation that I found: Haxe JS generation doesn't go through a loader, so I'm only using react-hot-loader/webpack to resolve the requires. It all works perfectly excepted source mapping: our JS has a source map but it's lost in the process.

@elsassph Do you mind filing an issue in React Hot Loader? Preferably with a minimal reproducing project.

@chrisblossom No, this hack only works for sync routes. The only solution to hot reloading with async routes is fixing reactjs/react-router#2182.

@gaearon Thanks for the info. I ended up disabling code splitting in development to keep HMR working.

Hi all,
I just tried this out with my setup. I may just be doing something wrong, but I'm getting Warning: Object prototype may only be an Object or null: react-hot-loader/babel. Thoughts?

This thread is irrelevant with RHL tech details, but just some noisy whining.
Really appreciate your effort to make our development flow much more awesome, but I'll be even more grateful if you can point out that<EMAIL_ADDRESS>doesn't work with React Router currently in your OP (even there are lots of pending hacks to be reviewed and merged).
Initially I'm thrilled to know functional components hot reloading is finally supported, and just can't wait to upgrade and refactor a redux project which finished three or four months ago (in which react-router-redux was redux-simple-router).
After hours of effort to upgrade dependency and set up environment, I failed to enable hot reloading in my project, totally. I mean before upgrading, at least the hot reloading is working but just some error thrown when related with functional components. Now, it's totally not working.
I know it's my fault that I haven't read through all these conversations before upgrade and refactor, but in your OP there're too many flowers and fireworks and plus ones, it's really hard to stay cool and be suspicious.
Anyway, hot reloading is still awesome, but I'll definitely waiting for the final release this time.

@jasonslyvia I too got stuck initially with getting this to work with Router Router. Turns out the magic trick is to force the Router to unmount and mount after a hot reload. See https://github.com/rybon/counter-hmr/blob/master/src/components/Root.jsx (the hmrKey bit). The actual HMR implementation is just as Dan described in this TodoMVC commit, see https://github.com/rybon/counter-hmr/blob/master/src/index.jsx.
This repo is a small example, but uses all the major libraries for demonstration purposes. Check out the files in the root folder (package.json, .babelrc, webpack.config.js, server.js). I removed as many dependencies as I could from package.json to demonstrate that one should only need a few devDependencies to get it to work.

@rybon Thank you for your solution but adding key to Router causes all sub-components' local state removed, so I guess that's not ideal.

@jasonslyvia that is why you should not be using local state :). I know it is convenient and tempting, but I found a lot of issues simply go away if you store everything in the Redux store, even state one would consider 'local' for a certain component (such as a toggle boolean to show/hide something), and keep the components stateless.
Same goes for triggering side effects in component lifecycle methods. Again, very convenient and tempting, but keeping those things out of the dispatch -> rerender loop helps with achieving the goal of making the UI a pure and idempotent function of application state ((state) => UI).
This is why functional stateless components are great! They enforce these constraints.

@rybon I guess that's off the topic and if I don't have any local state, I don't even have to use react-hot-loader at all, just webpack's module.hot API is sufficient.

I guess that's off the topic and if I don't have any local state, I don't even have to use react-hot-loader at all, just webpack's module.hot API is sufficient.

This is correct. One of the points of RHL 3 is the process is “progressively enhancing”. You set up HMR first, then if you want to preserve the state, you do a few extra steps, can always go back easily if RHL causes problems.

@rybon
This is not correct. If you put a unique key you might as well not use React Hot Loader at all because vanilla HMR works exactly the same way.
@jasonslyvia
I'm sorry this did not work for you yet. As you said, there are more pending fixes that may fix the problem for you later. Those are still workarounds because the underlying problem is with React Router itself. It doesn't behave the way any other components do: it doesn't accept new props. We hope to fix it on the router side but please understand this takes some effort, and React Hot Loader is a hobby project. If you want an issue to be fixed, it might be a good idea to take some time to look into it yourself and help diagnose it, or at the very least create a minimal project reproducing it so that other people can look at it later.
However it would be much more helpful

Really appreciate your effort to make our development flow much more awesome, but I'll be even more grateful if you can point out that<EMAIL_ADDRESS>doesn't work with React Router currently in your OP

Also I'm afraid this is wrong. It does work. Currently the limitation is that only JSX config with sync routes works. But it's incorrect to say it doesn't work at all.
I will amend the OP post to include this clarification.

in your OP there're too many flowers and fireworks and plus ones, it's really hard to stay cool and be suspicious.

I'm sorry that people are enthusiastic about this alpha version which is how it is tagged and called. The reason it is released as an alpha is so that the community can help find issues like this.

After hours of effort to upgrade dependency and set up environment, I failed to enable hot reloading in my project, totally.

In the future I suggest that if you can't afford to spend these hours, don't use alpha versions of experimental packages. ;-)

I added “Known Issues” to the opening post.

@gaearon for my understanding, how does RHL in combination with React Router work then? In my code, I could only get it to work by using Math.random as the <Router /> key. But you are saying that should not be necessary? If so, great!

For "Known Issues" it's probably worth it to include this as well: webpack/webpack#2399, as export default function is a common pattern for functional components which React Hot Loader 3 supports.

Saddly I'm using POJO React Router config because it's a rather huge and complex project with many routes. Anyway I guess it's my fault to blindly upgrade and refactor despite the fact of alpha version.
And I have to say that @gaearon you're so productive and responsive, that's why I love the open source community.
Many thanks!

@jasonslyvia
No problem. I just released 3.0.0-alpha.13 which should work with POJO routes.
@rybon
In your App.js file (whatever your root component is called), export a root component like this:
export default function Root() {
  return (
    <Router>
      ...
    </Router>
  )
}

Then use it normally in <AppContainer>, i.e. <AppContainter component={Root} />.
As of 3.0.0-alpha.13, this should work with any way of configuring React Router except async routes.

@gaearon you're right, it does work without the unique key hack. I've updated my example counter-hmr app accordingly. Thanks for the help!

Maybe I'm missing something but 3.0.0-alpha.13 still not working for me.
// app.js
import React from 'react';
import ReactDOM from 'react-dom';
import { syncHistoryWithStore } from 'react-router-redux';
import configureStore from './redux/configureStore';
import { AppContainer } from 'react-hot-loader';
import { browserHistory } from 'react-router';

const store = configureStore();
syncHistoryWithStore(browserHistory, store);

const Root = require('./containers/Root').default;
ReactDOM.render(
  <AppContainer component={Root} props={{
    store,
  }} />
, document.getElementById('app'));

if (module.hot) {
  module.hot.accept('./containers/Root', () => {
    ReactDOM.render(
      <AppContainer component={require('./containers/Root').default}
        props={{
          store,
        }}
      />
    , document.getElementById('app'));
  });
}

// Root.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { Router } from 'react-router';
import DevTools from './DevTools';
import routes from '../routes';
import { browserHistory } from 'react-router';

const Root = ({ store, history }) => {
  return (
    <Provider store={store}>
      {
        __DEV__ ?
        (<div>
          <Router history={browserHistory} routes={routes} />
          <DevTools />
        </div>) :
        <Router history={browserHistory} routes={routes} />
      }
    </Provider>
  );
};

export default Root;

And whenever I edited some component, I get the following output.
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[react-router] You cannot change <Router routes>; it will be ignored
[HMR] Updated modules:
[HMR]  - 1363
[HMR]  - 1362
[HMR]  - 1361
[HMR]  - 1538
[HMR]  - 1360
[HMR] App is up to date.

Predictably the component is not hot reloaded. Here are some dependencies I'm using:
    "react": "~0.14.3",
    "react-dom": "~0.14.3",
    "react-redux": "~4.4.5",
    "react-router": "~2.3.0",
    "react-router-redux": "~4.0.4",
    "redux": "^3.5.2",
    "react-hot-loader": "3.0.0-alpha.13",
    "webpack": "^1.13.0",
    "webpack-dev-server": "^1.14.1",
    "babel": "^6.5.2",
    "babel-core": "^6.7.7",
    "babel-loader": "^6.2.4",

Can anyone point out where did I go wrong?

@jasonslyvia I'd say your code looks mostly OK, although you are using browserHistory instead of the passed in history in the Root component. syncHistoryWithStore(browserHistory, store); should be const history = syncHistoryWithStore(browserHistory, store);. Then, pass history in as a prop in your AppContainer.
Could you verify my app https://github.com/rybon/counter-hmr works on your end? If so, I'd check what the differences between your code and mine are and see if you can resolve them. Perhaps you can wrap routes in a function and render like so:
<Router history={history} />
    {getRoutes()}
</Router>

If nothing helps, npm cache clean rm -rf node_modules npm install?

In any case providing a complete project that reproduces the issue would be most helpful.

React Hot Loader 3 beta is out.
Release notes: https://github.com/gaearon/react-hot-loader/releases/tag/v3.0.0-beta.0.

I can't seem to get this to work with redux, specifically using the todos app example. I switched out the major parts, and they do work if I take out react-hot-loader/patch. But something strange happens when I add it.
It looks like props such as onClick callbacks are being passed down correctly on the first run, but for whatever reason, those views are being rendered again two more times. Both of these times log undefined for the onClick callback. Any ideas?

@bkgunby Was your problem solved? I see your message in my email but I don't see it here :disappointed:

Never mind. There is a serious issue when used together with React Redux: https://github.com/gaearon/react-hot-loader/issues/266. The good news is, it’s fairly easy to solve, and solving it might also solve full RR support.

@gaearon Is this support to be working now with react router POJO static routes?

POJO routes are already working in the current beta.
The only thing that doesn't work today is async routes.
This is what will get fixed together with https://github.com/gaearon/react-hot-loader/issues/266 in the next beta (not solved yet).

@gaearon hmm. Not working for me (SystemJS), Ill try play a bit more and maybe get a repo up to replicate. Does it need the react router hack that was posted earlier? Or should it work without monkey patching React Router

It should work fine as is, but it is necessary that the root component gets rerendered. Just replacing the module won't be enough.

If you can post an example I can take a look.

v3.0.0-beta.1 fixes a few major issues. React Router support should now also be complete.
Please update.
https://github.com/gaearon/react-hot-loader/releases/tag/v3.0.0-beta.1

@gaearon it was the same issue gaearon/react-hot-loader#266 had. But I came across your wonderful medium post on hot loading, and I realized I don't even need it for the most part lol.
Thanks for reaching out!

@bkgunby Got it, cool! I’d appreciate if you gave 3.0.0-beta.1 a try though in case you discover more problems we can fix before the stable release 😄 . Thanks!

I'm just getting into Redux, but hot replacing reducers doesn't appear to work for me (i'm on 3.0.0-beta.1).
I've tried modifying both ../reducers/index.js, and ../reducers/counter.js and neither show the console.log and state:
[HMR] The following modules couldn't be hot updated: (They would need a full reload!)

Here is my store/configureStore.js file
import { createStore } from 'redux'
import rootReducer from '../reducers'

export default function configureStore(initialState) {
  const store = createStore(rootReducer, initialState,
    window.devToolsExtension ? window.devToolsExtension() : undefined)

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      console.log('replacing root reducer');
      const nextReducer = require('../reducers').default
      store.replaceReducer(nextReducer)
    })
  }

  return store
}

Maybe I'm missing something?

I'm just getting into Redux, but hot replacing reducers doesn't appear to work for me (i'm on 3.0.0-beta.1).

This shouldn’t be related to React Hot Loader, it has no opinion on what you do with reducers. It only handles React components. That said, if you remove RHL, and the issue goes away, please file a bug in RHL. It’s hard to say more without a complete project reproducing this issue.

@gaearon understood, thanks :)

Is there any way to get rid of the
[react-router] You cannot change <Router routes>; it will be ignored

error?

@leshow Yes, you can contribute to React Router to help fix this: https://github.com/reactjs/react-router/issues/2182

Two questions after playing with this today:

Does anyone have a complicated example yet using redux/redux-react-router? Something like this non-working example that works would be great:

    <AppContainer>
        <Provider store={store}>
            <Router history={history}>
                <Route path="/" component={Root}>
                    <Route path="debug" component={Root} />
                </Route>
            </Router>
        </Provider>
    </AppContainer>, document.getElementById('pluto-container'));

if (module.hot) {
    module.hot.accept('./components/root.jsx', () => {
        ReactDOM.render(
            <AppContainer
                component={Root} props={{store}}
            />, document.getElementById('container'));
    });
}```

2) The examples I see have:
```if (module.hot) {
   //...
<AppContainer
                component={require(./components/root)} props={{store}} />
...

Is the require part necessary? You can't just include that already imported Root component for this? I have been trying to be in the habit of imports vs requires but I notice this require seems to be necessary, maybe to re-instantiate the component?
Thanks for all the hard work, @gaearon!

Does anyone have a complicated example yet using redux/redux-react-router? Something like this non-working example that works would be great:

Just move <Provider>...</Provider> into a separate component called Root in another file that looks like
export default Root() {
  return <Provider>...</Provider>
}

Then you can use <AppContainer><Root /></AppContainer> in both places.

Is the require part necessary? You can't just include that already imported Root component for this? I have been trying to be in the habit of imports vs requires but I notice this require seems to be necessary, maybe to re-instantiate the component?

It is necessary in Webpack 1.x because the Root component will point to the old version even after a hot update. require()ing it again retrieves the new version.
In Webpack 2, this is unnecessary because Root binding is updated automatically. So you can just use Root again.

Thanks @gaearon. So what am I missing here?

Passing "component" prop to  is deprecated. Replace

It's been a long day so apologies if it's simple, but if this is deprecated, how do I do:
<AppContainer component={require(./components/root)} props={{store}} />
Is this going to be acceptable behavior?
let X = require('./components/root.jsx').default;
        ReactDOM.render(
            <AppContainer>
                <X />
            </AppContainer>,
                document.getElementById('container'));
    });

@framerate yes, and that way you can also use props normally. <X store={ store } />.

I have a "complicated" boilerplate for this I made last night. It uses react-router/react-router-redux and a laundry list of other things. I mashed together the minimal boilerplate example with react-slingshot
https://github.com/leshow/react-hot-loader-boilerplate

I created a compatibility table of hot-loadable components. It contains different kinds of components together with react-router. Maybe this is helpful to somebody else wondering why it sometimes works and sometimes doesn't.
The gist of it for react-hot-loader/babel:

Component
Hot Loading

Sync

SyncIndexRouteComponent
✓

SyncRouteComponent
✓

SyncRouteComponentChild
✓

SyncNonExportedComponent
✓1

SyncReassignedComponent
✗

Aync

AsyncIndexRouteComponent
—

AsyncRouteComponent
—

AsyncRouteComponentChild
—

1: only hot-reloads for non-exported component, not for exported component
After manually remounting the components by changing routes back and forth all hot-updates were applied to components which ignored updates initially (marked with —).
Legend:

✓ = Keeps state after hot-loading
✗ = Loses state after hot-loading
— = Ignores update completely

Dependencies:

react-hot-loader 3.0.0-beta.2
react-router 2.4.0

The repository can be found here: https://github.com/dferber90/react-hot-boilerplate.
@gaearon Is this how it is supposed to work at the moment or did I mess up the setup?
I also discovered that components in async routes are hot-loaded correclty when they are included into the application somewhere else directly (e.g. adding import './AsyncRouteComponent' to App.js in the example repo would make it hot-load correctly).

@dferber90
Thank you very much for creating a sample app!
I added a link to it from https://github.com/gaearon/react-hot-loader/issues/288.
Please feel free to help out!

For anybody interested, I have managed to set up react-hot-loader to work with react-router async routes (and redux) by manually adding some workarounds. These workaround will hopefully become unnecessary once react-hot-loader v3 is out and react-router is upgraded. Use with caution until then :)
1. Avoid breaking react-hot-loader
Make sure all your components are defined with const. This is to avoid changing the reference of a component before the export which would break react-hot-loader.
More about this in https://github.com/dferber90/react-hot-boilerplate.
2. Avoid react-router warning messages
Create a file referentially-equal-root-route which only contains export default {}. Import that file where your routes are defined and use
import referenctiallyEqualRootRoute from './referentially-equal-root-route'
Object.assign(referenctiallyEqualRootRoute, {/* your actual routes */})

This ensures the root route has the same reference even across hot-loads and therefore avoids the warning message. This workaround can be removed once react-router accepts changing props.
I'm not sure of the consequences this approach has for onEnter onLeave hooks being fired, so use with caution. This step is not really required for hot-loading components of async routes (I think).
3. Enable hot-loading components of async routes
This is to enable hot-loading components of async routes. In whatever component is wrapped in AppContainer, import the code-split points into the main application (in development).
Given you have this somewhere in your app
getChildRoutes (location, cb) {
    require.ensure([], require =>
      cb(null, require('./async').childRoutes))
  },

Add this to your Root component
if (process.env.NODE_ENV !== 'production') {
  // ...
  require('foo/async')
}

When the main bundle contains the code-split components hot-loading them will work. Since this should only be the case in development, we only include them in dev mode.

Make sure all your components are defined with const. This is to avoid changing the reference of a component before the export which would break react-hot-loader.

Woah, good gotcha. We should definitely document this. It’s a bit of an unfortunate limitation but I don’t see this as a big issue yet. I filed https://github.com/gaearon/react-hot-loader/issues/295.

When the main bundle contains the code-split components hot-loading them will work. Since this should only be the case in development, we only include them in dev mode.

I wonder if this is intentional or not. Is this a bug in Webpack? Why doesn’t it propagate hot updates to async parents? Do you think it’s worth to raise an issue?

Woah, good gotcha

Thank you :)

I wonder if this is intentional or not. Is this a bug in Webpack? Why doesn’t it propagate hot updates to async parents? Do you think it’s worth to raise an issue?

Well, the updates seem to arrive. The app gets rerendered from the root. I have no idea why this fixes hot-loading, I stumbled upon this workaround while debugging. I'm not familiar with webpack internals so I can't judge where the culprit lies :(

I'm working on converting a rather complicated electron package over (and rewriting my webpack config as I go).
Is this immediately indicative of something? If I switch away from only-dev-server it forces a full refresh but I thought the Maximum call size exceeded might be indicative of a common mistake I missed while upgrading to hmr3. Any suggestions appreciated!
[WDS] App updated. Recompiling...
[WDS] Warnings while compiling.
./~/encoding/lib/iconv-loader.js
Critical dependencies:
9:12-34 the request of a dependency is an expression
 @ ./~/encoding/lib/iconv-loader.js 9:12-34
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] The following modules couldn't be hot updated: (They would need a full reload!)
[HMR]  - 856
[HMR] Nothing hot updated.
[HMR] App is up to date.
Uncaught RangeError: Maximum call stack size exceeded

@dferber90 thanks for your example!
Do you (or anyone here) know if it is safe to create singletons like the application store by putting an instance on export default like you do in store.js? I couldn't find any definite answer on this...

@0x80 This should be ok, as long as the singleton is in a leaf node of your dependency tree and you aren't modifying it :) As soon as you modify it you will loose state

@alexisvincent Does it make the state behave any different when you edit code in reducers? I'm trying to understand if there are any edge cases.

@0x80 Nope. You should be getting back exactly the same object as before. You might also want to have a look at https://github.com/peteruithoven/systemjs-hot-reloader-store

@framerate Alas, can’t help without a project reproducing the issue. 😞

I'm seeing a CORS issue. I'm serving the html on the port 3040 and webpack using webpack-dev-server is serving the assets on 5001.
abstract-xhr.js:132 GET http://localhost:5001/assets/build/info?t=1463998805473

XMLHttpRequest cannot load http://localhost:5001/assets/build/info?t=1463998805473. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3040' is therefore not allowed access. The response had HTTP status code 404.

Has anyone managed to get this working with Relay? Components stop reloading as soon as I wrap them with Relay.createContainer.

@nthtran
I'm not familiar with relay, but it was stated in this thread that components can't have their reference changed (and so you should define them with const).
My guess is that Relay is changing the reference of the components and thus breaking RHL.

@gaearon Could you please strike through  this line in your original posting for clarity:

@gaearon I used @dferber90 boilerplate as an example and moved my project to react-hot-loader 3.0.0-beta.2.
But I get main.bundle.js:25951 Uncaught SyntaxError: missing ) after argument list
This is the code it complains about:
		module.hot.accept(/*! !./../../../~/css-loader?sourceMap&modules&importLoaders=2!./../../../~/postcss-loader!./../../../~/resolve-url-loader!./../../../~/sass-loader?sourceMap!./styles.scss */ 27/*! !./../../../~/css-loader?sourceMap&modules&importLoaders=2!./../../../~/postcss-loader!./../../../~/resolve-url-loader!./../../../~/sass-loader?sourceMap!./styles.scss */ 27, function() {
			var newContent = __webpack_require__(/*! !./../../../~/css-loader?sourceMap&modules&importLoaders=2!./../../../~/postcss-loader!./../../../~/resolve-url-loader!./../../../~/sass-loader?sourceMap!./styles.scss */ 27);
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});

Any ideas whats going on here?
This is what I run:
cross-env NODE_ENV=development webpack-dev-server -d --history-api-fallback --inline --progress --hot --watch
This is my webpack.config.babel.js:
 /**
 * Dependencies
 */
import path from 'path';
import yargs from 'yargs';
import webpack from 'webpack';
import autoprefixer from 'autoprefixer';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import BrowserSyncPlugin from 'browser-sync-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';

/**
 * Environment type
 */
const {buildProduction, buildDevelopment, buildTest} = yargs
  .alias('p', 'build-production')
  .alias('d', 'build-development')
  .alias('t', 'build-test')
  .argv;
const nodeEnv = buildProduction ? 'production' : 'development';

console.log(buildProduction, buildDevelopment, buildTest);
console.log('------------------------------------------------------');

/**
 * Config
 * Reference: http://webpack.github.io/docs/configuration.html
 * This is the object where all configuration gets set
 */
let config = {};

/**
 * Entry
 * Reference: http://webpack.github.io/docs/configuration.html#entry
 * Should be an empty object if it's generating a test build
 * Karma will set this when it's a test build
 */
if (buildTest) {
  config.entry = {}
} else {
  config.entry = [
    'react-hot-loader/patch',
    'webpack-dev-server/client?http://localhost:3000',
    'webpack/hot/only-dev-server',
    './src/index.js'
  ]
}

/**
 * Externals
 * Reference: http://webpack.github.io/docs/configuration.html#externals
 */
config.externals = {
  "react": "React",
  "react-dom": "ReactDOM"
};

/**
 * Output
 * Reference: http://webpack.github.io/docs/configuration.html#output
 * Should be an empty object if it's generating a test build
 * Karma will handle setting it up for you when it's a test build
 */
if (buildTest) {
  config.output = {};
} else {
  config.output = {
    // Absolute output directory
    path: buildProduction ? __dirname + '/dist' : __dirname + '/public',

    // Output path from the view of the page
    // Uses webpack-dev-server in development
    // Reference: http://stackoverflow.com/questions/34133808/webpack-ots-parsing-error-loading-fonts/34133809#34133809
    publicPath: buildProduction ? '' : 'http://localhost:3000/',

    // Filename for entry points
    // Only adds hash in build mode
    filename: buildProduction ? '[name].[hash].js' : '[name].bundle.js',

    // Filename for non-entry points
    // Only adds hash in build mode
    chunkFilename: buildProduction ? '[name].[hash].js' : '[name].bundle.js'
  };
}

/**
 * Devtool
 * Reference: http://webpack.github.io/docs/configuration.html#devtool
 * Type of sourcemap to use per build type
 */
if (buildTest) {
  config.devtool = 'inline-source-map';
} else if (buildProduction) {
  config.devtool = 'source-map';
} else {
  config.devtool = 'cheap-module-source-map';
}

/**
 * Resolvers
 * Reference: http://webpack.github.io/docs/configuration.html#resolve
 */
config.resolve = {
  extensions: ['', '.jsx', '.scss', '.js', '.json'],
  modulesDirectories: [
    'node_modules',
    path.resolve(__dirname, './node_modules')
  ]
};

/**
 * Loaders
 * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
 * List: http://webpack.github.io/docs/list-of-loaders.html
 * This handles most of the magic responsible for converting modules
 */

// Initialize module
config.module = {
  preLoaders: [],
  loaders: [{
    // JS LOADER
    // Reference: https://github.com/babel/babel-loader
    // Transpile .js files using babel-loader
    // Compiles ES6 and ES7 into ES5 code
    test: /\.js$/,
    loader: 'babel',
    exclude: /(node_modules|bower_components)/
  }, {
    // ASSET FONT LOADER
    // Reference: https://github.com/webpack/file-loader
    // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
    // Rename the file using the asset hash
    // Pass along the updated reference to your code
    // You can add here any file extension you want to get copied to your output
    test: /\.(svg|woff|woff2|ttf|eot)$/,
    loader: 'file?name=assets/fonts/[name].[hash].[ext]'
  }, {
    // ASSET IMAGE LOADER
    // Reference: https://github.com/webpack/file-loader
    // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
    // Rename the file using the asset hash
    // Pass along the updated reference to your code
    // You can add here any file extension you want to get copied to your output
    test: /\.(png|jpg|jpeg|gif)$/,
    loader: 'file?name=assets/images/[name].[hash].[ext]'
  }, {
    // HTML LOADER
    // Reference: https://github.com/webpack/raw-loader
    // Allow loading html through js
    test: /\.html$/,
    loader: 'html'
  }, {
    // JSON LOADER
    // Reference: https://github.com/webpack/json-loader
    // Allow loading JSON
    test: /\.json$/,
    loader: 'json'
  }
  ]
};

// ISPARTA LOADER
// Reference: https://github.com/ColCh/isparta-instrumenter-loader
// Instrument JS files with Isparta for subsequent code coverage reporting
// Skips node_modules and files that end with .test.js
if (buildTest) {
  config.module.preLoaders.push({
    test: /\.js$/,
    exclude: [
      /(node_modules|bower_components)/,
      /\.test\.js$/
    ],
    loader: 'isparta-instrumenter'
  })
}

// LESS LOADER
// Reference: https://github.com/webpack/less-loader
// Allow loading less/css through js
// Reference: https://github.com/postcss/postcss-loader
// Postprocess your less/css with PostCSS plugins
var lessLoader = {
  test: /\.less$/,
  // Reference: https://github.com/webpack/style-loader
  // Use style-loader in development for hot-loading
  loader: (!buildProduction || buildTest) ? 'style!css?sourceMap&modules&importLoaders=2!postcss!resolve-url!less' :
    // Reference: https://github.com/webpack/extract-text-webpack-plugin
    // Extract less/css files in production builds
    ExtractTextPlugin.extract(
      // activate source maps via loader query
      'css?sourceMap&modules&importLoaders=2!postcss!resolve-url!less'
    )
};

// SASS LOADER
// Reference: https://github.com/jtangelder/sass-loader
// Allow loading sass/css through js
// Reference: https://github.com/react-toolbox/react-toolbox/issues/246
// Configure React-Toolbox properly. TODO replace with own theming plugin
var sassLoader = {
  test: /(\.scss|\.css)$/,
  // Reference: https://github.com/webpack/style-loader
  // Use style-loader in development for hot-loading
  // Reference: https://github.com/webpack/css-loader
  // Use css-loader with css-modules support for react-toolbox
  // Reference: https://github.com/postcss/postcss-loader
  // Reference: https://github.com/jtangelder/sass-loader
  loader: (!buildProduction || buildTest) ? 'style!css?sourceMap&modules&importLoaders=2!postcss!resolve-url!sass?sourceMap' :
    // Reference: https://github.com/webpack/extract-text-webpack-plugin
    // Extract sass/css files in production builds
    ExtractTextPlugin.extract('css?sourceMap&modules&importLoaders=2!postcss!resolve-url!sass?sourceMap')
};

// Skip loading css in test mode
if (buildTest) {
  // Reference: https://github.com/webpack/null-loader
  // Return an empty module
  lessLoader.loader = 'null';
  sassLoader.loader = 'null';
}

// Add cssLoader to the loader list
// To use less use: config.module.loaders.push(lessLoader);
config.module.loaders.push(sassLoader);

/**
 * PostCSS
 * Reference: https://github.com/postcss/autoprefixer-core
 * Add vendor prefixes to your css
 */
config.postcss = [
  autoprefixer({
    browsers: ['last 2 version']
  })
];

/**
 * Plugins
 * Reference: http://webpack.github.io/docs/configuration.html#plugins
 * List: http://webpack.github.io/docs/list-of-plugins.html
 */
console.log(JSON.stringify(nodeEnv));
console.log('------------------------');
config.plugins = [
  // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
  // Configure the node build environment
  new webpack.DefinePlugin({
    'process.env': {NODE_ENV: JSON.stringify(nodeEnv)}
  }),
  // Reference: https://github.com/webpack/extract-text-webpack-plugin
  // Extract css files
  // Disabled when in test mode or not in build mode
  new ExtractTextPlugin('[name].[hash].css', {
    disable: !buildProduction || buildTest
  }),
  // Reference: http://mts.io/2015/04/08/webpack-shims-polyfills/
  // Inject a polyfill for the given key words
  new webpack.ProvidePlugin({
    'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
  })
];

// Skip rendering index.html in test mode
if (!buildTest) {
  // Reference: https://github.com/ampedandwired/html-webpack-plugin
  // Render index.html
  config.plugins.push(
    new HtmlWebpackPlugin({
      template: './src/index.ejs',
      inject: false
    })
  );
}

// Add build specific plugins
if (buildProduction) {
  // Reference: https://github.com/jeffling/ng-annotate-webpack-plugin
  // Make Angular Injections minification safe
  config.plugins.push(
    // Reference: https://github.com/johnagan/clean-webpack-plugin
    // Clean the output folders before building
    new CleanWebpackPlugin(['dist', 'build'], __dirname),
    // Reference: https://github.com/kevlened/copy-webpack-plugin
    // Copy the public folder to the dist folder
    new CopyWebpackPlugin([
      {from: 'public'}
    ]),
    // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
    // Only emit files when there are no errors
    new webpack.NoErrorsPlugin(),

    // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
    // Dedupe modules in the output
    new webpack.optimize.DedupePlugin(),

    // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
    // Minify all javascript, switch loaders to minimizing mode
    new webpack.optimize.UglifyJsPlugin()
  )
}

// Add dev specific plugins
if (!buildProduction && !buildTest) {
  config.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    // https://webpack.github.io/docs/list-of-plugins.html#occurenceorderplugin
    new webpack.optimize.OccurenceOrderPlugin(),
    // Reference: https://github.com/gaearon/react-hot-loader/issues/127
    // https://webpack.github.io/docs/list-of-plugins.html#hotmodulereplacementplugin
    // new webpack.HotModuleReplacementPlugin(),
    // https://github.com/webpack/webpack/issues/701
    new webpack.OldWatchingPlugin(),
    // https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
    new webpack.optimize.DedupePlugin(),
    // https://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
    new webpack.NoErrorsPlugin(),
    // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
    // Only emit files when there are no errors
    new BrowserSyncPlugin(
      {
        host: 'localhost',
        port: 3000,
        proxy: 'http://localhost:8087/'
      },
      {
        // determines if browserSync should take care
        // of reload (defaults to true). switching it off
        // might be useful if you combine this plugin
        // with webpack-dev-server to reach
        // Hot Loader/Hot Module Replacement tricks
        reload: false
      })
  )
}

/**
 * Dev server configuration
 * Reference: http://webpack.github.io/docs/configuration.html#devserver
 * Reference: http://webpack.github.io/docs/webpack-dev-server.html
 */
config.devServer = {
  contentBase: './public',
  port: 8087,
  stats: {
    modules: false,
    cached: false,
    colors: true,
    chunk: false
  }
  /**
   * Add your own certificates for https here.
   * cert: fs.readFileSync('certificates/my-domain.crt'),
   * key: fs.readFileSync('certificates/my-domain.decrypted.key')
   */
};

export default config;

And this my .babelrc:
{
  "presets": [
    "es2015",
    "stage-0",
    "react"
  ],
  "env": {
    "development": {
      "plugins": [
        "react-hot-loader/babel",
        [
          "react-intl",
          {
            "messagesDir": "./build/i18n/",
            "enforceDescriptions": true
          }
        ]
      ]
    },
    "production": {
      "plugins": []
    }
  }
}

Does anyone have a running version of this using webpack v2?  I've had all sorts of trouble with mine, but the moment I remove the RHL babel plugin all is well again (minus the RHL of course).

@ctrlplusb you can check out this very minimum project if you like CrocoDillon/universal-react-redux-boilerplate v2, got Webpack 2 and RHL 3 working there.

I have a very strange case. Hot reloading is working beautifully, however when I manually refresh my page the original (i.e. first built) bundle is served instead of the latest version.
Absolutely confused about this one...

Hey guys,
Any news on v3.0 release? When about is it planned?

Hi all, I've created a new boilerplate that uses Webpack 2 and RHL 3.
react-universally
A mildly opinionated ultra low dependency universal react boilerplate.
https://github.com/ctrlplusb/react-universally

@gaearon I have noticed that you have commented on a few issues related to selectors and referencing v3.
I am still having issues with selectors, but I am not using reselect. Is it expected? Am I potentially missing setup? Or is it just because I have not implemented reselect yet?
Thanks

I have another boilerplate/starter going at https://github.com/jkudish/spark-react-starter. It includes isomorphic/universal/server rendering

Any boilerplate examples that don't use Babel?

Is it possible to get https://github.com/gaearon/react-transform-catch-errors working with the new loader?

I'm trying to set up RHL3-beta, and followed both upgrade manuals, but for some reason on every update the entire root component is refreshed (without saving any component's inner state, or even scroll position).
Seems like it just re-renders everything, as it would have done without me wrapping it with 'AppContainer'.
What can I be doing wrong? Where should I start looking?
(I'm using the Babel plugin.)
Thanks!

I'm using webpack 2 and react-hot-loader is not reloading my react components as stated, I had to use this
const rootElement = document.getElementById('grv-root-element');
render(<AppContainer><App/></AppContainer>, rootElement);

if (module.hot) {
  module.hot.accept('./lib/components/App', () => {
    const NewApp = require('./lib/components/App');
    render(<AppContainer><App/></AppContainer>, rootElement)
  });
}

If I comment the NewApp line, it won't reload, but if I use the NextApp in the second render it will tell me with a warning on the browser that it could not update my components.

I have had similar findings like @aj1310, that requiring "Root" component in a hot.accept causes the desired reload however using the newly required "Root" causes react-router warnings.

Why would requiring be a condition for the reload?
How come it works without using the new require?
What kind of repercussion could this have?

Thanks

@aj1310 this may have just been a mistype but in your hot.accept the render is referencing App instead of NewApp, do you see any changes when you switch that out?

@kwelch I think he tried explain that was intentional:

If I comment the NewApp line, it won't reload, but if I use the NextApp in the second render it will tell me with a warning on the browser that it could not update my components.

This due to the same result I experienced that for some reason requiring causes the reload, but if the new required component is used instead of the original, react-router complains when hot-reloaded. The solution we found was to use the old component (Im using webpack 1) while requiring a dummy in the modules.hot.accept(...).
Root.jsx
import Routes from './Routes.jsx';

export default function Root(props) {
    return (
        <Provider store={props.store}>
            <Router history={props.history} routes={Routes} />
        </Provider>
    );
}

Client.jsx
const store = ...
const history = ...
const Root = require('./Root.jsx').default;
const $root = document.getElementById('root');

ReactDOM.render(
    <AppContainer>
        <Root store={store} history={history} />
    </AppContainer>,
    $root
);

if (module.hot) {
    module.hot.accept('./Root.jsx', () => {

        /* Running require tiggers hot reload, however using "dummy" instead of "Root" causes router warnings */
        const dummy = require('./Root.jsx').default;

        ReactDOM.render(
            <AppContainer>
                <Root store={store} history={history} />
            </AppContainer>,
            $root
        );
    });
}

Thanks for clarification, I am using webpack 1, but I use NextApp in the reload section. It has been working more or less for our current app. Although it took a good amount of time to get it that way.

I'm having great success with the beta branch. For the first time, my app is actually hot reloading components (always had issues due to stateless components or something wrong in the setup).

Is there any reason this beta version would not work with webpack-dev-middleware and webpack-hot-middleware?

@pauldotknopf I've been using it for months. Works great.
The only trouble I had was trying to get it working with server-side rendering & react-redbox... but that's because I couldn't really find any examples for how to make those things work.
Have been hot reloading functional components for months though!

Do i need to manually implement hot reloading for redux-style containers or it is supposed to work out of the box? e.g.:
...
const ContainerForSomeComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(SomeComponent);

export default ContainerForSomeComponent;

I can see that everything is hot-reloaded well until reaching this ContainerForSomeComponent and the embedded SomeComponent isn't reloaded.

Here's a Chrome DevTools filter you can use to suppress [react-router] You cannot change <Router routes>; it will be ignored:
^((?!You cannot change <Router routes>).)+$

Put it here:

I'm using v.3.0.0-beta.1 with such config:
// lines skiped
    'webpack-hot-middleware/client',
     'react-hot-loader/patch',
// lines skiped

ERROR in ./~/react-hot-loader/patch.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./lib/patch in C:
workspace\java\boot-react\frontend\node_modules\react-hot-loader
@ ./~/react-hot-loader/patch.js 1:17-39

Replace

module.exports = require('./lib/patch');

To

module.exports = require('./src/patch');

helped.
But it my mistake in installation (copy downloaded source to node_modules) or what?
And gotten

@istarkov hello, I also use webpack-hot-middleware,  and if I add webpack-hot-middleware/client into the entry, the webpack will bundle source and do well, but the browser do nothing, and if I add webpack-hot-middleware/client?reload=true  then the browser will reload all the page instead of updating the hot change, did you meet this problem?

@dferber90, thanks for the great work of the compatibility table. Just a quick question in terms of your solution to enable hot-loading components of async routes, does requiring code-split points essentially make async routes become sync routes? I am asking because in my local test, after adding those require statements the required components seem to get pre-loaded before the corresponding route is accessed.

@aarryy Yes it makes them synchronous, but only in development mode since the routes are only imported if process.env.NODE_ENV !== 'production'. This is fine since the workaround is only necessary to fix react-hot-loader which is not used in production anyways.
This workaround introduces a slight difference between your development and production environments, since the async chunks are evaluated immediately in development mode, but in production they are evaluated only after the route is visited.

I use webpack-dev-middleware, webpack-hot-middleware and webpack 2. Can't make RHL work. It shows success messages in the browser console, but the DOM isn't updated. The same thing with webpack 1.
Does anybody have simple working example with webpack 2 + WDM + WHM + RHL 3?

@osenvosem  https://github.com/gaearon/react-hot-boilerplate/pull/72 can what you are looking for. I used the same config except that I used browsersync instead of express due to the project requirement and that worked well for me.

Getting the following when changing the text of my component
[HMR] Cannot apply update. Need to do a full reload!
dev-server.js:19[HMR] Error: Aborted because 945 is not accepted...

Is this because I am using ReactDOM.render?
ReactDOM.render(
      <AppContainer>
        <Provider store={store}>
          <Router history={history} routes={routes} />
        </Provider>
      </AppContainer>
      , document.querySelector(opts.selector))

I cannot seem to get this working. Keep getting [HMR] Cannot apply update. Need to do a full reload! on a simple text change. Was working before with RHL 1.3
Does anything stand out with my setup?
// client.js

import 'react-hot-loader/patch'

...

ReactDOM.render(
  <AppContainer>
    <Provider store={store}>
      <Router history={history} routes={routes} />
    </Provider>
  </AppContainer>
  , document.querySelector(opts.selector))

// webpack.hot.config.js

module.exports = {
  devtool: 'source-map',

  context: __dirname + '/app/assets/javascripts/react',

  entry: {
    client: './client.js',
    server: './server.js',
  },

  output: {
    path: __dirname + '/app/assets/javascripts/react/',
    filename: '[name]_bundle.js',
    publicPath: 'http://localhost:8080/assets/react/',
    // Used to expose server-side rendering function to global contenxt
    library: ['HS', '[name]'],
    libraryTarget: 'var',
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['jsx-loader', 'babel-loader'],
        exclude: /node_modules/
      },
    ],
  },
}

// .babelrc

{
  "presets": ["react", "es2015", "stage-1"],
  "plugins": ["react-hot-loader/babel"]
}

// package.json

"devDependencies": {
  ...
  "react-hot-loader": "3.0.0-beta.3",
  "webpack-dev-server": "^1.14.1",
},
"dependencies": {
  ...
  "react": "^0.14.7",
  "react-dom": "^0.14.7",
  "webpack": "^1.12.13"
  ...
}

@ryan-sherpa I'm noticing that message on a fresh upgrade today but only when using stateless components:
import React from 'react';

const Main = () => (
    <div>
        <h1>Root Route</h1>
    </div>
);

export default Main;

If I convert that to a normal react class, it hot reloads fine. @gaearon is that a known issue? Or possibly indicative of a greater problem?

@framerate, thanks for the response. I just tested both smart and dumb components in my app, neither seem to hot-reload appropriately. I'm thinking it's my webpack config file not being setup properly, however I could be mistaken.

@ryan-sherpa Yeah I have this setup on another project and it seems to be working flawlessly. This new one though I seem to be missing something as well. I can't seem to find a "checklist" of all the things to do thats easy to follow, but perhaps someone can direct us to one.

@framerate @ryan-sherpa I have an example app react-lego which shows how to add RHL v3 (sorry, not an upgrade path from v1)
the comparison in github will hopefully help you though: https://github.com/peter-mouland/react-lego/compare/react-hot-loader

@osenvosem I've just push a branch to the same react-lego  app mentioned above which shows webpack 2 working with RHL3.
this is the branch https://github.com/peter-mouland/react-lego/tree/webpack2-rhl
but i guess you want to see the changes made to get webpack 2 working, then RHL3?
https://github.com/peter-mouland/react-lego/compare/webpack2-rhl
This link shows you the 1 commit for webpack2, 1 commit for rhl3 then a 3rd just to get them playing together.
hope that helps, any questions let me know

Seems like we shouldn't have any more dreaded "can't change routes" warnings with RR v4. And routes should hot reload too. https://react-router-website-uxmsaeusnn.now.sh/basic

@peter-mouland I tried you webpack2-rhl branch but I get a UNMET PEER DEPENDENCY<EMAIL_ADDRESS>

@tuler I don't get that - rm -rf node_modules && npm i in the correct branch and it was fine.
ps, any more questions, i'm happy to help - just post them in the react-lego repo to keep this thread as small as possible!

While trying to upgrade to v3 I'm getting (npm debug log) using with express:
41 error argv "/home/fpaboim/.nvm/versions/node/v6.3.1/bin/node" "/home/fpaboim/.nvm/versions/node/v6.3.1/bin/npm" "install" "babel-plugin-react-hot-loader/babel" "--save"
42 error node v6.3.1
43 error npm  v3.10.3
44 error code 128
45 error Command failed: git clone --template=/home/fpaboim/.npm/_git-remotes/_templates --mirror git@github.com:babel-plugin-react-hot-loader/babel.git /home/fpaboim/.npm/_git-remotes/git-github-com-babel-plugin-react-hot-loader-babel-git-6e2be987
45 error Cloning into bare repository '/home/fpaboim/.npm/_git-remotes/git-github-com-babel-plugin-react-hot-loader-babel-git-6e2be987'...
45 error ERROR: Repository not found.
45 error fatal: Could not read from remote repository.
45 error
45 error Please make sure you have the correct access rights
45 error and the repository exists.

when I insert:
...
"plugins": ["react-hot-loader/babel"],
...

Looks like it's not finding the repo? Nevertheless, hot module reloading seems to be working when I insert the plugin! If I remove it, the message goes away, but rebuilding does not update the view. On ubuntu 16.04 in virtualbox, beta6 version of package. Thanks, awesome work!

@gaearon is your April 18 suggestion intended only for hot reloading routes themselves, not their components? I took it to mean component hot reloading, but componentWillReceiveProps isn't run (for me, at least) if all I do is modify the contents of a component.

Hi guys
Can you please post a recipe here with all the things that need to be imported and configured to make the new react-hot-loader work with redux.
I read through all the posts already and there are many projects with different attempts, but nobody actually explains exactly what are the steps to make it work.
As of now I could not find a way to make this component 'hot reload' without loosing state:
function Home(props) {
  return (
    <div onClick={() => props.onStuff(4711)}>
        Change this text and see that we loose this state: {props.stuff}
      </div>
  );
}

const mapStateToProps = (state) => {
  return {
    stuff: state.home.stuff
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onStuff: (id) => {
      dispatch({type: 'STUFF', id: id});
    }
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);

I also tried const Home React.createClass({ and class Home extends React.Component { but nothing helped.

@BerndWessels I quickly created a bare-minimum demo repo: https://github.com/patrikholcak/hot-loader-demo
I couldn’t get it to work with webpack-dev-server so I ended up using webpack-dev-middleware & webpack-hot-middleware together with express.
First off, you need to add react-hot-loader/patch as an entry to webpack. It needs to be run before your app’s entry point. So:
module.exports = {
  entry: [
    'react-hot-loader/patch',
    'webpack-hot-middleware/client',
    './src/main.js'
  ],
  …
}

If you don’t use webpack or don’t want to add it as entry-point, you can import it in your app’s entry point but it should be on the first line.

You also need to add react-hot-loader/babel as a plugin to your .babelrc (in my case package.json)
{
  "presets": [
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel"
  ]
}

Then you need to render your app in the <AppContainer> component — like this:
import { AppContainer } from 'react-hot-loader';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

import App from './app';
import appReducer from './reducer';

const store = createStore(appReducer);

ReactDOM.render(
  <AppContainer>
    <Provider store={store}>
      <App />
    </Provider>
  </AppContainer>,
  rootEl
);

and the last step is to tell webpack that ./app and ./reducer know how to hot-reload themselves.
if (module.hot) {
  module.hot.accept('./reducer', () => {
    // redux store has a method replaceReducer
    store.replaceReducer(appReducer);
  });

  module.hot.accept('./app', renderApp);
}

Hope it helps!

@patrikholcak Thank you so much. That is what I was looking for and I really hope that this will become a proper official documentation.
PS Where is the best place to learn more about module.hot in more detail?

@BerndWessels well, it’s still in an alpha stage, so there’s still much to iron out and keeping the documentation on par with the code might slow the process down a bit. However, I understand the frustration — I spent a good amount of time debugging it myself.
I also have a<EMAIL_ADDRESS>set up with redux controlled router, if that’s something you’re interested in.
You can read more about module.hot in the webpack documentation.

I also have a<EMAIL_ADDRESS>set up with redux controlled router, if that’s something you’re interested in.

@patrikholcak  Yes please!

I guess some people playing with webpack 2 may still not be aware of its latest documentation, since it's a different url. The new url is https://webpack.js.org/
It isn't complete yet, but I found it super helpful, specially the sections configuration and how to.

here is my set up with a webpack 2, react-router 4 and react-hot-load v3.
each one added in a new branch making it very easy to see the changes required.
hope it helps.
https://github.com/peter-mouland/react-lego#server-side-rendering-ssr

@oomathias, @rafaelbiten, @geowarin — Just pushed a new commit to patrikholcak/hot-loader-demo. I might keep updating it, but I certainly will not be able to provide any support. It’s quickly put together and the implementation is very rough. I wouldn’t recommend running it in production (although I am).
I know about the new url and the documentation is awesome, but I don’t really want to link to it as it’s not fully written and might cause confusion.
@peter-mouland Awesome repo from which I have taken some inspiration implementing this, but reading through diffs is somehow confusing to me so I wanted to give it a shot myself and go with the minimal setup
PS: I had the same idea about the lego repo a while ago, it’s so cool to see someone actually do it! :)

All examples I've looked at are using HMR accept like the one in the official docs: How to Set Up Hot Module Replacement with React?
This part doesn't work for me (the callback is never being called so the HMR fails leaving a message in the console that a reload is required, the dependency does match otherwise it would give an error so I'm not sure why the callback isn't being called when the dependency is changed)
module.hot.accept('./components/App', render);

However self-accepting works (which also means you won't need the render function)
module.hot.accept();

Any downsides to this approach?

@CrocoDillon weird. Did you read my tutorial just above? It should work. Which webpack version are you using?
Using only if (module.hot) module.hot.accept(); should theoretically work, as it accepts the module itself. I’m not sure about the downsides though. The only one I can imagine would be using it with a module which requires some additional reload configuration (eg. redux store).
module.hot.accept('./reducer', () => {
  const nextStore = require('./reducer');

  store.replaceReducer(nextStore);
});

@patrikholcak If a module self-accepts, it prevents any module that accepts it as dependency from having their accept callbacks run. If you are, for some reason, using commonjs, not running the accept callback (for the require call) also prevents the imported object from being updated.

@CrocoDillon make sure the ./component/App is only imported from one place, the file that tries to accept it. A module has to be accepted by all files that, directly or indirectly, import it.
The console log should tell you why it was not accepted.

I'm running a webpack setup using a separately bundled DLL file similar to this: http://engineering.invisionapp.com/post/optimizing-webpack/
When I implemented React Hot Loader 3.0, hot loading was working, but would stop as soon as a component used react-redux connect. Removing react-hot-loader from the DLL and instead allowing it to be included in the main app webpack bundle solved the problem. I am now seeing correct hot loading behaviour 😃

So after a few hours of banging my head against the wall, I was finally able to get it working with React-Router and async routes (using require.ensure). I followed @patrikholcak 's well-written instructions, but had to add a few more things.
if (module.hot) {
  module.hot.accept('./routes', () => {
    routes = require('./routes').default
    ReactDOM.render(
      <AppContainer key={Math.random()}>
        <Provider store={store}>
          <Router
            history={history}
            routes={routes}
            render={applyRouterMiddleware(useScroll())}
          />
        </Provider>
      </AppContainer>,
      document.getElementById('root')
    )
  })
}

Essentially I'm listening to the routes file, reloading it whenever there's a change, and adding a random key to AppContainer.
Please guys we need to document this somewhere. My hot reload just suddenly stopped working yesterday after clearing my node_modules, and I had to waste a lot of time on Google trying to fix this (ending up here in this random pull request). I've definitely learned the hard way that I need to shrinkwrap everything (guessing that would've prevented this).

@JeremyBernier the key={Math.random() works well for me.
My index.js file looks like:
import {Router, Route, browserHistory} from 'react-router'
import { AppContainer } from 'react-hot-loader'
import ReactDOM from 'react-dom'
import React from 'react'

import App from './App'
import './style.scss'

const el = document.getElementById('app')

function render (component) {
  return ReactDOM.render(
    <AppContainer key={Math.random()}>
      <Router history={browserHistory}>
        <Route path='/' component={component} />
      </Router>
    </AppContainer>,
    el
  )
}

render(App)

if (module.hot) {
  module.hot.accept('./App', () => {
    // If you use Webpack 2 in ES modules mode, you can
    // use <App /> here rather than require() a <NextApp />.
    const NextApp = require('./App').default
    render(NextApp)
  })
}

@gaeron  I got my project to work with v3 and webpack 2.2.0-rc.0  using this webpack.config.entry
entry: {
        app: [
            'webpack-hot-middleware/client',
            'react-hot-loader/patch',
            "./src/ts/index.jsx"]
    }

running the server entrypoint like node server.js. Its fast!
Is there a way I could hook this up to run with the webpack-dev-server yet?

What would be the correct setup if instead of having a SPA we have an hybrid server rendered page with a bunch of standalone React components rendered independently at different places on the same page. For instance when you just want to add a JS widget (in React) on an existing page.
Note that I have a single entry point "main.js" in webpack which works with some kind of a router calling different functions (which render react components) depending on the current URL path.
For now, I have to wrap each component in a different  along with module.hot.accept stuff. While this makes sense and works fine, it's kind of repetitive when I need to render more than 1 component in the same page.
I know that since each component is rendered separately, they are each different mini-application with their own lifecycle. Just wondered if I can do better than this :)

@benjamindulau i don't know if this is the right place for this discussion, but i'll answer anyway, then if any more info is needed i'd recommend stack overflow rather than adding to the discussion here.
sounds like a custom webpack-loader might work here.  You can make the loader wrap the files for you.  I've only ever had a hand in building one so i don't know best practises, but the reason for mine and yours were very similar.  I wrapped each component in code that would render each component within a ruby app, so we could drop in components independently.
here is the source to get you started.
const loaderUtils = require('loader-utils');
const getComponentName = (componentPath) => {
  const componentPathSegments = componentPath.split('/');

  //return the second-to-last segment
  return componentPathSegments.slice(-2, -1)[0];
};

module.exports = function (source) {
  let componentName;
  let loaderSource = source;

  this.value = loaderSource;
  this.cacheable && this.cacheable();
  try {
    componentName = getComponentName(loaderUtils.getRemainingRequest(this));
  }
  catch (e) {
    return source;
  }
  try {
    loaderSource = `${source};
    window.document.addEventListener("DOMContentLoaded", function(event) {
      window.setTimeout(function(){
        const elems = document.querySelectorAll('[toga=${componentName}]');
        [].forEach.call(elems, function(elem) {
          let props;
          try {
            props = JSON.parse(elem.getAttribute('props'));
          } catch (e) {
            props = {};
          }
          const Component = (typeof exports.default === 'undefined')
              ? module.exports
              : exports.default;
          ReactDOM.render(<Component {...props}/>, elem);
        });
      }, 1);
    });`;
  }
  catch (e) {
    return source;
  }
  this.value = loaderSource;

  return loaderSource;
};

For those who are having trouble with react-router 3 + async routes + hot-module-reload, please see: https://github.com/gaearon/react-hot-loader/issues/288#issuecomment-281372266
You may look at https://github.com/moxystudio/react-with-moxy for a working example.

@JeremyBernier your solution seems to be working for me, but I get Warning: [react-router] You cannot change <Router routes>; it will be ignored in the console. Not sure if this matters or if it slowing down the update. Also routes = require('./routes').default  line is missing a const BTW

Not sure if this is the right forum for the following comments, but I see lots of references to universal rendering projects. I just got all universal rendering +<EMAIL_ADDRESS>working together and have some tips.

The module.hot.accept line needs to look like module.hot.accept('./App', () => render(require('./App').default));

For those trying to have universal rendering + hot module reloading:

You should split webpack-dev-server out into its own process (especially if you are using node-foreman or some other backend reloader).
Your webpack config's output entry should look like this:

output: {
        path: __dirname + '/build/',
        filename: 'app.js',
        publicPath: `http://localhost:${DEV_SERVER_PORT}/build/`,
    },

That is, your publicPath should contain the full URL of your webpack-dev-server otherwise it will try to make the hot module reload request to your backend server instead of the webpack-dev-server.

@dantesolis dev dependency

Shouldn't be a dependency since you import {AppContainer} from 'react-hot-loader' even when your app is in production (and AppContainer does nothing in this case)?

@aymericbouzy you can work around that problem with a require rather than import based on NODE_ENV. i.e.
// HmrContainer.js
export default (process.env.NODE_ENV === 'development')
  ? require('react-hot-loader').AppContainer // eslint-disable-line
  : ({ children }) => (children);

to be used like:
// client-entry.js
const App = (
  <HmrContainer>
    <Root />
  </HmrContainer>
);

if (module.hot) {
module.hot.accept('./App', () => {
const NewApp = require('./App').default;
render();
});
}
we must require App first, and then render newApp component, otherwise it will not work

can we merge green?
or upgrade to react-hot-loader 4?

What is going on here?...

Or close :)


Run Zero123 under 13GB RAM

Trying to run zero123 on Colab free tier fails because loading the model uses up all 12.7GB of RAM and crashes. Using some techniques to avoid loading the full model into RAM on the way to the GPU will unlock broader use of this exciting model.

Hi, @generatorman. We are actively addressing this issue, and you can refer to this pull request for more details.  You can also consider reducing the num_ray_samples to 256 and downsampling the resolution of images by adjusting the width and height parameters.

Thank you for the response. The PR you linked to seems related to VRAM usage - the issue I'm facing is with RAM. For example, running the following command quickly uses up 13GB of RAM and crashes, without using any VRAM at all.
!python launch.py --config configs/zero123.yaml --train --gpu 0 system.renderer.num_samples_per_ray=256 data.width=64 data.height=64
So currently it's bottlenecked by RAM usage rather than VRAM usage. Is there any quick fix I could apply?

I think loading the zero123 guidance model requires lots of RAM. To address this, you could consider modify torch.load(..., map_location='cpu') command to torch.load(..., map_location='cuda:0), which could potentially alleviate the memory consumption. Another alternative solution is to load an fp16 model instead of an fp32 model.

@generatorman Honestly, you're going to need plenty of RAM and VRAM to run this kind of model. It's inevitable at this stage. Over time the efficiency of the code will probably improve, but for now, you need a good GPU and a powerful system.
I recommend we close this issue for now.

Any idea what the minimum model would be required?

24GB is not enough, I run it on nvidia A10, it failed as OOM:
return self._call_impl(*args, **kwargs)
File "/home/dreamer/.local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/dreamer/.local/lib/python3.10/site-packages/torch/nn/modules/conv.py", line 460, in forward
return self._conv_forward(input, self.weight, self.bias)
File "/home/dreamer/.local/lib/python3.10/site-packages/torch/nn/modules/conv.py", line 456, in _conv_forward
return F.conv2d(input, weight, bias, self.stride,
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 96.00 MiB. GPU 0 has a total capacty of 22.02 GiB of which 85.19 MiB is free. Process 22828 has 21.93 GiB memory in use. Of the allocated memory 19.16 GiB is allocated by PyTorch, and 299.45 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

It seems 40GB VRAM is enough. I run it on A100 40G successfully.
 | Name       | Type                          | Params
-------------------------------------------------------------
0 | geometry   | ImplicitVolume                | 12.6 M
1 | material   | DiffuseWithPointLightMaterial | 0
2 | background | SolidColorBackground          | 0
3 | renderer   | NeRFVolumeRenderer            | 0
-------------------------------------------------------------
12.6 M    Trainable params
0         Non-trainable params
12.6 M    Total params
50.450    Total estimated model params size (MB)
[INFO] Validation results will be saved to outputs/zero123/[64, 128, 256]_1_clipdrop-background-removal.png_prog0@20231028-091058/save
[INFO] Loading Zero123 ...
LatentDiffusion: Running in eps-prediction mode
DiffusionWrapper has 859.53 M params.
Keeping EMAs of 688.
making attention of type 'vanilla' with 512 in_channels
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
making attention of type 'vanilla' with 512 in_channels
100%|███████████████████████████████████████| 890M/890M [00:56<00:00, 16.6MiB/s]
[INFO] Loaded Zero123!
/home/dreamer/.local/lib/python3.10/site-packages/pytorch_lightning/trainer/connectors/data_connector.py:441: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.
/home/dreamer/.local/lib/python3.10/site-packages/pytorch_lightning/trainer/connectors/data_connector.py:441: The 'val_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=11` in the `DataLoader` to improve performance.
Epoch 0: |                                                        | 174/? [01:52<00:00,  1.55it/s, train/loss=12.50]Epoch 0: |                                                        | 175/? [01:52<00:00,  1.55it/s, train/loss=11.20]Epoch 0: |                                                        | 200/? [02:10<00:00,  1.53it/s, train/loss=11.20]

@davideuler I wondered if the peak of the VRAM varied a lot when you ran the code. I am using A6000 48G VRAM and running into the OOM at step 400 or so.
RuntimeError: /tmp/pip-req-build-zhms_45x/include/tiny-cuda-nn/gpu_memory.h:584 cuMemCreate(&m_handles.back(), n_bytes_to_allocate, &prop, 0) failed: CUDA_ERROR_OUT_OF_MEMORY
Epoch 0: |          | 415/? [03:30<00:00,  1.97it/s, train/loss=15.70]


Serialize vars early to avoid living references

Since we added the recursive option for the EventScrubber in #2755, vars nested inside could be replaced with AnnotatedValue and potentially break userland code.
We really shouldn't be holding references to frame.f_locals throughout our SDK, this has all sorts of breakage potential.
This is a bit hacky, but we'll simply call serialize early on vars. I tried patching deepcopy in #3392  to work with our requirements, but I was simply reimplementing most of this serialize function.
Turns out @sentrivana did the same in #2117

hmm @philipstarkey I see, that's a valid concern.
So the reason I looked at this again was because of a report where we patch the original f_locals and actually potentially break user code. We should generally not be holding the original variable references for longer than necessary.
Further, the scrubber was meant to be a simpler before_send with a simple denylist so that people can remove some vars by name easily from the event payload.
I'm going to go ahead with merging this PR, but at the same time I will expose another before_serialize_vars (naming TBD) that you can hook into to do precisely what you want in a separate PR.

@sl0thentr0py Thanks! I appreciate the consideration. I've only had a very cursory look at the serialization code but it occurred to me that being able to provide a custom implementation for safe_repr (or rather, being able to customise the function that safe_repr calls so it's not just repr()) might also address my concern? It has a very clear interface (get object, return a string representation of the object) so it feels like something that could easily pluggable by end-users such as myself.

@philipstarkey we actually already have that but we haven't documented it openly since it's a footgun. You can set __sentry_repr__ on your class and we will pick it up.
https://github.com/getsentry/sentry-python/blob/bd67ea47586fb066def5dc4cd0ba10597ad37624/sentry_sdk/serializer.py#L271
Could you try that and let me know if it works for you?

@sl0thentr0py I did happen to see that actually! It's where I got the idea from 🙂 Unfortunately __sentry_repr__ doesn't quite do what we want because:

we can't easily set this on objects we don't control (numpy arrays, pandas data frames, and Django QuerySets come to mind)
most importantly we'd like something that would fail closed on unknown object types

Now that this is merged I'd also be happy to continue the conversation in a new issue if you'd like.

aha okay, so we have 2 options, both of which I'm fine with, so I'll let you choose which one you prefer:

A before_serialize_vars hook
A custom repr function that will be tried in safe_repr first
I assume you prefer the latter?

@sl0thentr0py Thanks, yes, I think we prefer option 2 - the option for a custom repr function to be tried in safe_repr (my current understanding of how everything works is that this will both solve our needs and reduce the likelihood of this bug to creeping back in).
Thanks for giving us the choice 🙂


Can we remove the fedora.33-x64 intermediate artifacts?

Why do we have fedora.33-x64 intermediate artifacts?
The previously source-built artifacts tarball contains some RID-specific artifacts:
$ find -iname '*intermediate*nupkg' -exec du -hs {} \; | sort -hr | grep fedora
366M    ./Microsoft.SourceBuild.Intermediate.runtime.runtime.fedora.33-x<IP_ADDRESS>-rc.2.21459.6.nupkg
358M    ./Microsoft.SourceBuild.Intermediate.runtime.Crossgen2Pack.fedora.33-x<IP_ADDRESS>-rc.2.21459.6.nupkg
320M    ./Microsoft.SourceBuild.Intermediate.runtime.fedora.33-x<IP_ADDRESS>-rc.2.21459.6.nupkg

These seem like they would have very limited use. They wouldn't be used on Fedora 34, nor on RHEL, nor on any other Linux distribution. Even Fedora 33 would fall back to linux-x64, right? They have a really large footprint too, around 1GB. Does it really make sense to keep them in the "main" Private.SourceBuilt.Artifacts.0.1.0-6.0.100-bootstrap.17.tar.gz tarball?

I tried it out and it removal doesn't seem to make any differences, as far as I can see.

General overview:
When building the product tarball, intermediate packages are included in the resulting archive. The packages themselves also contain unnecessary (from the product build's perspective) tarballs inside, bloating the end tarball's size by a couple of Gbs.
Proposed solution:
Based on existing limitations (ex.: handling rid-specific tarballs), the go-to solution is to limit intermediate package usage to repo builds and exclude them from the tarball builds. The later should utilize package feeds to circumvent not having required source-built packages in local Nuget cache.
Actions to take:

condition out the logic for retrieving and restoring intermediate packages to local Nuget cache;
verify resulting changes by building and comparing the product's tarball;
use the tarball from the previous action to build the product again (using n-1 version to build version n). The product's ability to build itself using source-built n-1 should be confirmed first.

Regarding the Actions to take, the logic which create the artifacts tarball will need to be updated to exclude all intermediate NuGet packages.

Validating these changes is currently blocked by https://github.com/dotnet/installer/pull/14089.  There are some patches required to update the artifacts in addition to a new dotnet toolset is required.


Cannot see deposited items from a user

When clicking on Works created from a user's profile page, the search returns empty results. For example, go to https://scholarsphere.psu.edu/users/amm81 and click Works created. You don't see the two works. If you edit the search term to be amm81 and not "amm81" (without the quotes), the search will work.
This likely affects the user's dashboard, as well as the collections created links in the dashboard and user's profile page.

Duplicate of #1398?


fix: crash on auth config missing

Prevent from crashing application when config is missing.
Enforce users to handle this error case.
Progress

[x] Lazy init instance
[x] Unit tests

@aidenkeating Happy to document some of this if this is not planned in near future.

@wtrocki 👀