标准答案

  1. Tree Shaking 的基础是静态分析 import/export,ES Module 比 CommonJS 更容易被分析。
  2. 构建工具要能判断某段导出没有被使用,并在压缩阶段删除不可达代码。
  3. 包的 sideEffects 标记会影响构建工具是否可以安全删除未使用模块。
  4. 模块顶层执行副作用、修改全局对象、自动注册组件、引入 CSS 等行为都会让删除变得更谨慎。
  5. 动态 require、命名空间整体导入后动态访问、错误的构建产物格式都会削弱 Tree Shaking 效果。

题目解析

Tree Shaking 不是“没 import 就删掉”这么简单。构建工具要能静态看懂模块关系,还要敢判断某个文件执行后不会改变外部环境。

很多没有被显式调用的代码仍然会留下来,是因为它所在文件有顶层副作用,比如自动注册组件、改全局对象、引入样式或执行 polyfill。工具无法证明删除安全时,通常会选择保守保留。

排查时不要只盯源码。打开 bundle 分析结果,看包入口、sideEffects、导入写法和最终压缩产物,才能知道问题卡在静态分析还是副作用判断。

代码示例

sideEffects 可以告诉构建工具哪些文件不能直接删除。

JSON
{
  "module": "dist/index.mjs",
  "sideEffects": [
    "**/*.css"
  ]
}

常见误区

  • 认为只要使用 import/export,Tree Shaking 就一定完全生效。
  • 把有副作用的入口标成 sideEffects: false,导致样式或注册逻辑被错误删除。
  • 只看源码是否引用,没检查最终 bundle 里到底保留了什么。

作者信息