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

Stops live updating on WebPack error. #29

Closed
ronag opened this issue Sep 20, 2014 · 14 comments
Closed

Stops live updating on WebPack error. #29

ronag opened this issue Sep 20, 2014 · 14 comments

Comments

@ronag
Copy link

ronag commented Sep 20, 2014

See: https://github.com/js-next/react-style/issues/51

@ronag
Copy link
Author

ronag commented Sep 20, 2014

From what I've been able to figure out. Given the following code from index.js.

    'if (module.hot) {',
    '  module.hot.accept(function (err) {',
    '    if (err) {',
    '      console.error("Cannot not apply hot update to " + ' + JSON.stringify(filename) + ' + ": " + err.message);',
    '    }',
    '  });',
    '  module.hot.dispose(function () {',
    '    var nextTick = require(' + JSON.stringify(require.resolve('next-tick')) + ');',
    '    nextTick(__hotUpdateAPI.updateMountedInstances);',
    '  });',
    '}'

__hotUpdateAPI.updateMountedInstances is never called after an "Cannot not apply hot update to...".

@ronag
Copy link
Author

ronag commented Sep 20, 2014

This problem only occurs when I get the "Cannot not apply hot update..." error, e.g. Cannot not apply hot update to App.js: kjdfngdskfgjn is not defined. Where kjdfngdskfgjn is just something added to cause an error.

/** @jsx React.DOM */
'use strict';

var React = require('react');

kjdfngdskfgjn / asd

var App = React.createClass({
  render() {
    return (
      <h1>Hello, world!</h1>
    );
  }
});

module.exports = App;

Which only seems to occur for certain types of code errors (e.g. https://github.com/js-next/react-style/issues/51). In other cases errors are simply ignored and the above message is never displayed, e.g. if I remove the </h1> closing tag no error is displayed in the browser window and the problem does not occur.

@ronag
Copy link
Author

ronag commented Sep 20, 2014

I've tried this with

    "webpack": "1.4.1-beta1"
    "webpack-dev-server": "1.6.4"

@ronag ronag changed the title Bug - Stops live updating on WebPack error. Stops live updating on WebPack error. Sep 20, 2014
@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

Have you tried using hot/only-dev-server and NoErrorsPlugin?
Here's the example.

They should solve your problem.
(I plan to include them later in the doc btw.)

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

Ah I see, you're already using them.
Hmm..

@ronag
Copy link
Author

ronag commented Sep 20, 2014

Have you managed to reproduce the issue with the sample?

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

Yes, just did, thanks for the repro.

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

@sokra explains why this happens in this comment.

NoErrorsPlugin will only protect us against compilation errors. However ReferenceError is a runtime JS error. It ruins require and HMR runtime doesn't know what to do.

Now I'm not sure if there is a way for us to gracefully handle this—need to experiment a little bit.

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

I'm not actually sure why HMR can't live with the previous version in this case (if we promise our component definitions don't have side effects). We could of course wrap the whole module in try-catch and cache previous result but if feels hackish.

@ronag
Copy link
Author

ronag commented Sep 20, 2014

It doesn't really have to render anything meaningful (such as the previous version) on an error the important part is that you can fix it and continue working without having to reload.

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

While this could work, I'd prefer fixing this without "injecting ourselves" into the app.
The loader tries to be very unintrusive and I'd like to keep it that way, if possible.

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

Actually it seems like the main problem in this case being the final block (if (module.hot)) not being executed because ReferenceError makes the code die before that.

If I move if (module.hot) before module's actual code, it seems to work.
That is,

  return [
    'var __hotUpdateAPI = (function () {',
    '  var React = require("react");',
    '  var getHotUpdateAPI = require(' + JSON.stringify(require.resolve('./getHotUpdateAPI')) + ');',
    '  return getHotUpdateAPI(React, ' + JSON.stringify(filename) + ', module.id);',
    '})();',
    'if (module.hot) {',
    '  module.hot.accept(function (err) {',
    '    if (err) {',
    '      console.error("Cannot not apply hot update to " + ' + JSON.stringify(filename) + ' + ": " + err.message);',
    '    }',
    '  });',
    '  module.hot.dispose(function () {',
    '    var nextTick = require(' + JSON.stringify(require.resolve('next-tick')) + ');',
    '    nextTick(__hotUpdateAPI.updateMountedInstances);',
    '  });',
    '}',
    processedSource
  ].join('\n');

Can you verify whether this solves your initial problem?

@ronag
Copy link
Author

ronag commented Sep 20, 2014

That seems to have solved it. Good work!

@gaearon
Copy link
Owner

gaearon commented Sep 20, 2014

Thank you for reporting this and specifying the exact repro case.
Released on NPM as react-hot-loader@0.4.4.

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

2 participants