Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: hot reload by overriding exported members? #22

Closed
peteruithoven opened this issue Nov 27, 2015 · 10 comments
Closed

Discussion: hot reload by overriding exported members? #22

peteruithoven opened this issue Nov 27, 2015 · 10 comments

Comments

@peteruithoven
Copy link
Contributor

Like capaj explains in #17 (comment) the hot reloader currently also reloads all modules that use a module that is changed.
But is this really necessary? Could we for example override all exported members (functions / classes) with the members of the new version?
One thing that's probably tricky (if not impossible) are primary variables (numbers, strings etc).
Maybe we could implement "proxy's", like Dan Abramov explains in his talk: https://youtu.be/xsSnOQynTHs

This feature should improve editing stateless functions, like Redux reducers. Since in Redux reducers are used to create the store (state), because they define the initial state of their part, they can't be reloaded without also reloading the state.

@veggiemonk
Copy link

@peteruithoven Exactly what i was thinking when I saw this code:

export default function configureStore(initialState) {
  const store = createStore(rootReducer, initialState)

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers')
      store.replaceReducer(nextReducer)
    })
  }

  return store
}

In the redux library, there is an example todoMVC app that has this code.
I would like to translate from webpack to jspm-hot-reloader. @capaj Do you think it is even possible?

@capaj
Copy link
Collaborator

capaj commented Nov 27, 2015

@veggiemonk I am using jspm-hot-reloader mainly with observables. Yes, I am the devil @gaearon speaks about every time he mentions how bad one mutating state is.
I know redux, I haven't used it extensively but I don't really plan to support it more than other state management solutions.
It would be out of scope of what we are trying to do here. I might be open to support some plugins for this if the api is easy enough.
But if you open a PR I will always be open to discussion.

@peteruithoven
Copy link
Contributor Author

I wasn't suggesting making a exception for Redux, but I was asking whether the hot reloader could hot reload modules with stateless / pure functions without reloading all the modules that use that module.

@veggiemonk
Copy link

same question here.
Other way to ask: How one can override the auto-reloading of all the module in the chain?
It would be like being to set hot reload rules for a few specific files. The main use cases so far is redux but more will follow, i think.

@peteruithoven
Copy link
Contributor Author

I've been thinking about this and read through the hot reloader code. I can't think of a way to override the references to exports of an old module a module has, without having access to that class.

But maybe, just like __unload is called, a __reload function could be called, for example here: https://github.com/capaj/jspm-hot-reloader/blob/master/jspm-hot-reloader.js#L185. (There are other places the original System.import() is called so that's probably not enough).
If we can keep a reference to the deleted version of that module we can pass that to the __reload module, a developer could then get the state from that old module and use that in the reloaded module to restore the state.
I'm not sure what kind of object System._loader.moduleRecords[normalizedName] returns, but there seem to be references to the moduleRecords of deleted modules in the modulesJustDeleted object.

@peteruithoven
Copy link
Contributor Author

@veggiemonk, would that enable that to do what you want?

@veggiemonk
Copy link

@peteruithoven Thank you very much, I will give it try and the idea is quite neat...
I was thinking to approach the issue by saying 'if this file changes, only reload this one'
but now it's more like: 'here is the data to persist across (any) reload' which is much more powerful.

Do you have any idea on:

  • how to extract the store from the old modules ?
  • how to inject the store into the new modules ?

The goal here would be to modify the code of the app as little as possible in order to keep this a dev feature, meaning configurable so no extra dev code is shipped to production

I would love this to be just a parameter object that could be pass from config.js but that would be for the next iteration.

@veggiemonk
Copy link

I found that there are also project that allow this to happen at the application code level (not as good as dev-server level)

https://github.com/AgentME/ud

With a working example by @mijime
https://github.com/mijime/mithril-redux-starter-hmr/blob/master/src/utils/redux-ud/index.js

But that is another, less preferable, approach to letting the server know how to save and inject state from old modules to new ones.

@peteruithoven
Copy link
Contributor Author

I've made a basic example and a probably flawed pull request: #23

@capaj
Copy link
Collaborator

capaj commented Dec 11, 2015

@peteruithoven so this was merged, I am closing this discussion for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants