Skip to content

feat(web): migrate from es-toolkit/compat to native es-toolkit (#30244)#10

Open
bar-qodo wants to merge 5 commits intocopilot_bench-100-20260108-copilot_base_featweb_migrate_from_es-toolkit_compat_to_native_es-toolkit_30244_pr131from
copilot_bench-100-20260108-copilot_head_featweb_migrate_from_es-toolkit_compat_to_native_es-toolkit_30244_pr131
Open

feat(web): migrate from es-toolkit/compat to native es-toolkit (#30244)#10
bar-qodo wants to merge 5 commits intocopilot_bench-100-20260108-copilot_base_featweb_migrate_from_es-toolkit_compat_to_native_es-toolkit_30244_pr131from
copilot_bench-100-20260108-copilot_head_featweb_migrate_from_es-toolkit_compat_to_native_es-toolkit_30244_pr131

Conversation

@bar-qodo
Copy link

Benchmark PR from qodo-benchmark#131

lyzno1 and others added 5 commits December 27, 2025 20:31
…enius#30244)

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 langgenius#30243
Fixes langgenius#30244
Copilot AI review requested due to automatic review settings January 11, 2026 18:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates from es-toolkit/compat to native es-toolkit modules to improve performance and reduce bundle size. The migration moves utility functions like noop, capitalize, escape, cloneDeep, etc. to their specific module paths (/function, /string, /object, /array, /predicate) while keeping functions with special behaviors (like debounce, merge, xorBy) in the /compat module. The PR also removes the lodash dev dependency.

Changes:

  • Migrated 100+ imports from es-toolkit/compat to specific module paths
  • Removed lodash from devDependencies in package.json
  • Added unrelated code changes to Toast component (unused class, dependency array modification)
  • Introduced logic bugs in log list filtering and workflow node sorting

Reviewed changes

Copilot reviewed 159 out of 160 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
web/utils/index.ts Migrated escape from /compat to /string
web/service/use-plugins.ts Migrated cloneDeep from /compat to /object
web/i18n-config/i18next-config.ts Migrated camelCase, kebabCase from /compat to /string
web/context/*.tsx Migrated noop from /compat to /function across multiple context files
web/app/components/workflow/*.tsx Migrated cloneDeep, capitalize, escape, intersection, isEqual to specific modules
web/app/components/base/toast/index.tsx Added unused class, modified dependency array, migrated noop
web/app/components/app/log/list.tsx Bug: inverted filter logic, split imports
web/app/components/workflow/nodes/_base/components/variable/utils.ts Bug: inverted sort logic, migrated imports
web/package.json Removed lodash devDependency
web/pnpm-lock.yaml Removed lodash lock entries
Files not reviewed (1)
  • web/pnpm-lock.yaml: Language not supported

Comment on lines 827 to +830
if (a.data.type === BlockEnum.Start)
return 1
if (b.data.type === BlockEnum.Start)
return -1
if (b.data.type === BlockEnum.Start)
return 1
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

The sort logic for the Start node has been inverted. Previously, when a.data.type === BlockEnum.Start, it returned 1 (pushing it later in the sort order). Now it returns -1 (pushing it earlier). This changes the sorting behavior and may break the intended node ordering. The comment on line 825 says "reverse chronological order (most recent first)" but this change inverts that for Start nodes.

Copilot uses AI. Check for mistakes.
}: {
children: ReactNode
}) => {
const stateManager = new ToastStateManager()
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

The stateManager instance is created on every render but is never used. This creates unnecessary object allocation on each render. Either use the stateManager to manage state, or remove it entirely.

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +116
class ToastStateManager {
private params: IToastProps
private mounted: boolean = false

constructor() {
this.params = {
type: 'info',
message: 'Toast message',
duration: 6000,
}
}

getParams() { return this.params }
setParams(p: IToastProps) { this.params = p }
isMounted() { return this.mounted }
setMounted(m: boolean) { this.mounted = m }
}
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

This ToastStateManager class is added but never used in the code. It appears to be dead code that should be removed. The class is instantiated in ToastProvider on line 123 but none of its methods are called, making it completely unused.

Copilot uses AI. Check for mistakes.
}, params.duration || defaultDuring)
}
}, [defaultDuring, mounted, params.duration])
}, [defaultDuring, mounted])
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

The dependency array was changed to remove params.duration, but this creates a bug. The useEffect uses params.duration inside the callback (line 137), so it should be included in the dependency array. Without it, the effect won't re-run when the duration changes, causing the toast to use stale duration values.

Copilot uses AI. Check for mistakes.
}
// Use the oldest answer item ID for pagination
const answerItems = allChatItems.filter(item => item.isAnswer)
const answerItems = allChatItems.filter(item => !item.isAnswer)
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

This filter logic has been inverted from item.isAnswer to !item.isAnswer. This is a critical bug - the code is now filtering for question items instead of answer items, which is the opposite of what the comment on line 250 states ("Use the oldest answer item ID for pagination"). This will break pagination logic for chat messages.

Suggested change
const answerItems = allChatItems.filter(item => !item.isAnswer)
const answerItems = allChatItems.filter(item => item.isAnswer)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants