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
transform-react-constant-elements => Element type is invalid #5149
Comments
Hey @slorber! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
Please don't ping random people, that won't make the resolution of the problem faster. |
@danez these are not random people but people that previously contributed to this plugin or had discussed useful informations about it. About issue resolution I'm pinging people to know the right thing to do, and will likely make a PR if I am able to, based on feedback of pinged people. |
Thanks @slorber, will take a look at this; seems like another issue with Hoister bindings. |
Can confirm the following erroneous output: import React from "react";
const HOC = component => component;
var _ref = <div className="parent">
<Child />
</div>;
const Parent = ({}) => _ref;
export default Parent;
var _ref2 = <div className="child">
ChildTextContent
</div>;
let Child = () => _ref2;
Child = HOC(Child); Note |
This seems related to #3596, which prevented from hoisting to scopes where a binding hasn't been evaluated yet, but it did not seem to be able to handle situations where Program scope is all we have and we just need to reorder. |
Fixes babel#5149 and enables a few additional safe hoists.
Fixes babel#5149 and enables a few additional safe hoists.
thanks @STRML that was fast! Is reordering always possible? I mean there might be cases where people are using cyclic dependencies between the components? I've already done some things like that in my app. This is a dumb question but what's the easiest way for me to test your PR against my app? It seems npm install does not support installing through git subdirectories and babel is a monorepo |
You'd have to check out and build the whole project then copy the package
out.
If you have any patterns you think would break this, could you please post
them so I can get them in the test suite?
…On Jan 19, 2017 3:54 AM, "Sébastien Lorber" ***@***.***> wrote:
thanks @STRML <https://github.com/STRML> that was fast!
Is reordering always possible? I mean there might be cases where people
are using cyclic dependencies between the components? I've already done
some things like that in my app.
This is a dumb question but what's the easiest way for me to test your PR
against my app? It seems npm install does not support installing through
git subdirectories and babel is a monorepo
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#5149 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABJFPyUKllRHnRetSCg2dQLlSvSuQSlCks5rTzLfgaJpZM4LmANX>
.
|
Hi, @STRML it's probably better than before but it still does not work in my app. However it's probably very close to working because simply commenting a single HOC in my app makes it start successfully (didn't try to use it further but the basics are working) I can try to make a simpler repro case, in the meantime here's my raw problematic source file: https://gist.github.com/slorber/c5093d2759815d6235aeb2a4e2fc0e2e Commenting these lines makes my app work: WifiProblem = connect(state => ({
connectionDown: AppCommonStore.connectionDownSelector(state),
}))(WifiProblem); Tell me if you are able to do something or if you want me to look further Note that for legacy reasons we are using a legacy class constructor: |
Fixes babel#5149 and enables a few additional safe hoists.
Did you try the code from the PR? I have compiled your repro and it seems fine, unless I'm missing something in the noise. |
@STRML yes that's what I explain in my previous comment: I have tested your PR and I am still unable to start my app, due to a single file. I've posted a gist to this file unmodified so that you might be able to see where the problem come from. If you want I can try to get a smaller repro case |
Maybe I've not tested correctly, I'll try again because your output seems fine. I'll see if I get the same output as you do. |
@STRML I've just pasted your babel output to my app and it seems to work, so it's probably my test that was not good. |
Okay; then this is okay to mark as fixed by #5153 and let's get it merged. |
If you would, please keep this open until #5153 is merged (as it is not yet fixed in |
so I'm not sure what do you want me to do :) I'll let this open until the PR is merged |
Fixes #5149 and enables a few additional safe hoists.
* Add new flow preset (#5288) * Fix PathHoister hoisting JSX member expressions on "this". (#5143) The PathHoister ignored member references on "this", causing it to potentially hoist an expression above its function scope. This patch tells the hoister to watch for "this", and if seen, mark the nearest non-arrow function scope as the upper limit for hoistng. This fixes #4397 and is an alternative to #4787. * Fix PathHoister hoisting before bindings. (#5153) Fixes #5149 and enables a few additional safe hoists. * Fix linting error * feature: Support pure expressions in transform-react-constant-elements (#4812) * Fix loose for-of with label (#5298) * Rewrite Hub as interface #5047 (#5050) * Rewrite Hub as interface #5047 * Update index.js * Avoid adding unnecessary closure for block scoping (#5246) When you write ``` for (const x of l) { setTimeout(() => x); } ``` we need to add a closure because the variable is meant to be block-scoped and recreated each time the block runs. We do this. However, we also add the closure when no loop is present. This isn't necessary, because if no loop is present then each piece of code runs at most once. I changed the transform to only add a closure if a variable is referenced from within a loop. * Add greenkeeperio-bot to mention-bot blacklist (#5301) [skip ci] * Upgrade lerna to current beta. (#5300) * Revert "Upgrade lerna to current beta." (#5303) * Add charset so tests work with convert-source-map@>1.4 (#5302) * Add CHANGELOG for 6.23.0 [skip ci] (#5304) * Update babel-types README from script. * v6.23.0 * Revert change that lerna force-committed. * Revert "Rewrite Hub as interface #5047" (#5306) * v6.23.1 * Revert lerna again
Fixes #5149 and enables a few additional safe hoists.
After enabling this Babel react optimization I am getting the following error:
If I disable just this plugin it works fine. My current test setup is:
Input Code
Babel Configuration (.babelrc, package.json, cli command)
Expected Behavior
It should probably work out of the box, eventually not optimizing things if they are too complicated to optimize, but should not require the user to rewrite his own code (IMO)
Current Behavior
The compiled output looks like that:
You can see that
_ref2
is trying to use the Child component, which is declared after the_ref2
creation.This is due to the HOC usage on the Child component, because comenting the HOC usage produces the following code that works fine:
Unfortunatly I'd like to use an HOC on the child. I think the plugin should support this usecase correctly to avoid users to have to rewrite any code. On large codebase this rewrite would be painful for users, and the React error is not helpful as-is: you have to introspect the stacktrace to find the source of the problem.
Possible Solution
The plugin could bypass the optimization in this usecase, exactly like it's done for when the HOC is used.
I think it makes sense to not optimize in this usecase because the plugin already doesn't optimize when using Child component without the HOC (probably because it's not safe), so I don't see why it would be safer once used through a HOC.
In case this would be safe to optimize, another possible solution is that instead of using static references, the plugin could output memoized functions that return the constant element, so that the constant element initialisation is deferred after app construction.
The output code could look like
As a side note, I would say that generalizing this memorisation technique in the plugin may lead to an app that could be faster on initial load, because only the required constant elements would be constructed on startup. But there would be a performance penalty after initial load due to using a memoized function call. This may be better or not according to the usecase (probably better in large apps that are not using code-splitting) and could be made a plugin option.
The text was updated successfully, but these errors were encountered: