React Hotloading in native Meteor is ready (i.e. no webpack)

Thanks, @benjamn!

Yes, please do share your thoughts. I had planned to discuss the way forward with you after a 1.3.0 final came, once things have calmed down a bit. If you’d like to do so before, let me know your preferred medium (we could open an issue on meteor/meteor to track the various subissues involved, etc).

As per the README, this current solution is “hacky by design” (which has been quite liberating). It’s also not a full HMR implementation, but just the bare minimum needed for the react hotloading to work. However, if you’d like this to serve as the basis for something official, I can gradually move to something more structured where possible (e.g. full HMR runtime on the client, with tests, etc; modifying the build process in the “right way” might be beyond me though).

Will reply to the other github issues directly.

2 Likes

Hope people have been enjoying this! Unfortunately since I’m using pre-release version numbering I can’t track downloads on Atmosphere.

I’ll also be a bit more pro-active at announcing version updates here, since a few annoying things got fixed recently. The current version is gadicc:ecmascript-hot@v0.0.3-modules.7 and you can see the changelog in the 2nd post of this thread or on github.

The two most important recent changes are better module resolution (we didn’t support root and some relative paths until now), and an automatic full client refresh for cases we can’t handle (so no need to manually restart Meteor, which was annoying). You can also trigger this by hand by just typing hot.reload() in the console now, if desired.

Top priority moving forward is better recognition of stateless components, and cases where hotloads fail when they shouldn’t (and we need your help here to report them). A longer term goal is to provide full HMR support (not just for react), which will allow redux and other hotloading too.

But most important is feedback. Is this working well for you? When isn’t it? Reporting issues on github is the only way annoying things will get fixed.

P.S. I’m away for a few days again and am travelling after, but I’ll find time to squeeze in small fixes here and there.

6 Likes

Hi there. On this point:

Edit your .meteor/packages and replace ecmascript with gadicc:ecmascript-hot@0.0.2-modules.7 (don’t forget to set it back before a production deploy!)

How do you propose handling that if we’re using the Atmosphere package? Must we “meteor remove gadicc:hot” before doing our Mup deploys?

I imagine you’d just toggle the comment on both lines no?

//.meteor/packages
#ecmascript
gadicc:ecmascript-hot@0.0.3-modules.7
1 Like

@jasongrishkoff, yeah sorry, you no longer need gadicc:hotin your .meteor/packages file. Since the Atmosphere release, gadicc:ecmascript-hot implies gadicc:hot too, to make for a super simple replacement.

I too recommend just toggling the comments like @mordrax suggested, before deploy. If you prefer using the meteor CLI, that’s fine too, but then you should also meteor add ecmascript after removing ecmascript-hot. Hopefully in the future we can come up with a good way to avoid the need for this.

Last note, looks like I didn’t update the README properly, the current latest version is indeed 0.0.3.

I have not tested it so I don’t know if it works but maybe you could use a condition on process.env.NODE_ENV on the gadicc:ecmascript-hot package.js file?

Package.onUse(function (api) {
  api.versionsFrom('1.3-modules-beta.7');

  if (process.env.NODE_ENV === 'production') {
    api.imply('ecmascript');
  } else {
    // current code: `imply`, `addFiles`, `export`...
  }
});

Hum unfortunately process.env.NODE_ENV is undefined in package.js. Is that on purpose @benjamn?

I think it is. Meteor relies on package.js to build the package to be published, making conditional logic problematic. I know we used tricks like this often in the past but as far as I know package bundling is handled differently for a while now.

Had to interrupt my flow and share this. (tl;dr - This package is the sh!ts, why are you not using it already in 1.3?)

So I was doing some massive refactoring because due to some brain-spasm, I had introduced ES6 classes into my redux state which was causing all sorts of refresh issues as I modified internal properties.

JS being the unfriendly, untyped monster it was caused everything to break left right and center as I jiggled around my states to normalize them, reordered my reducers, removed classes etc etc… My chrome dev console was throwing errors, Max stack limit reached, cannot hot reload x.js and others. But I persevered knowing that my goal was within sight.

Lastly, I came to hooking up the init state so I could test by hitting any route on a refresh:

  let areas = generateAreas();
  cotwStore.dispatch({type: "INIT_AREAS", areas});

The moment I typed the last ;, hit <enter> and Ctrl+S, my browser which had constantly been blank and flashing errors in the console suddenly sprang into life and my game map was BACK!

I lost the plot.

The workflow with hotloading has been amazing. It almost instantly refreshes react component changes and also does a full refresh on all other file changes. I don’t know why but a full refresh with hot loading is also faster, taking on average ~2sec with the error appearing in the console.

Normally, I’d be waiting 5-10 secs for meteor to build on each compile/debug/test loop.

Adoration over, back to coding…

2 Likes

After following install instructions I get:

W20160218-15:34:03.513(-8)? (STDERR)
W20160218-15:34:03.514(-8)? (STDERR) /Users/dpnewman/.meteor/packages/meteor-tool/.1.1.13-modules.7.ip1bjg++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:245
W20160218-15:34:03.515(-8)? (STDERR)            				throw(ex);
W20160218-15:34:03.515(-8)? (STDERR)            				      ^
W20160218-15:34:03.602(-8)? (STDERR) Error: locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr
W20160218-15:34:03.602(-8)? (STDERR)     at proxyReactComponents (/Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/packages/modules.js:21750:11)
W20160218-15:34:03.602(-8)? (STDERR)     at meteorInstall.both.lib.authorizeForRole.jsx (/Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/app/app.js:59:59)
W20160218-15:34:03.603(-8)? (STDERR)     at fileEvaluate (/Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/packages/modules-runtime.js:219:9)
W20160218-15:34:03.603(-8)? (STDERR)     at require (/Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/packages/modules-runtime.js:92:20)
W20160218-15:34:03.603(-8)? (STDERR)     at /Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/app/app.js:12405:1
W20160218-15:34:03.603(-8)? (STDERR)     at /Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/boot.js:242:10
W20160218-15:34:03.603(-8)? (STDERR)     at Array.forEach (native)
W20160218-15:34:03.603(-8)? (STDERR)     at Function._.each._.forEach (/Users/dpnewman/.meteor/packages/meteor-tool/.1.1.13-modules.7.ip1bjg++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/underscore/underscore.js:79:11)
W20160218-15:34:03.603(-8)? (STDERR)     at /Users/dpnewman/Meteor/haven-app/.meteor/local/build/programs/server/boot.js:137:5
=> Exited with code: 8

@mordrax, thanks for the awesome feedback! Exactly what I’m looking for.

@spherop, @all - I’m overseas atm but will take a look at any new issues and also support for the latest 1.3 beta as soon as I have a chance. @spherop, can you confirm you’re using beta.7 and whether or not you have your own .babelrc (which I don’t think works in beta.7 anyways).

@gadicc I do indeed have beta 7. i am gonna try a more vanilla project and add some things in assuming something is conflicting. will report back.
EDIT: do not have my own .babelrc

I don’t see any .babelrc in my dir either, should I be worried? And I didn’t encounter the error you had. My install was relatively pain free. I had to change my pure components a bit to fit the exact requirements for hot-reloading to pick it up.
Doing hot.reload() in the browser is also useful for the cases when the package doesn’t detect the change or on occasions where it is loading stale code.

In other news, component debugging is really nice:

Code was throwing Uncaught TypeError on a drag/drop. Jumped to shopComponent.jsx and fixed it.
Hot reload kicked in, took less time than it took to move the mouse to the browser window for a re-test. (500ms?)

Console shows should add undefined to General Store, damn, forgot I had moved the name into a base object, fixed again. Patched again.

Test drag/drop, should add Gauntlet of Dexterity to General Store, wohoo!
Total debug time (10 secs), Total time spent winning (9 secs) :smiley:

1 Like

Hey all. I’m away at the moment with very limited PC time, but for the impatient, gadicc:ecmascript-hot@0.0.4-beta.11 should work with beta.11. It’s not well tested. Maybe existing users can report here if the upgrade is smooth for them.

4 Likes

@gadicc Thanks for updating…

1 Like

@mordrax, happy things are working so well! I think it will be even nicer when I have a chance to implement the pretty error catching. Feel free to open some issues on github for cases where you need to manually reload; we can assess if it’s stuff we might be able to better detect.

@all, had a bit more time to play around with the beta.11 support, happy to report it seems to be working great! I’m finding this works pretty well for daily use now and would love feedback on any weak areas.

1 Like

@gadicc, I’ve been working with this for the last couple of days now and have come across some issues which I’m not sure if it’s just hotloading or chrome devtools or something else.

  1. Code not refreshing - So because there is an issue with meteor source maps on chrome (sometimes), I’ve resorted to putting in debugger; statements for breakpoints. When it hits a debugger and I remove the debugger, hotloading will do a complete refresh but hit the debugger; that I removed because the code hasn’t updated.

  2. Replays error - If there is a clientside error with the code, it seems to reapply all the hotloading patches up to the error. And on the refresh, due to the first issue, I’m not sure if it’s the new code or the old code that’s failing sometimes. This could just be the first issue in disguise.

  3. Multiple refreshes - I’ve noticed this from the beginning. Sometimes when I make a single change, it makes multiple refreshes.

These issues only seem to happen on a hot.reload() either when I manually kick it off (the package fails to detect the change in my connect or ReactDnD component) or when it does it automatically.

The most worrying thing here is that I can’t be sure the code has been refreshed so sometimes I have resorted to restarting meteor. Other ways I’ve been tackling this is to log verbosely rather than use debugger and when the source map decides to work then I can do breakpoints.

These are very vague feedback, I’m working with it daily and will try to get you some reproduceable steps. Thought I’d just share to see if anyone else has these issues.

New release: gadicc:ecmascript-hot@0.0.5-beta.11

First release using a new strategy which seems to be a lot more reliable. I’m finally back from my trip, so will get out a release for Meteor 1.3-beta.12 in the next few days, just need some feedback on how the new strategy is working in different scenarios. Note: no more hot.reload() - just refresh the page as usual for a complete reload!

@mordrax, I think this release should solve all the kinds of issues you mentioned, let me know. Btw, I didn’t bother with source maps for hot replaced modules… if you need it, just ctrl-R, otherwise your debugger will take you to the code inside the hot.js we send across on updates (except now these won’t accumulate).

2 Likes

Actually :slightly_smiling:

New release: gadicc:ecmascript-hot@0.0.5-beta.12.

For Meteor 1.3-beta.12.

5 Likes

New release: gadicc:ecmascript-hot@0.0.7-beta.12

Best and most reliable HCP blocking strategy to date. We now, only, block a single HCP after a single (successful) HMR. Everything else comes through (CSS, new files, etc). Most reliable method to date. Probably no more work required here, and future work will focus on allowing HMR for other things (redux, etc). This release is also more flexible on functional components.

5 Likes