在 Webpack 项目迭代过程中,经常会遇到这样一个问题:改了文件名或者调整了 hash 策略后,旧的 bundle 文件依然留在 dist 目录里,时间一长输出目录变得臃肿不堪,甚至可能把过期文件一起部署上线。为了解决这个问题,Webpack 从 5.20 版本开始原生支持 output.clean 配置,用来在生成资产前清理输出目录。很多开发者会有疑问:它到底是在构建前清理,还是构建后清理?清理的范围有多大?会不会误删其他文件?本文将围绕这些问题详细展开。

output.clean 的工作时机与基本用法
首先明确回答标题中的问题:output.clean 并不是在构建开始前清理,而是在构建完成后、向输出目录写入资产之前清理。这个时序非常重要。Webpack 会先完成模块编译、代码分割、生成资产列表等全部工作,确认本次构建成功产出了文件之后,才执行清理动作,随后把新文件写入目录。这样的设计可以避免一种危险情况:如果构建中途失败,而清理已经提前执行,输出目录就会被清空却没有新文件补上,导致线上可用资产丢失。
基础用法非常简单,只需要在 output 对象中添加 clean: true 即可:
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true // 每次构建输出前清理 dist 目录
}
};启用之后,每次执行构建命令,Webpack 都会先输出编译日志,在资产生成阶段清空 output.path 指定的目录,再写入新的文件。你可以在终端中看到类似 cleaning output directory 的提示信息,同时构建摘要里会多出一行 CleanWebpackPlugin 风格的输出,表明清理了多少个文件。需要注意的是,clean 只作用于 output.path 指向的目录,不会影响项目中的其他任何路径,这一点让它的破坏范围可控。
进阶配置:自定义清理规则
clean 选项除了接受布尔值,还可以接受一个对象,用于精细控制清理行为。最常用的是 dry 和 keep 两个参数。dry 设为 true 时只打印将要删除的文件,不真正删除,适合在调整规则时预演效果;keep 接收一个正则表达式或返回布尔值的函数,匹配到的文件会被保留,不被清理。
// webpack.config.js
const path = require('path');
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: {
dry: false, // true 表示只报告不删除
keep: /^(stats|manifest)\.json$/ // 保留 stats.json 和 manifest.json
}
}
};这个场景在实际项目中很常见。比如某些插件会在 dist 目录中额外生成 stats.json 用于体积分析,或者有脚本往输出目录写入版本清单文件,如果这些文件不是 Webpack 资产流水线的一部分,每次清理时就会被删掉。通过 keep 规则可以保护它们。如果需要更复杂的判断逻辑,也可以传入函数形式:keep: (filePath) => !filePath.endsWith('.map'),这样所有 sourcemap 文件都会被保留,方便排查线上问题。
此外还有 verbose 参数控制是否在控制台输出被删除文件的详细日志,默认情况下 Webpack 只在清理的文件数量较多时提示。对于调试清理规则是否生效,建议临时开启 verbose: true 观察。
与 clean-webpack-plugin 的对比及选型建议
在 output.clean 出现之前,社区普遍使用 clean-webpack-plugin 插件来完成同样的工作。两者功能高度重合,但存在一些差异,理解这些差异有助于做技术选型。
| 对比维度 | output.clean | clean-webpack-plugin |
|---|---|---|
| 依赖情况 | Webpack 5.20+ 原生支持,零依赖 | 需要额外安装第三方包 |
| 执行时机 | 资产写入输出目录之前 | 编译开始前的 emit 阶段 |
| 配置方式 | 直接写在 output 对象中 | 通过 plugins 数组引入并实例化 |
| 多编译器场景 | 支持,且可避免并发冲突 | 多 compiler 同时运行时容易误删彼此输出 |
从执行时机上看,插件版本是在编译流程早期触发清理,而原生的 output.clean 更靠后、更安全。对于新项目,只要 Webpack 版本满足要求,优先推荐使用原生配置,减少一个依赖、少一份维护成本。只有在 Webpack 4 等老版本项目中,才需要继续依赖插件方案。
使用中的注意事项
第一,clean 清理的是 output.path 整个目录,如果你把 output.path 误配置到了项目根目录这类危险位置,后果不堪设想。务必确认路径指向专门的构建输出目录。第二,在 watch 模式或 webpack-dev-server 场景下要谨慎:dev server 默认把产物放在内存中而非磁盘,clean 通常不会产生实际影响,但如果配置了 writeToDisk,就可能触发清理逻辑,需要结合 keep 规则避免误删开发期文件。
第二点,多入口或多配置(webpack.config 导出数组)场景下,如果多个配置共用同一个输出目录,每个配置构建时都会执行一次清理,先完成的产物可能被后一个配置清掉。解决办法是为不同配置指定不同的输出子目录,或者只在最后一个配置上开启 clean。第三,如果项目中有 CI 流水线依赖 dist 目录中的历史文件做缓存或对比,启用 clean 前要评估影响,必要时用 keep 保留关键文件。
总结来说,output.clean 是一个安全、轻量、时机合理的输出目录清理方案。它把清理动作放在构建成功之后、写盘之前,配合 dry 和 keep 参数可以覆盖绝大多数项目需求。如果你还在手动删除 dist 目录或者维护着老的清理脚本,不妨升级到这个原生能力,让构建流程更简洁可靠。
Webpackoutput.clean构建清理修改时间:2026-09-02 00:00:37