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

Lodash: Refactor away from _.setWith() #47017

Merged
merged 2 commits into from
Jan 20, 2023
Merged

Lodash: Refactor away from _.setWith() #47017

merged 2 commits into from
Jan 20, 2023

Conversation

tyxla
Copy link
Member

@tyxla tyxla commented Jan 10, 2023

What?

This PR removes Lodash's _.setWith() from the block editor hooks. There is just a single usage in that block and conversion is pretty straightforward.

We're also removing one of the few remaining _.clone() usages together with that.

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:

How?

We're extending the custom immutable set functionality to use custom inline cloning and setting functions. We're adding tests to ensure that we're covering all the necessary prior functionality.

Alternatively, we could introduce new libraries, but since we were handling our own custom function for immutable settings, I thought it makes sense to just expand it.

We could remove the dot notation since it doesn't seem to be necessary for the existing use cases. More or less, it would remove a couple of lines of the path normalization and a few tests. I decided to keep it, but let me know if you'd suggest otherwise.

Another thing we could simplify is to default to an empty object in other places and keep the immutableSet simpler in terms of how it handles nullish values, but I decided to keep the previous behavior there.

Testing Instructions

  • Set some custom colors and typography on a paragraph block.
  • Verify "Reset all" in colors still work and removes all colors, but keeps typography styles intact.
  • Verify all tests pass and checks are green.

@tyxla tyxla added [Type] Performance Related to performance efforts [Type] Code Quality Issues or PRs that relate to code quality [Package] Block editor /packages/block-editor labels Jan 10, 2023
@tyxla tyxla self-assigned this Jan 10, 2023
@tyxla tyxla requested a review from ellatrix as a code owner January 10, 2023 11:39
@github-actions
Copy link

github-actions bot commented Jan 10, 2023

Size Change: +4.6 kB (0%)

Total Size: 1.33 MB

Filename Size Change
build/blob/index.min.js 483 B -4 B (-1%)
build/block-editor/content-rtl.css 3.65 kB +692 B (+23%) 🚨
build/block-editor/content.css 3.65 kB +693 B (+23%) 🚨
build/block-editor/index.min.js 185 kB +1.47 kB (+1%)
build/block-editor/style-rtl.css 14.2 kB -325 B (-2%)
build/block-editor/style.css 14.2 kB -328 B (-2%)
build/block-library/blocks/table/editor-rtl.css 433 B -24 B (-5%)
build/block-library/blocks/table/editor.css 433 B -24 B (-5%)
build/block-library/editor-rtl.css 11.7 kB -7 B (0%)
build/block-library/editor.css 11.7 kB -6 B (0%)
build/block-library/index.min.js 199 kB +582 B (0%)
build/blocks/index.min.js 50.4 kB -5 B (0%)
build/components/index.min.js 203 kB +196 B (0%)
build/components/style-rtl.css 11.6 kB +8 B (0%)
build/components/style.css 11.7 kB +8 B (0%)
build/core-data/index.min.js 15.9 kB +21 B (0%)
build/customize-widgets/index.min.js 11.7 kB +2 B (0%)
build/data/index.min.js 7.95 kB +265 B (+3%)
build/edit-navigation/index.min.js 16.2 kB +6 B (0%)
build/edit-navigation/style-rtl.css 4.14 kB +25 B (+1%)
build/edit-navigation/style.css 4.15 kB +25 B (+1%)
build/edit-post/index.min.js 34.4 kB -234 B (-1%)
build/edit-post/style-rtl.css 7.46 kB +15 B (0%)
build/edit-post/style.css 7.45 kB +15 B (0%)
build/edit-site/index.min.js 66.5 kB +1.24 kB (+2%)
build/edit-site/style-rtl.css 9.38 kB +116 B (+1%)
build/edit-site/style.css 9.38 kB +119 B (+1%)
build/edit-widgets/index.min.js 16.8 kB +4 B (0%)
build/edit-widgets/style-rtl.css 4.49 kB +24 B (+1%)
build/edit-widgets/style.css 4.49 kB +25 B (+1%)
build/editor/index.min.js 44.1 kB +12 B (0%)
build/editor/style-rtl.css 3.68 kB -7 B (0%)
build/editor/style.css 3.67 kB -9 B (0%)
build/experiments/index.min.js 862 B -20 B (-2%)
build/list-reusable-blocks/index.min.js 2.14 kB +8 B (0%)
build/media-utils/index.min.js 2.99 kB +48 B (+2%)
build/reusable-blocks/index.min.js 2.27 kB +18 B (+1%)
build/reusable-blocks/style-rtl.css 265 B -18 B (-6%)
build/reusable-blocks/style.css 265 B -18 B (-6%)
build/url/index.min.js 3.69 kB -4 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/block-directory/index.min.js 7.16 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 84 B
build/block-library/blocks/avatar/style.css 84 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 485 B
build/block-library/blocks/button/editor.css 485 B
build/block-library/blocks/button/style-rtl.css 532 B
build/block-library/blocks/button/style.css 532 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.57 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 984 B
build/block-library/blocks/gallery/editor.css 988 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 829 B
build/block-library/blocks/image/editor.css 828 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 298 B
build/block-library/blocks/latest-comments/style.css 298 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 716 B
build/block-library/blocks/navigation-link/editor.css 715 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB
build/block-library/blocks/navigation/editor.css 2.14 kB
build/block-library/blocks/navigation/style-rtl.css 2.22 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 376 B
build/block-library/blocks/page-list/editor.css 376 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 318 B
build/block-library/blocks/post-featured-image/style.css 318 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 440 B
build/block-library/blocks/query/editor.css 440 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 409 B
build/block-library/blocks/search/style.css 406 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 490 B
build/block-library/blocks/site-logo/editor.css 490 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/style-rtl.css 651 B
build/block-library/blocks/table/style.css 650 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 404 B
build/block-library/blocks/template-part/editor.css 404 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 691 B
build/block-library/blocks/video/editor.css 694 B
build/block-library/blocks/video/style-rtl.css 179 B
build/block-library/blocks/video/style.css 179 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 162 B
build/block-library/classic.css 162 B
build/block-library/common-rtl.css 1.05 kB
build/block-library/common.css 1.05 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 12.4 kB
build/block-library/style.css 12.4 kB
build/block-library/theme-rtl.css 698 B
build/block-library/theme.css 703 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/compose/index.min.js 12.3 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/date/index.min.js 32.1 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.71 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/element/index.min.js 4.93 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.2 kB
build/format-library/style-rtl.css 598 B
build/format-library/style.css 597 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.88 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/notices/index.min.js 977 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.59 kB
build/react-i18n/index.min.js 702 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.75 kB
build/rich-text/index.min.js 10.8 kB
build/server-side-render/index.min.js 2.09 kB
build/shortcode/index.min.js 1.52 kB
build/style-engine/index.min.js 1.53 kB
build/token-list/index.min.js 650 B
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.31 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@github-actions
Copy link

github-actions bot commented Jan 10, 2023

Flaky tests detected in 2635c75.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/3959670242
📝 Reported issues:

Copy link
Contributor

@sgomes sgomes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking at this, @tyxla!

I added some comments regarding the API. Let me know how you want to proceed, and I'll do a final review 👍

* Clones all nested objects in the specified object.
*
* @param {Object} object Object to set a value in.
* @param {number|string|Array} path Path in the object to modify.
Copy link
Contributor

@sgomes sgomes Jan 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to see the string-based API removed altogether; parsing strings to split them into paths is quite inefficient if it ends up in a hot path. I've had to fix several instances of this in Redux selectors over the years (in other applications), and the fix was usually to move to a (static) array path instead.

There's also the matter of this API being more complex and less explicit, which makes it difficult to migrate to something simpler in the future, even if the number and string notations aren't being used. If at this time it's easy to identify all the usage and move to something simpler, then we should take the chance, lest it become more difficult to do so in the future.

The only argument in favour of the dot notation, as I see it, is readability; but I don't think it's worth the other issues, given that an array of path segments is pretty readable on its own. Plus, if we really wanted to keep dotted paths for some reason, we could always relegate that to the consumer, where it makes sense:

import { immutableSet } from 'hooks/utils';

const THE_PATH = 'foo.bar.baz'.split( '.' );

export function doSomething( input ) {
  return immutableSet( input, THE_PATH, 42 );
}

The above avoids parsing the path and instancing an array on every call, and is just as readable as passing it directly to immutableSet.

All of that said, I acknowledge this is possibly out of scope for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the observation and your hint, @sgomes! You actually caught one of my biggest doubts about this work here.

I was very close to removing the . support, and likely should have, since we have no present usage of it in the codebase. That will simplify the code and add less complexity to an already complex part of the codebase.

I consider this part of the PR's scope, since we're directly tinkering with the API, so it's the right time to simplify it.

I'll work on that before asking you to do another review.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed support for dot notation in 2635c75.

@@ -30,8 +30,75 @@ export const cleanEmptyObject = ( object ) => {
return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects;
};

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're dropping support for arrays and their indexed notation [0] here. Is that intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to implement it, but IMO it would needlessly complicate the function, and I didn't see a need for that within our existing usages.

Unless I'm misunderstanding you, in which case I'd ask you for a unit test or an example of what exactly you mean 😉

Copy link
Contributor

@sgomes sgomes Jan 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, dropping it is indeed my preferred approach, as is dropping the dot notation as well 👍 Just wanted to make sure it was intentional 🙂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for double-checking 👍

@tyxla
Copy link
Member Author

tyxla commented Jan 19, 2023

Hey, @sgomes I've dropped the dot notation support and this is ready for another look when you get a chance. Thanks!

@tyxla tyxla requested a review from sgomes January 19, 2023 15:03
Copy link
Contributor

@sgomes sgomes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @tyxla! 👍

* 2 => [ '2' ]
* [ 'foo', 'bar' ] => [ 'foo', 'bar' ]
*
* @param {number|string|Array} path Path
* @param {string|number|Array} path Path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go a step further and enforce it as an array, always, but this is probably a good middle-ground between convenience and simplicity.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think that could be a good improvement for the future, but I decided to leave that support since we have at least one existing use case for a single string path:

() => transformStyles( styles, EDITOR_STYLES_SELECTOR ),

@tyxla
Copy link
Member Author

tyxla commented Jan 20, 2023

Thank you, @sgomes 🙌

@tyxla tyxla merged commit acd9cfe into trunk Jan 20, 2023
@tyxla tyxla deleted the refactor/lodash-set-with branch January 20, 2023 10:33
@github-actions github-actions bot added this to the Gutenberg 15.1 milestone Jan 20, 2023
Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like too much code for something that can be provided by an existing library. Did we consider immer here?

@tyxla
Copy link
Member Author

tyxla commented Mar 9, 2023

This feels like too much code for something that can be provided by an existing library. Did we consider immer here?

My initial research resulted that every library we could use for that would be larger than what we're introducing here. Immer also seems to be 16.3KB minified, which isn't too much, but still is more than we're introducing here. I'm happy to try it out if you think it will be better. Given that code-size-wise immer would not be an improvement, what other motivation do you have for suggesting that? I'm happy to try it out if there are valid reasons it will be better.

@sgomes
Copy link
Contributor

sgomes commented Mar 10, 2023

This feels like too much code for something that can be provided by an existing library. Did we consider immer here?

This is in part predicated on the idea that we'd never want to get rid of immer, but if history is any indication, every third-party library has an expiration date, for any number of reasons. And while you can definitely make the argument that we're already using it elsewhere, every time we use it it becomes more difficult to eventually drop it; that's why it's been so much work to get rid of lodash, even though some of the use was quite trivial.

If the problem we're solving can be dealt with in 60 lines of code, I think that's definitely worth keeping around, particularly since @tyxla was diligent enough to add extensive testing.

@youknowriad
Copy link
Contributor

It's not the first function that I see around that replicates a lodash function. I remember seeing or having to implement omit in a couple places too. I think this should be seen as a devx issue that needs solving. We can't keep reinventing the same functions forever. I'm fine if we provide them but this function is randomly placed in a random package in a random folder and it has nothing to do with that package.

Unless you know it's there, you're not going to use it. In fact I wrote a lot of code in the global-styles/*-panel.js components that could benefit from it but was not aware of it, so I just added more bytes and lines of code for nothing.

I don't care whether it's a third-party package or a first-party one but seeing all these utility functions scattered everywhere is a problem.

@tyxla
Copy link
Member Author

tyxla commented Mar 13, 2023

I generally agree with your sentiment, @youknowriad. At the same time, my opinion is that while you're right, sometimes those functions are domain- or context-specific and way simpler than they would have been if they cover all generic cases.

We never wanted to reinvent the wheel, and having a smaller inline abstraction actually makes it more comprehensible what the expectations of input and output of a certain function or component are. Lodash functions would often conceal those abstractions and that made the code less readable, worse typed, and potentially more error-prone for future iterations.

Also, I believe that we have far too few of those helper functions inline in packages. Especially considering how much Lodash usage we've removed. I definitely would like to remove them all, but sometimes there's no good candidate for external package, or the use case is way too simple to justify using another external package with additional own dependencies.

I do believe the code is in a much better, predictable, and manageable state without Lodash, compared to how it was with Lodash. This doesn't mean that there aren't further opportunities for improvement. I'm always happy to work on those, so thank you for sharing your thoughts.

I often like reminding ourselves that this is a marathon and not a sprint. We are making incremental steps toward a better codebase. As we continue to iterate, we'll keep seeking opportunities to improve any devex gaps like the one you mentioned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Block editor /packages/block-editor [Type] Code Quality Issues or PRs that relate to code quality [Type] Performance Related to performance efforts
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants