优化工具函数导出结构的关键是支持Tree Shaking:采用具名导出、按功能拆分文件、消除顶层副作用、提供纯ESM入口。

优化工具函数的导出结构,核心是让打包工具能准确识别哪些函数被使用、哪些可安全剔除。关键不在“写得漂亮”,而在“结构清晰、无歧义、无副作用”。
用具名导出替代默认导出对象
避免把一堆函数塞进一个默认导出对象里,比如:
❌ 不推荐:export default { debounce, throttle, once, deepClone };
这种写法会让 Tree Shaking 工具难以判断单个函数是否被引用——只要有人 import 了这个 default 对象,整个对象可能全被保留。
立即学习“Java免费学习笔记(深入)”;
✅ 推荐:export function debounce() { ... }<br>export function throttle() { ... }<br>export function once() { ... }<br>export function deepClone() { ... }
这样使用者可以精确 import:import { debounce, throttle } from './utils',未使用的 once 和 deepClone 就能被完整摇掉。
拆分文件,按功能粒度导出
把大型工具模块按逻辑切分成独立小文件,每个文件只导出 1–3 个强相关函数:
-
src/utils/debounce.ts→ 只导出debounce和cancelDebounce -
src/utils/number.ts→ 只导出clamp、roundTo、isInteger
这样不仅利于 Tree Shaking(整文件未被引入就直接跳过),也提升可维护性和类型推导准确性。配合 package.json 的 "exports" 字段,还能支持更细粒度的按需加载路径,如 import debounce from 'my-utils/debounce'。
避免顶层副作用,确保模块“纯净”
即使导出结构再干净,如果模块顶部执行了有影响的操作,打包工具会因“不确定是否安全删除”而保留整个文件。例如:
❌ 危险写法:console.log('utils loaded');<br>window._utilsInit = true;<br>document.addEventListener('DOMContentLoaded', init);<br>export function debounce() { ... }
这类代码会被视为“有副作用”,除非你在 package.json 中显式声明它(如 "sideEffects": ["./src/utils/debounce.ts"]),否则 "sideEffects": false 下它会被直接删掉——连带里面的 debounce 函数。
所有导出函数保持纯逻辑;副作用移入函数内部或由上层主动调用。模块本身只做定义,不自动执行。
提供 ESM 入口并禁用 Babel 转换 modules
确保构建链路不破坏 ES 模块静态性:
- 在
package.json中设置"type": "module"或通过"exports"指向.mjs或index.esm.js - Babel 配置中必须设
modules: false(尤其@babel/preset-env),否则import/export会被转成require,Tree Shaking 彻底失效 - 若用 TypeScript,
tsconfig.json中"module": "ESNext",且不启用outDir自动生成 CommonJS


















