less 中 js 表达式(如反引号包裹的代码)默认被禁用,因 modern 构建工具(less-loader@7+、vite 5+、lessc v4.2+)已默认关闭 javascriptenabled,属主动安全策略,非配置遗漏;启用等同开放 node.js 命令执行,生产环境严禁。

Less 中的 JS 表达式(如 @size: unit(10px / 2, px) 或 @color: `colorPalette('${@primary}', 'light')`)在现代构建工具中被拦截,根本不是“安全策略升级”或“配置遗漏”,而是因为 javascriptEnabled 默认关闭 + 构建工具显式禁用执行上下文。
less-loader@7+ 和 Vite 的默认行为已彻底移除 JS 执行能力
Webpack 5 + less-loader@8.3.0、Vite 5+ 的 less 预处理器默认将 javascriptEnabled 设为 false,且不再提供降级开关。这不是 bug,是明确的安全决策——JS 表达式允许任意 Node.js 代码执行(比如 @x: `require('fs').readFileSync('/etc/passwd')`),构建阶段一旦启用,等于开放命令执行入口。
- 错误现象:编译不报错,但
@color: `hex(${@base})`直接输出为未解析的字符串,CSS 里出现color: `hex(#007bff)` - 检查方式:在编译产物 CSS 中搜索反引号
`或require(,若残留说明 JS 没执行;若整行消失或报Unrecognised input,说明 parser 在词法层就拒了 - Vite 用户注意:
css.preprocessorOptions.less.javascriptEnabled是无效字段,必须写进modifyVars同级的lessOptions(Vite 5.4+ 要求)
Ant Design 等库仍依赖 JS 表达式,但仅限特定写法
像 .bezierEasingMixin() 这类 AntD 内置 mixin,底层用了 ~"cubic-bezier(...)" 这种带波浪号的字符串插值,它不触发 JS 执行引擎,只做字面量拼接。真正被拦截的是含括号调用、require、process、Math 等运行时对象的表达式。
- 能过:
@ease: ~"cubic-bezier(0.2, 0, 0, 1)";(波浪号逃逸) - 被拦:
@ease: `cubic-bezier(${@a}, ${@b}, ${@c}, ${@d})`;(反引号触发 JS 解析) - 替代方案:把计算逻辑提到 JS 层,用
modifyVars注入结果值,例如{ '@ease': '"cubic-bezier(0.2, 0, 0, 1)"' }
命令行 lessc 工具也默认禁用,除非显式传参
lessc 从 v4.2.0 开始,默认关闭 JS 支持。你写的 lessc main.less > out.css 不会执行任何反引号内容——即使文件里有 @x: `Date.now()`,输出也是空或报错。
- 临时启用(仅开发):
lessc --javascript-enabled main.less > out.css - 生产环境禁止:CI/CD 流水线中若发现该 flag,应直接 fail —— 它违背零信任构建原则
- 注意:Webpack/Vite 配置里的
javascriptEnabled: true若生效,等价于命令行加了这个 flag,风险等级相同
真正难处理的不是“怎么开”,而是“哪些 JS 表达式其实可以不用”。Less 6.0+ 的 if()、percentage()、darken() 全部是纯函数,不依赖 JS 引擎;所有需要 require 或 fetch 的逻辑,都应该剥离到构建脚本里预计算再注入变量——这才是现代 Less 工程化的分界线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











