Less编译OOM主因是3.9.x–3.10.2版本存在递归失控缺陷,解析自引用变量或mixin自调用时无深度保护,导致AST爆炸;升级至3.13.1+可修复。

Less 编译卡死或报 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory,大概率不是你代码写错了,而是 Less 解析器在处理某些语法结构时触发了内部递归失控或无限展开逻辑 —— 尤其发生在 3.10.3 以下版本。
Less 3.9.x ~ 3.10.2 存在已知的内存爆炸 bug
旧版 Less(尤其是 3.9.* 到 3.10.2)在解析带深层嵌套、变量递归引用、或某些混合(mixin)调用链时,会陷入非终止的 AST 遍历。这不是你写的 .less 文件本身有死循环,而是解析器在求值过程中没设递归深度保护。
- 典型诱因:
@color: darken(@color, 10%);这类自引用变量(即使写在不同文件里,经@import后也会被串联) - 另一个高危模式:
.btn { &:hover { .btn(); } }—— mixin 自调用 + 选择器嵌套,旧版解析器会反复展开直到堆溢出 - Ant Design 项目中尤其常见,因为其主题变量和覆盖逻辑大量依赖动态计算和多层
@import
如何快速验证是不是 Less 版本问题
不用重装整个构建链,先确认当前 Less 版本:
npm list less
如果输出是 less@3.9.0、less@3.10.1 等,基本可以锁定。再试一个最小复现:
- 新建
test.less,只写一行:@a: darken(@a, 5%); - 执行:
npx lessc test.less - 如果卡住或报
heap out of memory,就是它了
升级到 less@^3.13.1 或更高(如 4.2.0)后重试,该问题会消失 —— 新版加了 max-call-stack 限制和变量循环检测。
升级 Less 后仍偶发内存溢出?检查 Webpack / react-scripts 的封装层
很多项目用 react-scripts 或 webpack + less-loader,它们可能锁死了内部 Less 版本,导致 npm install less@latest 无效。
- 查
node_modules/react-scripts/node_modules/less是否存在,存在则说明被覆盖了 - 强制覆盖:运行
npx npm-force-resolutions(需package.json中有"resolutions": {"less": "4.2.0"}) - 或改用
less-loader显式指定:options: { lessOptions: { math: 'always' } }(math: 'always'可避免部分表达式延迟求值引发的嵌套加深)
真正麻烦的从来不是“怎么加内存”,而是“为什么加了内存还是崩”——旧版 Less 的递归失控是纯 CPU+内存双耗型问题,--max_old_space_size=8192 只会让它晚几秒崩,不会改变根本行为。盯住版本号,比调参管用十倍。











