使用 es-toolkit 处理日常 JavaScript 工具函数
如果你曾使用 Lodash 来对输入框做防抖、对数组分块或从对象中挑选键,那么你已经体会到一个设计良好的 JavaScript 工具库的价值。今天值得思考的问题是:Lodash 是否仍然是最佳默认选择?还是说在现代 TypeScript 与 ESM 项目中,更轻量的方案会更合适?
es-toolkit 是一个仍在积极维护的 JavaScript 工具库,它从一开始就基于 TypeScript、ESM 以及现代 JavaScript API 进行构建。它涵盖了前端开发者最常用的辅助函数——而且其体积明显小于 Lodash。
关键要点
- es-toolkit 是一个以 TypeScript 为先的现代工具库,自带类型定义,并开箱即支持干净的 tree-shaking。
- 它已经具备生产级可用性,被 Storybook、Recharts、CKEditor 采用,并获得了 Nuxt 的官方推荐。
- 与 Lodash 相比,打包体积可显著更小,非常适合对加载时间敏感的客户端 JavaScript 场景。
- 兼容层(
es-toolkit/compat)可以简化从 Lodash 的迁移过程,不过从长期来看,标准包才是更好的选择。
什么是 es-toolkit?为什么它值得关注?
es-toolkit 是一个现代 JavaScript 工具库,它为常用辅助函数提供了带类型的、可 tree-shake 的实现。它完全使用 TypeScript 编写,自带类型定义,无需额外安装 @types/ 包。
正如 es-toolkit 文档所述,该库已被 Storybook、Recharts、CKEditor、Material UI 和 Nuxt 等项目和生态采用。这种程度的采用度足以表明该项目正在被积极维护,并适合用于生产环境。
该库被划分为清晰的几个分类——array、object、function、string、math 和 async 工具函数——每类都有独立模块。这样的结构使得任何现代打包器都能轻松实现 tree-shaking。
全方位覆盖的常用辅助函数
下面来看一下 es-toolkit 在各类常见工具函数上的实际表现:
数组工具
import { chunk, groupBy, uniq, difference } from 'es-toolkit';
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
groupBy(['one', 'two', 'three'], (s) => s.length); // { 3: ['one', 'two'], 5: ['three'] }
uniq([1, 2, 2, 3]); // [1, 2, 3]
difference([1, 2, 3], [2, 3]); // [1]
对象工具
import { pick, omit, mapValues } from 'es-toolkit';
pick({ a: 1, b: 2, c: 3 }, ['a', 'c']); // { a: 1, c: 3 }
omit({ a: 1, b: 2, c: 3 }, ['b']); // { a: 1, c: 3 }
mapValues({ a: 1, b: 2 }, (v) => v * 2); // { a: 2, b: 4 }
函数工具
import { debounce, throttle, once } from 'es-toolkit';
const handleSearch = debounce((query: string) => fetchResults(query), 300);
const handleScroll = throttle(() => updatePosition(), 100);
const initialize = once(() => setupApp());
空值检查与类型守卫
import { isNotNil } from 'es-toolkit';
const values = [1, null, 2, undefined, 3];
values.filter(isNotNil); // [1, 2, 3] — 类型为 number[]
TypeScript 在这里能够正确推断出收窄后的类型——而在 Lodash 与 @types/lodash 组合下,这往往需要更多的手动处理。
打包体积:一个实际的差异
当你在 Vite 项目中只从 es-toolkit 导入某一个函数时,最终打包结果中只会包含该函数的代码。视具体工具函数而定,相比同等 Lodash 导入,所增加的打包体积可以非常小。
差距在不进行 tree-shaking 而直接从完整 lodash 包导入时最为明显,那种情况下可能增加超过 20 kB(压缩后)的体积。
这种差异对客户端 JavaScript 影响最大,因为打包体积会直接影响加载时间和 Core Web Vitals。
Discover how at OpenReplay.com.
从 Lodash 迁移
如果你正在迁移现有代码库,es-toolkit 提供了兼容层:
// 迁移前
import _ from 'lodash';
// 迁移后(兼容模式)
import _ from 'es-toolkit/compat';
es-toolkit/compat 通过了 Lodash 自身的测试套件,目标是与 Lodash 完全兼容。话虽如此,从长期来看,标准的 es-toolkit 包才是更好的选择——它体积更小、速度更快,TypeScript 类型也更精确。
标准包的 API 也比 Lodash 更精简、更现代,因此在进行大规模迁移之前,建议先查阅官方文档。
何时适合选择 es-toolkit
在以下情况下使用 es-toolkit:
- 你正在启动一个新的 TypeScript 或 ESM 项目,希望使用带类型的工具函数,又不想引入沉重的依赖。
- 你关心打包体积,并希望获得干净的 tree-shaking 效果。
- 你需要现代的异步辅助函数,例如支持
AbortController的delay。 - 你希望使用内置类型,而无需额外安装
@types/包。
继续使用 Lodash(或原生 JavaScript)的情况:
- 你已有大型 Lodash 代码库,迁移成本高于收益。
- 整个旧应用大量依赖 Lodash 特有的写法和模式。
- 你的运行时环境早于现代 JavaScript 工具链。
结论
es-toolkit 是一个实用且维护良好的 Lodash 替代方案,适用于现代 JavaScript 与 TypeScript 项目。它无法立刻替代所有的 Lodash 工作流,但对于新项目——或任何重视打包体积与类型安全的代码库——它都值得作为默认工具库纳入考虑。
常见问题
并非完全可以。标准 es-toolkit 包的类型更严格、API 范围比 Lodash 更小,因此部分函数签名存在差异。为方便迁移,es-toolkit/compat 模块对齐了 Lodash 的 API,并通过了 Lodash 自身的测试套件。大多数项目可以从 compat 开始逐步迁移,再随时间过渡到标准包。
两者都支持。es-toolkit 可在现代 Node.js、浏览器、Deno 和 Bun 环境中运行,并能与 Vite、webpack、Rollup 等前端打包器无缝集成。
通常是的——尤其是当你目前从 Lodash 根包导入时。es-toolkit 是为现代 tree-shaking 设计的,许多工具函数对生产打包的体积增加非常有限。具体的体积差异取决于你导入的函数以及应用的打包方式。
不需要。es-toolkit 用 TypeScript 编写,自带类型定义,无需安装额外的 @types/ 包。其类型推断通常也比 Lodash 配合 @types/lodash 更准确,尤其是在 isNotNil 等类型守卫,以及 pick、omit 等泛型工具函数上。
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.