大型ui组件库未被tree shaking剔除,根本原因是未被允许摇:一是导入方式错误(如require或babel转译为commonjs),二是库未提供真正可摇的esm入口(需exports.import或module指向纯esm文件),三是副作用未正确声明(sideeffects缺失或为true导致全量保留),四是要通过生产构建产物验证实际是否引入未用组件。

排查大型 UI 组件库未被 Tree Shaking 剔除,核心不是“它没摇”,而是“它根本没被允许摇”——通常卡在模块系统、副作用声明或导入方式三个关键环节。
检查是否用了 CommonJS 式导入
即使组件库本身支持 ESM,你自己的代码若用 require 或 Babel 自动转译,就会破坏静态分析。
- 确认项目中没有
const { Button } = require('xxx-ui')这类写法 - TypeScript 或 Babel 配置里检查
modules是否设为false(尤其@babel/preset-env);设为commonjs会把import编译成require,直接废掉 Tree Shaking - 用构建后 dist 中的 JS 源码搜索该组件库名,看引入语句是否仍是
import,还是已变成__webpack_require__或require
验证组件库是否真正提供可摇动的 ESM 入口
很多 UI 库虽宣称支持 Tree Shaking,但实际入口仍是 main(CommonJS)或 module 字段指向非纯 ESM 文件。
- 查该库
package.json:是否有"exports"字段且包含"import"子字段(优先级最高),或至少有"module": "dist/index.esm.js" - 手动打开其
node_modules/xxx-ui/package.json,确认module或exports.import指向的文件确实是 ES 模块语法(含export,无module.exports) - 警惕 “伪 ESM”:有些库的
.esm.js文件只是把require换成import,但内部仍用Object.assign合并导出,导致所有内容被当成一个对象整体保留
确认副作用标记是否生效
UI 库常含样式注入、全局注册、Polyfill 等副作用,若未明确标注,打包器会保守保留全部代码。
- 查看该库
package.json是否声明"sideEffects": false;若为true或缺失,则整个包默认视为有副作用,无法剔除任何导出 - 若库未声明,你无法控制其
sideEffects,此时必须改用显式子路径导入:import Button from 'xxx-ui/lib/Button'(前提是它提供了这种结构化输出) - 注意:某些库(如早期 Ant Design)虽支持 ESM,但因 CSS 导入等副作用,默认
sideEffects: ["*.css"],此时仅靠命名导入仍可能保留样式相关逻辑
观察实际打包产物是否真包含未用组件
别只信配置,要验证结果。开发模式下看到的体积毫无参考价值。
- 执行真实生产构建(如
npm run build),打开dist下最终生成的 JS 文件(非 source map) - 搜索你未使用的组件名(如
Dialog、DatePicker),确认字符串或函数体是否真实存在 - 用 source-map-explorer 可视化分析各模块占比,定位冗余来源是 UI 库本身,还是它依赖的工具链(如 lodash)











