PostCSS 8+ 要求插件为函数,而 cssnano@4 导出对象导致 TypeError: plugin is not a function;需升级至 v5+ 并改用 require('cssnano'),preset 已默认集成。

为什么直接 require('cssnano') 会报错
PostCSS 8+ 要求所有插件必须是函数,而 cssnano@4 导出的是一个配置对象,不是函数。常见错误是:TypeError: plugin is not a function。
检查当前版本:npm list cssnano。若显示 4.x,必须升级。
-
npm install cssnano@latest --save-dev(v5+ 已内置postcsspeer 依赖) - 旧写法
require('cssnano')({ preset: 'default' })→ 新写法直接require('cssnano') - 配置中不再需要手动传
preset,v5+ 默认启用安全预设
怎样避免 cssnano 合并规则导致样式失效
压缩后 :hover 消失、@media 被删、.btn--primary 和 .btn.is-primary 样式错乱——根本原因是默认开启的高风险合并策略误判了作用域边界。
-
mergeLonghand: false:禁用简写合并(如把margin-top: 10px; margin-bottom: 10px合成margin: 10px 0 10px),防止 JS 动态读取单边距时出错 -
discardDuplicates: false:禁用重复声明删除,BEM 或 CSS Modules 下哈希类名看似重复实则隔离 -
reduceIdents: false:禁用自定义属性重命名,否则--theme-color可能被删或替换,破坏主题切换逻辑
在 postcss.config.js 中显式关闭:
立即学习“前端免费学习笔记(深入)”;
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({
mergeLonghand: false,
discardDuplicates: false,
reduceIdents: false
})
]
}怎样让 cssnano 正确处理 @import 和跨文件冗余
直接拼接多个 CSS 文件再压缩,体积反而更大——因为 cssnano 看不到全局上下文,无法识别跨文件重复选择器或未生效的 @import。
- 必须前置
postcss-import插件,它会在压缩前内联所有@import,让cssnano在单一 AST 上做去重和合并 - 顺序不能错:
postcss-import→autoprefixer→cssnano(autoprefixer必须在cssnano前,否则display: grid等新语法没加前缀就被删了) - 确保 Sass/Less 输出为
--style=expanded(非压缩格式),否则嵌套结构可能被解析失败
怎样保留关键注释不被误删
cssnano 默认删掉所有 /* */,但 /*! license */ 或 /* purgecss start ignore */ 这类注释必须保留,否则构建流程中断或法律风险。
- 用
comment: { preserve: /^!/ }只保留以!开头的注释 - 绝对不要用
preserve: /./全量保留,实测会使压缩后体积增加 15%~20% - 若配合 PurgeCSS,必须确保其指令注释(如
/* purgecss end ignore */)被保留,否则边界识别失败
真正影响体积的关键不在“压得多”,而在“压得准”——尤其是多文件、带变量、有运行时依赖的项目,激进压缩比不压缩更危险。


















