Less 中不能直接执行 JavaScript 表达式,所有变量和函数均为编译期求值;唯一安全的 JS 与 Less 协作方式是通过 less.modifyVars() 注入预计算的变量值,严禁启用 javascriptEnabled。

Less 里不能直接写 JavaScript 表达式
Less 的 @ 变量、darken()、percentage() 等函数都是编译期求值的,底层用的是 Less 自己的解析器和函数系统,不是 JS 引擎。你写 @width: 100 / 2 + 'px'; 是合法的,但写 @width: `${Math.random() * 100}px`; 或 @width: document.body.offsetWidth + 'px'; 会直接报错 —— ParseError: Unrecognised input。
想在 Less 中“调用 JS”,实际只有两个入口点
一个是浏览器端运行时通过 less.modifyVars() 注入变量值;另一个是 Node.js 构建阶段用 less.render() 传入 javascriptEnabled: true(已废弃且极度危险)。
-
javascriptEnabled: true在 Less 4.0+ 中默认禁用,启用后允许@{js: ...}语法,但会把字符串当作 JS 执行,存在任意代码执行风险,生产环境绝对禁止开启 -
less.modifyVars()是唯一安全、可控的 JS → Less 通道,它只接受纯对象映射,不执行代码,只覆盖变量值 - 如果你真需要动态计算(比如基于 viewport 宽度算栅格列宽),应该在 JS 里算好再传进去:
less.modifyVars({ '@grid-columns': String(Math.min(12, Math.floor(window.innerWidth / 80))) })
嵌套中使用 JS 计算值?别这么干
常见误区:以为可以在 &:hover { width: @{js: window.innerWidth}; } 这类嵌套规则里混 JS。这既不合法,也不可行 —— Less 编译发生在 CSS 生成之前,DOM 和 window 都还不存在。
- 所有样式逻辑必须在编译前确定或在运行时由 JS 显式注入变量
- 需要响应式尺寸?用 CSS 原生方案:
clamp()、vw单位、@media查询 - 需要用户交互驱动的样式变化?用 JS 切换 class,然后在 Less 里预定义好对应 class 的样式块,例如
.theme--dark { @primary-color: #1e1e1e; }
真正安全的“JS + Less”协作路径
核心原则:JS 负责“决策”和“传参”,Less 负责“表达”和“编译”。两者边界必须清晰。
立即学习“Java免费学习笔记(深入)”;
- 在 HTML 中引入
<link rel="stylesheet/less" href="main.less">和<script src="https://cdn.jsdelivr.net/npm/less@4"></script>(开发阶段) - 在 JS 中收集环境信息(主题偏好、设备类型、权限等级),整理成扁平 key-value 对象
- 调用
less.modifyVars()一次性注入,避免高频调用(否则触发多次编译,卡顿明显) - Less 文件里只用标准语法:
@primary-color、.btn { background: @primary-color; },不掺任何 JS 片段
最易被忽略的一点:修改变量后必须等 less.modifyVars().then() 完成再操作 DOM,否则样式可能还没生效就去读 getComputedStyle,拿到的是旧值。


















