Show HN:SuperUtilsPlus——Lodash 的现代替代方案
Show HN: SuperUtilsPlus – A Modern Alternative to Lodash

原始链接: https://github.com/dhaxor/super-utils-plus

SuperUtilsPlus 是一个现代化的 JavaScript 实用工具库,旨在成为 Lodash 的更优替代方案。它拥有改进的性能、完整的 TypeScript 支持和增强的开发者体验。使用 ES2020+ 构建,并提供 ESM 和 CommonJS 支持,SuperUtilsPlus 通过允许您只导入必要的函数来促进 tree-shaking。 它轻量级且零依赖,并进行了广泛的测试以确保可靠性。主要功能包括数组操作(分块、扁平化、差异计算)、对象实用程序(深度克隆、基于路径的值检索)、字符串转换(camelCase)、函数操作(去抖动)、全面的类型检查和随机值生成。 SuperUtilsPlus 的与众不同之处在于其优化的性能、比 Lodash 更广泛的实用函数范围以及更直观的类型检查(例如,`isNumber` 对 `NaN` 的处理更准确)。该库兼容浏览器和 Node.js 环境。它还鼓励模块化导入以减小包大小,并为无缝 TypeScript 集成提供明确的类型定义。

Hacker News 上,“SuperUtilsPlus” 的作者介绍了他们的 JavaScript 工具库,将其定位为 Lodash 的现代替代方案,旨在解决包大小和一些奇特行为等常见问题。它从底层使用 TypeScript 构建,拥有更好的类型推断和更合理的默认值(例如,`isObject([])` 返回 false)。它专为 ES2020+ 设计,支持 ESM,并且可以 tree-shaking,允许用户导入特定模块以优化打包。值得注意的功能包括 `compactNil()`、`differenceDeep()` 和改进的随机数工具。 讨论围绕依赖管理展开,一些用户更倾向于直接复制粘贴实用函数以避免版本更新和潜在的安全漏洞。另一些人则强调固定依赖版本和及时更新安全补丁的重要性。讨论还涉及 es-toolkit 和 remeda 等替代库,重点关注 tree-shaking 功能和特定实用函数的实现。

原文

A superior alternative to Lodash with improved performance, TypeScript support, and developer experience.

  • Full TypeScript Support: Type definitions are first-class citizens
  • Modern JavaScript: Written for ES2020+ with full ESM and CommonJS support
  • Tree-Shakable: Only import what you need
  • Zero Dependencies: Lightweight and no bloat
  • Extensive Testing: High test coverage for reliable code
  • Extended Functionality: More utility functions than Lodash
  • Performance Focused: Optimized for speed and efficiency
  • Browser & Node.js: Works everywhere JavaScript runs
npm install super-utils-plus
# or
yarn add super-utils-plus
# or
pnpm add super-utils-plus
import { chunk, compact, difference, flatten, flattenDeep, groupBy } from 'super-utils';

// Create chunks of arrays
chunk([1, 2, 3, 4, 5], 2);
// => [[1, 2], [3, 4], [5]]

// Remove falsy values from array
compact([0, 1, false, 2, '', 3, null, undefined, NaN]);
// => [1, 2, 3]

// Remove only null and undefined values
compactNil([0, 1, false, 2, '', 3, null, undefined, NaN]);
// => [0, 1, false, 2, '', 3, NaN]

// Find values not included in other arrays
difference([2, 1], [2, 3]);
// => [1]

// Find values not included using deep equality
differenceDeep([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }]);
// => [{ 'x': 2 }]

// Find values not included using a custom iteratee
differenceBy([2.1, 1.2], Math.floor, [2.3, 3.4]);
// => [1.2]

// Flatten an array one level
flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]

// Recursively flatten an array
flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]

// Group array elements by a key or function
groupBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': [4.2], '6': [6.1, 6.3] }

groupBy(['one', 'two', 'three'], 'length');
// => { '3': ['one', 'two'], '5': ['three'] }
import { get, deepClone } from 'super-utils';

// Get a value from an object with a path
const object = { 'a': [{ 'b': { 'c': 3 } }] };

get(object, 'a[0].b.c');
// => 3

get(object, ['a', '0', 'b', 'c']);
// => 3

get(object, 'a.b.c', 'default');
// => 'default'

// Create a deep clone of an object
const original = { a: 1, b: { c: 2 } };
const clone = deepClone(original);

original.b.c = 99;
// clone.b.c is still 2
import { camelCase } from 'super-utils';

// Convert a string to camel case
camelCase('Foo Bar');
// => 'fooBar'

camelCase('--foo-bar--');
// => 'fooBar'

camelCase('__FOO_BAR__');
// => 'fooBar'
import { debounce } from 'super-utils';

// Create a debounced function
const debouncedSave = debounce(saveFunction, 300, { leading: true, trailing: true });

// Call it multiple times, but it will only execute once after 300ms of inactivity
debouncedSave();
debouncedSave();
debouncedSave();

// Cancel the debounced function
debouncedSave.cancel();

// Immediately invoke the debounced function
debouncedSave.flush();
import { 
  isNil, isUndefined, isNull, isNumber, isString, isBoolean,
  isFunction, isArray, isObject, isPlainObject, isEmpty, isEqual 
} from 'super-utils';

// Check types
isNumber(123);      // => true
isNumber('123');    // => false
isNumber(NaN);      // => false (more intuitive than Lodash)

isString('hello');  // => true
isObject({});       // => true
isObject([]);       // => false (unlike Lodash, arrays are not objects)
isArray([]);        // => true

// Check for null or undefined
isNil(null);        // => true
isNil(undefined);   // => true
isNil(0);           // => false

// Deep equality comparison
isEqual({ a: 1, b: 2 }, { a: 1, b: 2 });  // => true
isEqual([1, 2, 3], [1, 2, 3]);            // => true
import { random, randomInt, randomString, randomUUID } from 'super-utils';

// Generate a random number between min and max
random(1, 10);  // => 4.237...

// Generate a random integer between min and max (inclusive)
randomInt(1, 10);  // => 7

// Generate a random string
randomString(10);  // => "a1b2c3d4e5"
randomString(5, 'ABC');  // => "BACAB"

// Generate a random UUID
randomUUID();  // => "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

Tree-Shaking with Module Imports

For optimal bundle size, import only what you need:

// Import only what you need from specific modules
import { chunk, difference } from 'super-utils/array';
import { get } from 'super-utils/object';
import { debounce } from 'super-utils/function';
import { isArray } from 'super-utils/utils';

SuperUtilsPlus is written in TypeScript and provides full type definitions:

import { get } from 'super-utils';

interface User {
  name: string;
  profile: {
    age: number;
    email: string;
  };
}

// Type-safe access with generics
const user = get<User>(data, 'users[0]');

MIT

联系我们 contact @ memedata.com