cssnano报Unexpected token的根源是前置PostCSS插件未处理新语法(如oklch()、@container),而非cssnano本身不支持;需确保postcss-preset-env在cssnano前启用对应feature、browserslist合理、禁用废弃插件、显式配置cssnano preset并严格控制插件顺序与环境分流。

cssnano报Unexpected token是因为新语法没被前置插件处理
报错不是cssnano本身不支持oklch()或@container,而是它前面的PostCSS插件没把它们转成兼容写法,导致cssnano拿到非法token直接崩。比如color: oklch(50% 0.2 240)流到cssnano时还是原样,而v6默认preset根本不认这个函数名。
- 用
npx postcss --verbose resources/css/app.css逐层看输出,确认postcss-preset-env是否在cssnano之前、且生效了 -
postcss-preset-env必须显式启用对应feature:{ 'color-function': true, 'container-query': true },不能只靠stage: 3 -
.browserslistrc必须存在且内容合理,执行npx browserslist确认不含IE11等老环境——否则grid类特性不会降级,反而触发压缩器报错 - 删掉
postcss-cssnext:它已废弃,和postcss-preset-env共存会导致AST解析错乱,静默失败
cssnano配置必须显式传参,不能只写require('cssnano')
v6+版本不接受裸调用require('cssnano'),否则会报Invalid CSS after ""。它要求你明确传入preset对象,哪怕只是{ preset: 'default' }。更重要的是,默认preset里mergeRules和sortSelectors会重排伪类顺序,reduceTransforms可能把transform: translateX(var(--x))误判为无效值直接删掉。
- 最小安全配置是:
require('cssnano')({ preset: ['default', { mergeRules: false, sortSelectors: false, reduceTransforms: false, discardEmpty: false, normalizeWhitespace: false }] }) - 如果用了
postcss-custom-properties,必须加preserve: true,否则变量在替换前就被当成未使用声明删了 - 确保插件顺序严格为:
postcss-import→autoprefixer→cssnano;顺序反了,-webkit-flex就补不上,iOS 12直接布局崩溃
检查压缩后文件是否真保留了var()声明
别光看浏览器表现,先确认压缩器有没有把var(--primary)吃掉。本地构建完,进public/css目录,用grep 'var(--' app.css查——没结果就是压缩阶段丢了;有结果但样式不对,再往下查CDN或HTTP头。
- 临时禁用压缩验证:在
webpack.mix.js里给.options({ css: { safe: true } }),跑npm run dev看public/css/app.css是否完整保留var() - CDN或反向代理可能二次压缩:关掉CDN缓存,直连服务器IP测试,排除中间环节干扰
- 某些构建配置把
postcss-loader放在scss-loader前面,导致cssnano处理的是未编译SCSS语法,直接跳过或报错
Laravel Mix里cssnano必须按环境分流加载
在postcss.config.js顶层写require('cssnano'),会让dev环境也走压缩流程,热更新(HMR)会卡死甚至中断。Laravel Mix的PostCSS链由mix.postCss()控制,必须动态注入。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:在
webpack.mix.js中构造插件数组,只在process.env.NODE_ENV === 'production'时推入cssnano - 或者改用Mix内置的
.minify()(仅限单文件),绕过PostCSS链:mix.postCss('resources/css/app.css', 'public/css').minify('public/css/app.css') - 别碰
MiniCssExtractPlugin.loader的minimize: true:它已废弃,会绕过PostCSS管道,退化成弱压缩,且无法控制discardUnused等行为


















