DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

webpack 压缩后圆角消失,检查 CSS 变量 calc 运算符空格

webpack 内置 CSS 压缩曾删掉自定义属性 calc 加减号前的空格,导致变量替换后的值无效。5.111.1 包含修复,也可暂时只禁用这类 CSS 压缩。

升级 webpack 后,Bootstrap 卡片、弹窗或菜单的圆角突然变成直角,而生产构建与控制台都没有错误,可以检查生成 CSS 中自定义属性的 calc()。一个关键差异是运算符前面的空格:

/* 原样式 */
.card {
  --radius: 8px;
  --width: 1px;
  --inner-radius: calc(var(--radius) - var(--width));
  border-radius: var(--inner-radius);
}
/* 受影响输出片段 */
/* --inner-radius:calc(var(--radius)- var(--width)) */

calc() 中的加减运算需要两侧空白。自定义属性本身可以保存很宽泛的 token 序列,所以错误字符串未必在构建时被拒绝;等 border-radius 使用它时,计算值无效,样式就可能回到初始值。只搜索“CSS 语法错误”日志很容易错过这种故障。

具体受影响的原报告核过 webpack 5.110.0、5.110.3 和 5.111.0;环境包含 Node 24.10.0、macOS ARM64,浏览器后果在 Chrome 中确认。5.109.2 的这条构建路径尚未压缩 CSS,因而不能把它的正常结果解释成所有旧 CSS 压缩器都正确。

问题发生在自定义属性的原样 token 打印分支:它把闭合括号旁的空白当成可以删除的分隔符,没有保留数学运算所需的空白。普通 width: calc(100% - 10px) 可以正常输出,所以单独验普通声明不足以排除该问题。

webpack 5.111.1 包含保留这类空白的修复。先固定实际参与构建的版本,再生成生产资产:

npm install -D webpack@5.111.1
npm ls webpack
npm run build

使用项目原来的构建脚本,保留 loader、抽取插件与生产优化条件。不要只看 package.json 写了什么范围;如果构建入口使用另一份工作区依赖,版本检查应在那个入口完成。

暂时不能升级时,可以只停用 webpack 内置的 CSS 压缩:

module.exports = {
  mode: 'production',
  optimization: {
    minimizeOptions: { css: false },
  },
};

把这一项合并到已有优化配置中。这不会关闭内置 JavaScript 压缩,但若项目另外注册了会处理 CSS 的第三方 minimizer,还要检查那条处理链。不要用开启更多自定义属性重写作为通用补救,它会改变另一组转换行为。

重新构建后,查看 --inner-radius 等自定义属性中 +、- 两侧的空白,再在实际组件上读取计算样式。上面的示例,在变量值不被其他规则覆盖时,应得到 7px 的圆角;还应保留一个普通 calc() 声明作为对照。最后检查原页面的卡片、菜单和弹窗,而不是仅确认 CSS 文件能够下载。

这条修复解决自定义属性的压缩打印问题。若生成值正确而圆角仍为零,应继续检查变量覆盖、层叠与组件规则;若另一台设备不支持所用 CSS 表达式,单纯保留空格也不会增加浏览器支持。