Repository navigation
fix[groupBy, maxBy, minBy]: call the iteratee with only the element like lodash - #2122
Merged
raon0211 merged 1 commit intoSep 30, 2026
Conversation
…ike lodash Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
raon0211
approved these changes
Sep 30, 2026
raon0211
pushed a commit
that referenced
this pull request
Oct 9, 2026
compat's groupBy has its own implementation since #2122, so the main-library groupBy is no longer in compat's dependency graph. Revert it to main and drop Object.hasOwn from compat's groupBy instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raon0211
added a commit
that referenced
this pull request
Oct 23, 2026
* feat(compat): support Node.js 6+ in es-toolkit/compat es-toolkit/compat exists to migrate lodash code, which often still runs in old environments. Make it work on Node.js 6 as published, with no transpilation and no polyfills, and keep it that way. - Restrict src/compat/** to ES2015 syntax and built-ins: rewrite optional chaining, nullish coalescing, object spread, Object.hasOwn, Object.values, Array#flat/flatMap/at/findLast(Index), String#matchAll/trimStart/trimEnd. - words: fall back to lodash's ES5 word patterns when the engine cannot compile the Unicode-property regex, so camelCase and friends work on Node.js 6. - truncate: drop the named capture group (Node.js 10+ only). - isNative: use the internal globalThis shim instead of the bare global. - cloneDeepWith: give compat its own implementation instead of delegating to the main library's, which relies on structuredClone. - Fix the few main-library files compat imports (groupBy, pull, remove, isEqualWith, clone, deburr, trimStart, trimEnd, debounce) and stop invokeMap from importing the whole predicate barrel. - ESLint: es-x + eslint-plugin-compat with a Node.js 6 target on src/compat. - CI: new compat-node6 job runs the built package on a real Node.js 6 (entry points + every compat @example case) on every change. - Docs: Node.js support section in browser-support (en/ko/ja/zh_hans). * test: update bundle size snapshots * fix(trimStart, trimEnd): drop the whitespace regex flagged by CodeQL `str.replace(/\s+$/, '')` is quadratic on inputs with a long run of whitespace followed by a non-whitespace character. Scan from the edges with a per-character `\s` test instead, which is linear and still ES2015-compatible. The compat variants delegate to the main implementations instead of carrying their own regex. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(compat/groupBy): avoid Object.hasOwn for Node.js 6 compat's groupBy has its own implementation since #2122, so the main-library groupBy is no longer in compat's dependency graph. Revert it to main and drop Object.hasOwn from compat's groupBy instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: update bundle size snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * build: upgrade tsdown and lower published code to ES2019 syntax Lowering `?.` and `??` at build time lets the source keep using them while `es-toolkit/compat` still loads on ES2015 engines such as Node.js 6. Oxc cannot lower individual syntax features yet (oxc-project/oxc#15373), so the whole output targets ES2019. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(compat): keep the main library untouched for Node.js 6 support - Revert the main-library changes; compat now has ES2015 copies of the pieces it needs (`basePull`, `baseIsEqualWith`, `baseClone`, and local `remove`/`trimStart`/`trimEnd` implementations), plus its own `isEqual`. - Allow `?.` and `??` in compat again, since the build lowers them. - Add `hasOwn` and `objectValues` helpers instead of repeating `hasOwnProperty.call` and `Object.keys(...).map(...)`. - Merge `legacyWords` into `compat/_internal/words.ts`. - Use array spread in `cloneDeepWith`'s `copyProperties`; `concat` made deep clones of objects 8-21% slower than before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: move compat environment support to its own page Add a "Browser & Node.js Support" page under /compat in all four languages, and link to it from the main Browser Support page instead of merging the content there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-compat): add a manual case for Queue `Queue` (#2150) has no runnable `@example`, so the Node check in the browser-compat workflow failed with "1 exports have no test case", which then left the WebKit lane waiting on a fixture that was never built. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(compat/words): always split words with lodash's patterns The Unicode-property pattern only approximated lodash and still disagreed on inputs such as `ПриветМир`, `foo©bar`, `foo™bar`, `DžDž`, and mathematical letters, while lodash's own patterns match lodash exactly and already run on every engine, including Node.js 6. Using them everywhere removes the second implementation, makes non-ASCII input about 1.5x faster, and shrinks compat `camelCase` from 4,410 to 3,448 bytes. * docs: name es-toolkit/compat in the environment support link --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: T3 Code Service User <t3code@raonserver-t3code.Maxio>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes
es-toolkit/compat'sgroupBy,maxBy, andminByto call iteratees with only the current element, matching Lodash. Passing(element, index, array)instead can produce different results for callbacks such asparseInt, even though the equivalent Lodash calls compile in strict mode with@types/lodash. ForgroupBy, this mismatch was introduced when #1561 added index and array arguments to the main implementation used by compat.Changes
getValue(element)instead ofgetValue(element, i, array)in compatmaxByandminBy.groupByto pass only the element to the iteratee, rather than delegating to the main implementation or adding a wrapper callback.es-toolkitimplementations unchanged, including their index and array arguments.parseIntbehavior in all three functions. These tests fail onmainand pass on this branch.Validation
All 3,301 compat and array tests pass. Type checking, Prettier, and ESLint checks pass; the two ESLint warnings also exist on
main.Benchmarks
Measured locally on Windows with Node.js 22, comparing
main(d6f79606) against this branch (0666b800). The benchmarks workspace failed withERR_UNSUPPORTED_ESM_URL_SCHEMEon Windows, so equivalent benchmarks were run withvitest bench, importing directly fromsrc/compat.Results are in ops/sec; higher is better. Each
groupBycell contains results from two separate runs.groupBybenchmarks/performance/groupBy.bench.tsgroupBymaxByminByThe final implementation showed no consistent slowdown across these local runs. An initial wrapper-based
groupByimplementation reached 3,882,366–4,494,805 ops/sec in the 5-item case, so it was replaced with the local loop.