-
Notifications
You must be signed in to change notification settings - Fork 2k
Codemods: Add assign-component-to-displayname-variable codemod #18710
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
Conversation
2064c29
to
2e315cc
Compare
b9ee467
to
2e315cc
Compare
const calleeNameValue = node.get( 'declaration', 'callee', 'name' ).value | ||
|
||
if ( ! calleeNameValue ) { | ||
throw new Error( 'return early, no immediate function call' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing errors looks pretty awful so I tried console.log
which looks pretty nasty too - is it worth having anything here at all or better just to allow this to fail silently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give an example of what calleeNameValue
represents? It doesn't seem to be like the lack of it should be an error. Usually if a codemod doesn't need to modify a file then it just returns the original file.source
unmodified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calleeNameValue
Would be localize( ... )
or any other wrapping function.
I'd seen errors been thrown in (IIRC) some react codemod. I think it makes most sense to just return early without making any noise, then as you say, return the original / don't call .replaceWith
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, error should mean that there is something really wrong. like an issue with the source file, or an unexpected edge case (multiple default exports). Standard noop flow can be silent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm feeling that too, I'll squish out those errors/logs and just have it return early :)
@spen: something I've found helpful when working on codemods is to open a second branch that runs the codemod on the entire The diff there should show exactly how this codemod works + what its transformation looks like. When I tried running this on |
2e315cc
to
136ab5b
Compare
Thanks for taking a look @samouri - that is weird though, I'm finding that 100+ files are changed... It might just be that I've not force pushed after rebasing (since the i18n codemod was run). Before that was run this was more a preemptive move :) |
Also, I've just pushed after a rebase with master - if you have time would you mind trying to run over client once more?
|
? j.identifier( displayName ) | ||
: arg.value; | ||
|
||
const exportDefaultDeclarations = root |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
This should always return either 0 or 1 result. We could return early in the case of 0 and not have to write the rest in terms of a loop with:
const defaultExportDeclaration = _.head(
root.find( j.ExportDefaultDeclaration )
);
if ( ! defaultExportDeclaration ) {
root.toSource(); // not sure if this line is correct
}
// continue rest without for loop
const calleeNameValue = node.get( 'declaration', 'callee', 'name' ).value;
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do kind of agree, though a .forEach over a 0 length array would surely be inconsequential, nothing would be run right?
I did originally have this early return in place but figured it'd actually be safer to run in a forEach.
Happy to refactor though :)
136ab5b
to
66c5307
Compare
return exportDefaultDeclarations.toSource( { | ||
useTabs: true, | ||
} ); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i might be wrong, but I think this whole file is currently being indented with spaces instead of tabs.
can we change it to tabs instead? (and if you want autoformatting feel free to prepend the file with: /** @format */
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! Bit of an oversight on my part! All fixed up now thanks to prettier :)
66c5307
to
451a252
Compare
451a252
to
eb212b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the test files and merge away!
* refactor * args --> hocArgs * return no file
c3e1874
to
4c86d68
Compare
Summary
This codemod aims to fix up instances where a component is directly wrapped by a HoC and exported.
It tackles the same issue that #18390 aims to fix, but retrospectively.
The Problem
Wrapping a
.createClass
orclass extends Component
instance inlocalize
is a bit of an ugly pattern and likely encourages folks towards thec( b ( a( Component ) ) )
pattern for enhancing components - either directly or indirectly through some flavour of the following, where enhancements end up scattered:I've seen a couple of instance like the above, but by their nature they're pretty hard to search for.
Also, when we export
localize( React.createClass() );
we lose the ability to shallow render the component in unit tests and make access to the base component trickier.Testing
I've added some test files to show the effects of this codemod. If we decide to proceed with this codemod I'll remove them (or replace with actual 'expected vs actual' type testing.
Run the following to see these effects:
Notes:
I've written this codemod with flexibility in mind. Though the focus was to fix cases of
localize( class extends...
it will pick out components from any arbitrary HoC or function call. Since the component isn't necessarily the first and only argument of such a HoC or function call it also maintains the argument order when substituting the component with a variable name.