Components: remove lodash from context/getStyledClassName:#48688
Components: remove lodash from context/getStyledClassName:#48688
context/getStyledClassName:#48688Conversation
| * External dependencies | ||
| */ | ||
| import { kebabCase } from 'lodash'; | ||
| import { paramCase as kebabCase } from 'change-case'; |
There was a problem hiding this comment.
I may be wrong here, but I think some incorrect types might be deceiving us here.
See this usage of getStyledClassNameFromKey():
gutenberg/packages/components/src/ui/context/context-connect.ts
Lines 94 to 106 in 8dee3e6
Seems like namespace could be an array? If that happens, this will crash, while _.kebabCase( [ 'test', 'x' ] ) will work just fine, returning test-x.
This other use of getStyledClassNameFromKey() is in a similar situation like the one I reported here:
Since the namespace is declared by externally exposed API (useContextSystem()), theoretically, the namespace could be test1 and then one of them would yield a test1 class, and the other would yield a test-1 class. That would basically be an unexpected breaking change.
I think to get around this, we need to make sure that the replacement function behaves exactly the same way when mixing letters, numbers and special characters.
There was a problem hiding this comment.
Thanks Marin! I'm currently working through your feedback. Regarding
Seems like namespace could be an array?
namespace is typed as string so if you try to pass an array to contextConnect you'd get a type error. I'm not exactly sure why the guard is still in place, it's probably a leftover from #31099 where the Array<string>|string type was replaced with string. My assumption is we could remove it.
There was a problem hiding this comment.
Sounds good for the array case. I'd suggest we remove it then, so we're intentional with our type approach here. Can be done in a separate PR, but I think it should be done before this one lands.
What do you think about this other difference that I mentioned? Reposting here for clarity:
This other use of
getStyledClassNameFromKey()is in a similar situation like the one I reported here:Since the namespace is declared by externally exposed API (
useContextSystem()), theoretically, the namespace could betest1and then one of them would yield atest1class, and the other would yield atest-1class. That would basically be an unexpected breaking change.I think to get around this, we need to make sure that the replacement function behaves exactly the same way when mixing letters, numbers and special characters.
There was a problem hiding this comment.
Since the namespace is declared by externally exposed API (useContextSystem())
I had a quick look and it doesn't seem that neither getStyledClassNameFromKey nor useContextSystem() are exported by the @wordpress/components package (via the packages/components/src/index.js file).
Maybe @sarayourfriend could help us to clarify any remaining doubts on this, since she worked extensively on the context system?
There was a problem hiding this comment.
I had a quick look and it doesn't seem that neither getStyledClassNameFromKey nor useContextSystem() are exported by the @wordpress/components package (via the packages/components/src/index.js file).
I've manually audited the existing usages and I have no further concern. The use case I've mentioned does not occur, and it won't cause any regressions, so we should be safe to move forward.
The only suggestion I'd have before shipping this one would be removing the unnecessary array handling that we discussed above.
There was a problem hiding this comment.
I started looking into removing the array handling we talked about and found a few more things which might be worth addressing. I'm going to discuss those with @ciampo this week (as I don't fully understand a few parts of the components context system). Could we unblock this PR and make your suggestion a follow up @tyxla?
There was a problem hiding this comment.
Maybe @sarayourfriend could help us to clarify any remaining doubts on this, since she worked extensively on the context system?
Happy to help if I can, but can you clarify what the question is?
There was a problem hiding this comment.
It's mostly about the naming of contexts in useContextSystem() and specifically, treating numbers. It was about whether if we call useContextSystem( 'test-1' ), we should expect to get a className of test-1 or test1.
I realize this might be coming from the original g2 implementation, in which case @sarayourfriend might not have the answer too.
I'm fine with making a decision here though, since useContextSystem() is still internal and uses no numbers in context names just yet. That's why I approved the PR.
There was a problem hiding this comment.
I realize this might be coming from the original g2 implementation, in which case @sarayourfriend might not have the answer too.
Yup, I have no idea what the original intention is.
since useContextSystem() is still internal and uses no numbers in context names just yet
Excellent 😁
ciampo
left a comment
There was a problem hiding this comment.
I started looking into removing the array handling we talked about and found a few more things which might be worth addressing. I'm going to discuss those with @ciampo this week (as I don't fully understand a few parts of the components context system).
After discussing with Markus, we decided to keep the changes in this as lean as possible, in order to unblock further work on the lodash migration.
Markus may open a draft PR with some of his WIP about simplifying the Context System, but we won't realistically get back at it before completing the lodash and the TypeScript migration. After that, we will take a moment to assess the Context APIs, and decide the next steps (are these APIs really useful? Should we therefore use them more, or should we instead remove them entirely? If we keep them, what code optimisations can we apply?)
5dd0e3b to
d94976c
Compare
|
Flaky tests detected in d94976c. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4426740940
|
What?
This PR removes Lodash's
_.kebabCase()from thegetStyledClassNamefunction used in ui/context.Why?
Lodash is known to unnecessarily inflate the bundle size of packages, and in most cases, it can be replaced with native language functionality. See these for more information and rationale:
@wordpress/api-fetchpackage haslodashas a dependency #39495How?
Replaces
_.kebabCasewithparamCasefrom thechange-casepackage (already used in the components package).Testing Instructions
ContextSystemProviderworks and looks as expected (compare with trunk here: ContextSystemProvider)