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

live bindings #10

Open
cztomsik opened this issue Dec 13, 2018 · 6 comments
Open

live bindings #10

cztomsik opened this issue Dec 13, 2018 · 6 comments

Comments

@cztomsik
Copy link

In webpack this would work:

import App from './App'
import { render } from ...

const nativeNode = ...

const renderApp = () => render(<App />, nativeNode)

if (module.hot) {
  module.hot.accept('./App', renderApp)
}

It probably works because webpack actually transpiles everything and so if module is replaced, it's really visible everywhere then.

I don't know if this was intentional but it doesn't work currently with your module (which I find really great, thx).

Would you want to support such thing? I could help, I know I could easily do this for anything that is already transpiled (babel, typescript), because those are live bindings already and all we need is just to monkey-patch original esModule

On the other hand I don't know if it would work with .mjs files at all, transpilation or proxies are needed for such functionality and I don't think node is transpiling anything with .mjs files.
But it could be known issue, which can easily be fixed with esm loader, which does transpilation and so there are live-bindings again and we can monkey-patch.

Do you want me to do this?

BTW: here's something on live bindings if anyone is reading this and is not familiar with the concept
http://2ality.com/2015/07/es6-module-exports.html

@sidorares
Copy link
Owner

I started looking at esm hot reloading (with built in node esm modules or via esm package) and looks like it would have completely different implementation (if possible at all)

Scope of this module is allowing hot reload without any bundle/transpilation steps so might be not easy

Any help would really appreciated!

@cztomsik
Copy link
Author

I can give it a try but it's more about if you want it to monkey-patch original esModule or not. Webpack does this (App !== oldApp after replacement). I don't know if this was your intentional decision (less magic) or if it should be fixed so it's compatible.

@sidorares
Copy link
Owner

Not sure I follow. Here after replacement newModule !== oldModule as well

@cztomsik
Copy link
Author

This only works with webpack:

import * as React from 'react'
import { Window } from 'node-webrender'
import { render } from 'node-webrender/src/react'
import { App } from './App'

const w = new Window("Hello", 400, 500)

const renderRoot = () =>
  render(<App />, w)

if ('hot' in module) {
  (module as any).hot.accept('./App', () => {
    renderRoot()
  })
}

renderRoot()

To make it work with your module I had to do it this way:

import * as React from 'react'
import { Window } from 'node-webrender'
import { render } from 'node-webrender/src/react'
import { App } from './App'

const w = new Window("Hello", 400, 500)

let Root = App

const renderRoot = () =>
  render(<Root />, w)

if ('hot' in module) {
  (module as any).hot.accept('./App', () => {
    Root = require('./App').App
    renderRoot()
  })
}

renderRoot()

@sidorares
Copy link
Owner

I don't see an easy way to support that. Also it's easy to break:

import * as React from 'react'
import { Window } from 'node-webrender'
import { render } from 'node-webrender/src/react'
import { App } from './App'

const w = new Window("Hello", 400, 500)
const App2 = App;

const renderRoot = () =>
  render(<App2  />, w) // after update App2 points to old

if ('hot' in module) {
  (module as any).hot.accept('./App', () => {
    renderRoot()
  })
}

renderRoot()

@kireerik
Copy link
Contributor

I think I was experiencing something similar with deep objects.

Example:

data.json

{"value": {"nestedValue": "false"}}
var json = require('./data')

console.log(json) // {"value": {"nestedValue": "false"}}

json.value.nestedValue = true

console.log(json.value.nestedValue) // true, but consistently false after the first update

As a workaround I am creating a deep copy of the original object like this:

var json = JSON.parse(JSON.stringify(require('./data')))

console.log(json) // {"value": {"nestedValue": "false"}}

json.value.nestedValue = true

console.log(json.value.nestedValue) // always true

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