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
RHL throwing ReferenceErrors when hot-reloading third-party hooks. #1268
Comments
Got the point, and I know that's the problem. |
I recon this is related to facebook/react#15883, backporting to RHL... |
v.4.11.1 released. Containing fixes both for your problem and |
Thank you for pouncing on this so quickly! (And, incidentally, for the honor of adding that little code snippet to the official examples. ✨) I gave the updated version a shot, and the results were mixed: upgrading did not help with my issue, but I had misdiagnosed it anyway; once I landed on the actual problem, the fix was straightforward. The bug is indeed triggered when reloading a module with hooks---but only if Babel's CommonJS transform is enabled. Builds that allow My immediate error, for what little it's worth, was fat-fingering my module.exports = api => {
- const isWebpackBuild = api.caller(caller => !!(caller && caller.name === 'babel-webpack'))
+ const isWebpackBuild = api.caller(caller => !!(caller && caller.name === 'babel-loader'))
return {
presets: [
['@babel/env', {
modules: isWebpackBuild ? false : 'commonjs',
}],
],
}
} Given how rare it is to see folks preferring Babel's modules to Webpack's at this point, this doesn't seem especially pressing, at least from where I sit. So unless a fix springs to mind immediately, I'd be happy to dig into RHL's recent evolution and see whether I can make any headway. I'm sure it'd take a minute to get caught up, but reading this code has always been a learning experience. |
Ok, not the problem is more clear, and thank you for the simple way to cause it. |
I've tried babel 6 and babel 7 both unit tests and examples, with different module values. It always works. |
You're right... I can reproduce, but not consistently. I must have stumbled over some kind of incompatibility, but it's not as simple as activating CommonJS. I'll keep prodding and narrow it down. |
I'm hitting the same problem, with v4.11.1, using Parcel (TypeScript + Babel). |
The problem is understandable - two transforms are fighting with each other, but I am not sure how to fix it, as long as the best known solution was already applied. |
I dug into the problem, and I think I have an idea what's going on, and a potential fix. The reason plugin-transform-modules-commonjs isn't rewriting both occurrences of the custom hook identifier ( A solution is to change this line react-hot-loader/src/fresh/babel.js Line 205 in 70353e5
I haven't written a lot of Babel plugins or anything, but I think a deep clone is appropriate, because |
I think the better way would be to remove checks after, as long as the tree is mutating in an exclusive way, and no other plugins could interfere, ie @gaearon - you should have this problem as well. |
@theKashey we might be not understanding each other. The code that thinks it has already seen the node is not part of react-hot-loader, it is in Babel: https://github.com/babel/babel/blob/1d3f9815df747902ae535706f032081bc4825b87/packages/babel-helper-module-transforms/src/rewrite-live-references.js#L169 To give an example of the problem, if you imagine a transform that turns this:
into this:
then it seems important that the newly inserted
... which is clearly wrong. Babel is not expecting the same node at two different paths. |
@dgreensp - You are right, I got your message not correctly, and understand what did you mean only later. I've tried to create any red test, using a simple repetition like you proposed, but failed - always working for me. |
Ie - we could fix in a way you proposed, but how to verify? |
Hmm, what are the current tests relevant to the babel plugin? The test that's needed is basically that the react-hot-loader babel plugin composes correctly with the import/export plugin in the case of custom hooks. Specifically, a custom hook imported from another module. |
@dgreensp - see the commit ^above^. Unfortunately, the snapshot is always correct. However - that's also not bad - we could just shit fix and hope that it would help. |
I'll take a look and see if I can understand why it is passing. Maybe a different plugin order or something. |
@phyllisstein example is also always working for me. Could it be the case that you both have some unlucky package cached (should not be possible with yarn.lock, but 🤷♂️) |
I cloned the repo and am trying to run the tests. I'm currently stuck on a failure just running the tests as-is on master: |
Never mind, I ran |
Ok, the reason the tests aren't failing is because Babel 6 has different transformation code from Babel 6. The relevant Babel 6 code is here: https://github.com/babel/babel/blob/ffcd8d85e4bdc271a0390596f88a33e2218e5925/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js#L54 . It doesn't mind transforming two nodes that are Is there a way to add Babel 7 tests? Note also:
|
Now trying to run an example that uses Babel 7. The instructions to run |
I've reproduced the problem by modifying an example app. None of the example apps quite have a suitable config as-is, because to run into the problem you need a combination of:
This is mostly just a matter of using the latest and greatest stuff; none of these elements are unusual, of course. I've made some modifications to the Parcel example to reproduce the problem. Let's see if I can get it on a branch or something for ease of collaboration. |
Ok, here is a repro: master...dgreensp:repro-hook-issue . This is all I have time to do for today, probably. When messing with With these changes, just saving the file Anyway, I think the easiest way to test for it is to have the tests run Babel 7 (somehow, ideally in addition to 6) and confirm that the output is transformed correctly. |
I created a PR for the repro in case that makes it easier to check out. |
🪨 |
|
fix: clone node for signature, fixes #1268
v4.11.2, or, better, v4.12 should solve the problem |
Thanks for connecting the dots here and coming up with a patch! |
😅 look like the fix was not properly released :) |
Description
👋 Hey folks! I'm having a little trouble with RHL's hooks support in a little Gatsby project. RHL seems to be injecting code that evaluates the imported hook functions using their reference names in the source code. But since the imports have been transformed by Babel and/or Webpack, there's nothing in scope that matches. React's built-in hooks do not seem to be affected.
By way of a contrived example, here's a silly SFC that uses react-spring:
I dropped the transpiled code into this gist; the relevant hunks seem to be line 22:
...lines 42--44:
...and line 63:
The component uses the transpiled reference as expected, but RHL doesn't seem to know about it. When a hot update is triggered, it throws a
ReferenceError
:Stack trace 💥
I'm willing to believe this is an issue with Gatsby's configuration patterns or my particular abuses of Gatsby's configuration patterns, so I'm working on putting together a lightweight reproduction case. But I wanted to run it by you folks in the meantime to see whether there were any known issues that may be germane.
Let me know if I can do anything to add more color to the problem or help out with a solution! Thanks so much for your insight. ✨
Expected behavior
RHL should invoke hooks with their transpiled references, so as to avoid throwing
ReferenceError
s.Actual behavior
RHL attempts to invoke hooks using their untranspiled references, which are never in scope and throw
ReferenceError
s.Environment
React Hot Loader version:
v4.11.0
Run these commands in the project folder and fill in their results:
node -v
:v12.4.0
npm -v
:v6.9.0
yarn -v
':v1.16.0
Then, specify:
Reproducible Demo
🚧 So far just the gist, but I'm working on it!
The text was updated successfully, but these errors were encountered: