为什么ES模块中导入的CSS无法被Tree Shaking删除?
我在用ES Module打包项目时,发现导入的CSS文件里没用到的样式始终被包含在最终包里。比如我在组件里只用了.button-primary,但整个CSS文件都被打包了,这是为什么呢?
我试过在Webpack里配置了sideEffects: false,也确认用了ESM语法。但像下面这样的CSS文件里未引用的类还是会被带上:
.button-primary {
background: blue;
}
.button-secondary {
background: red;
}
.button--disabled {
opacity: 0.5;
}
难道CSS不能被Tree Shaking?或者需要额外配置?
简单说,JS 的 Tree Shaking 是基于**导入导出语法**和**实际引用关系**来判断代码是否无用。但 CSS 没有“引用”这个概念,你导入一个 CSS 文件,它就相当于在页面上加了个
标签,影响的是全局样式表。Webpack 没法判断哪些类名在 JS 中被“用到了”,哪些没有,它只能保守地把整个 CSS 文件打包进去。你说你配置了
sideEffects: false,这只能告诉 Webpack 这个模块没有副作用,可以尝试删除,但 Webpack 无法判断 CSS 内容是否真的无用,所以没用。### 血泪教训:
我以前也试过指望 Tree Shaking 干掉没用的 CSS,结果上线后发现样式没生效,查了半天才发现被 Shaking 掉了,哭都来不及。
### 解决办法:
如果你真想干掉没用的 CSS,得用专门的工具,比如:
- **PurgeCSS**(或现在叫 [PurgeCSS by Tailwind Labs](https://purgecss.com/))
- 或者使用像 **Tailwind CSS** 这种自带 Purge 功能的框架
它们会分析你 HTML 或 JS 中用到了哪些类名,然后从最终 CSS 中删除没用到的样式。
Webpack 做不到这点,别难为它了。
### 总结:
- CSS 不能 Tree Shaking 是机制决定的
- Webpack 没法分析类名是否被用到
- 真要删无用 CSS,用 Purge 类工具
希望你别再在这块儿踩坑了 😅
purgecss-webpack-plugin插件来清理未使用的CSS。记得安装插件:
npm i -D purgecss-webpack-plugin。