feat(web): migrate from es-toolkit/compat to native es-toolkit (#30244)#30246
feat(web): migrate from es-toolkit/compat to native es-toolkit (#30244)#30246crazywoola merged 4 commits intomainfrom
Conversation
Migrate 172 files from es-toolkit/compat to native es-toolkit. Migrated: - noop → es-toolkit/function - cloneDeep, omit, clone, pick → es-toolkit/object - uniq, intersection → es-toolkit/array - capitalize, camelCase, kebabCase, escape → es-toolkit/string - isEqual → es-toolkit/predicate Kept in compat (API differences): - uniqueId, isEmpty - get, merge, flow, curry, debounce - different APIs - uniqBy, groupBy, intersectionBy - property string support - flatten - undefined handling Benefits: 2-3x faster, smaller bundle Part of #30243 Fixes #30244
Summary of ChangesHello @lyzno1, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request focuses on enhancing the application's performance and optimizing its bundle size by migrating a large number of utility function imports from the compatibility layer of Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly migrates many utility functions from es-toolkit/compat to their native es-toolkit modules, which should improve performance and reduce bundle size. The changes are extensive and mostly correct. I've found a few places where some functions that could be migrated were left in es-toolkit/compat. Overall, great work on this large refactoring task.
Changes SummaryThis PR performs a systematic migration of 150+ files in the web frontend from using es-toolkit/compat imports to native es-toolkit submodule imports. Functions like noop, cloneDeep, clone, pick, omit, uniq, intersection, capitalize, camelCase, kebabCase, escape, and isEqual are moved to their respective native submodules, while keeping functions with different APIs (uniqueId, isEmpty, get, merge, etc.) in compat. This improves performance by 2-3x and reduces bundle size. Type: refactoring Components Affected: web/components - across modal, chat, configuration, datasets, workflow, plugins, web/app - authentication, account settings, app management pages, web/context - provider contexts, web/mocks - test mocks Files Changed
Architecture Impact
Risk Areas: Large-scale import refactoring across 150+ files - risk of merge conflicts in concurrent PRs, Import path changes could break if someone has custom es-toolkit wrapper imports, Need to verify es-toolkit/array, es-toolkit/function, es-toolkit/string, es-toolkit/object, es-toolkit/predicate exports exist and match expected APIs Suggestions
Full review in progress... | Powered by diffray |
Review Summary
Validated 12 issues: 7 kept (context assertion, any types, type assertions), 5 filtered (false positives, low-value quality concerns) Issues Found: 7💬 See 1 individual line comment(s) for details. 📊 4 unique issue type(s) across 7 location(s) 📋 Full issue list (click to expand)🟠 HIGH - Non-null assertion on context without validationAgent: typescript Category: bug File: Description: The 'useHooksStoreApi' function uses '!' assertion without null check. The sibling function 'useHooksStore' (lines 158-164) properly throws an error when context is missing, but this function does not. Suggestion: Add a runtime check like in useHooksStore: 'const store = useContext(HooksStoreContext); if (!store) throw new Error("Missing HooksStoreContext.Provider in the tree"); return store' Confidence: 85% Rule: 🟡 MEDIUM - Multiple 'as any' assertions for accessing model data (2 occurrences)Agent: typescript Category: quality 📍 View all locations
Rule: 🟡 MEDIUM - Record type with 'any' generic parameter (3 occurrences)Agent: typescript Category: quality 📍 View all locations
Rule: 🟡 MEDIUM - Potential null/undefined access on ctx.plan propertyAgent: typescript Category: bug File: Description: In 'createMockPlanUsage', 'createMockPlanTotal', and 'createMockPlanReset' functions, 'ctx.plan' is passed to merge() without verification. Since ctx is Partial, ctx.plan could be undefined. Suggestion: Add null coalescing: 'merge(ctx.plan ?? defaultPlan, { ... })' to ensure a valid base object Confidence: 70% Rule: ℹ️ 6 issue(s) outside PR diff (click to expand)
🟠 HIGH - Non-null assertion on context without validationAgent: typescript Category: bug File: Description: The 'useHooksStoreApi' function uses '!' assertion without null check. The sibling function 'useHooksStore' (lines 158-164) properly throws an error when context is missing, but this function does not. Suggestion: Add a runtime check like in useHooksStore: 'const store = useContext(HooksStoreContext); if (!store) throw new Error("Missing HooksStoreContext.Provider in the tree"); return store' Confidence: 85% Rule: 🟡 MEDIUM - Multiple 'as any' assertions for accessing model data (2 occurrences)Agent: typescript Category: quality 📍 View all locations
Rule: 🟡 MEDIUM - 'any' type parameter in function signature (2 occurrences)Agent: typescript Category: quality 📍 View all locations
Rule: 🟡 MEDIUM - Potential null/undefined access on ctx.plan propertyAgent: typescript Category: bug File: Description: In 'createMockPlanUsage', 'createMockPlanTotal', and 'createMockPlanReset' functions, 'ctx.plan' is passed to merge() without verification. Since ctx is Partial, ctx.plan could be undefined. Suggestion: Add null coalescing: 'merge(ctx.plan ?? defaultPlan, { ... })' to ensure a valid base object Confidence: 70% Rule: Review ID: |
There was a problem hiding this comment.
Pull request overview
This PR migrates utility functions from es-toolkit/compat to native es-toolkit for improved performance (2-3x faster) and smaller bundle size. The migration strategically moves functions with compatible APIs to their respective native submodules while keeping functions with API differences in compat.
- Migrated functions to native submodules:
noop→ function,cloneDeep/omit/clone/pick→ object,uniq/intersection→ array,capitalize/camelCase/kebabCase/escape→ string,isEqual→ predicate - Functions intentionally kept in compat:
uniqueId,isEmpty,get,merge,flow,curry,debounce,uniqBy,groupBy,intersectionBy,flatten,xorBy,unionBy,isArray - Import statements properly separated when files use both compat and native functions
Reviewed changes
Copilot reviewed 159 out of 159 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| web/utils/index.ts | Migrated escape from compat to string submodule |
| web/service/use-plugins.ts | Migrated cloneDeep from compat to object submodule |
| web/i18n-config/i18next-config.ts | Migrated camelCase and kebabCase from compat to string submodule |
| web/context/*.tsx | Migrated noop from compat to function submodule across multiple context files |
| web/app/components/workflow/utils/*.ts | Migrated cloneDeep from compat to object submodule for workflow utilities |
| web/app/components/workflow/run/utils/format-log/*.ts | Migrated noop and cloneDeep from compat to their respective submodules |
| web/app/components/workflow/panel/**/*.tsx | Migrated capitalize, noop from compat to their respective submodules, kept debounce in compat |
| web/app/components/workflow/nodes/**/*.tsx | Migrated capitalize, noop from compat to their respective submodules across node components |
| web/app/components/workflow/nodes/knowledge-retrieval/*.ts | Migrated uniq to array submodule, isEqual to predicate submodule, kept xorBy in compat |
| web/app/components/workflow/nodes/_base/components/*.tsx | Migrated intersection, isEqual, noop, capitalize to their respective submodules |
| web/app/components/workflow/nodes/_base/components/variable/utils.ts | Migrated uniq to array, kept isArray in compat |
| web/app/components/workflow/index.tsx | Migrated isEqual from compat to predicate submodule |
| web/app/components/workflow/hooks/*.ts | Migrated cloneDeep from compat to object submodule |
| web/app/components/workflow/custom-edge.tsx | Migrated intersection from compat to array submodule |
| web/app/components/workflow/block-selector/market-place-plugin/list.tsx | Migrated noop from compat to function submodule |
| web/app/components/plugins/**/*.tsx | Migrated noop, camelCase, capitalize, isEqual to their respective submodules, kept debounce in compat |
| web/app/components/datasets/**/*.tsx | Migrated noop to function submodule, pick/uniq to their respective submodules |
| web/app/components/base/**/*.tsx | Migrated noop to function submodule, escape to string submodule across base components |
| web/app/components/base/agent-log-modal/detail.tsx | Migrated uniq to array submodule, kept flatten in compat |
| web/app/components/base/chat/**/*.tsx | Migrated noop to function submodule, kept uniqBy and debounce in compat |
| web/app/components/base/file-uploader/*.tsx | Migrated isEqual to predicate submodule, noop to function submodule |
| web/app/components/app/log/*.tsx | Migrated omit to object submodule, noop to function submodule, kept get in compat |
| web/app/components/app/configuration/**/*.tsx | Migrated clone to object submodule, isEqual to predicate submodule, noop to function submodule |
| web/app/signin/**/*.tsx | Migrated noop from compat to function submodule |
| web/app/signup/components/input-mail.tsx | Migrated noop from compat to function submodule |
| web/mocks/provider-context.ts | Migrated noop to function submodule, kept merge in compat |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @copilot remove devDependencies: "lodash": "^4.17.21", commit and push in this branch, remember update pnpm-lock.yaml |
| @copilot resolve conflicts |
193101b to f05d43d Compare
Migrate some files from es-toolkit/compat to native es-toolkit.
Migrated:
Kept in compat (API differences):
Benefits: 2-3x faster, smaller bundle
Another:
lodashdependency in web/Part of #30243
Fixes #30244