我发现 LESS 有一个笨拙的 JavaScript 评估器,至少我使用它的方式是,在将 *.less 文件上传到 Web 服务器之前在客户端上将它们编译成 *.css。
我知道编译可能更经常在服务器端完成,但为了性能和简单性,我们只希望服务器上的 CSS 文件。我在 Fedora Linux 上编译 LESS 文件,并按照这些说明lessc
将ruby gem 安装到节点包管理器中。
编译器运行良好,但据我所知,JavaScript 表达式评估非常有限。我相信这也适用于基于此帖子的服务器端 JavaScript 表达式评估,这表明 JavaScript 引擎如何插入 LESS 环境的不确定性。
我只能使用简单的逗号分隔表达式,如下所示:
@bar: `
"ignored-string-expression"
,
5
`;
div.test-thing { content: ~"@{bar}"; }
编译成:
div.test-thing {
content: 5;
}
当我尝试定义一个函数时,编译器会出错(表达式中的分号是否被反斜杠转义):
[719] anjaneya% cat testfunc.less
@bar: `function foo() {return 5}; foo()`;
div.test-thing { content: ~"@{bar}"; }
[720] anjaneya% lessc testfunc.less
SyntaxError: JavaScript evaluation error: `function foo() {return 5}; foo()` ...
似乎也没有任何循环方式,即使您尝试像上面的“忽略字符串表达式”那样尝试欺骗它来评估循环,例如:
@foo: `x = 0,
for (var n = 0; n <= 10; n++) { x++; },
x
`;
div.test-thing { content: ~"@{bar}"; }
其中说:
ParseError: Syntax Error on line 1 ...
何必? 为了能够编译这个 LESS:
@svgSource: '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="@{start}" /><stop offset="1" stop-color="@{end}" /></linearGradient><rect x="0" y="0" width="100%" height="100%" fill="url(#g)" /></svg>';
进入这个 CSS:
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgeDE9IjAiIHkxPSIwIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzU3OWRkYiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAwMjIiIC8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIiAvPjwvc3ZnPg==);
使用这样的程序,无论算法是用 JavaScript、PHP、Perl、UNIX shell 还是其他任何方式实现的。这种处理可以在没有函数定义的情况下完成,但在没有循环的情况下也可以完成,没有函数你甚至不能有递归。
鉴于函数和循环都是复合语句,可能不会被评估为表达式(它不是 LISP),这可能是失败的基础......它实际上并不是一个完整的 JavaScript 解释器。所以我希望真正了解 LESS 编译器的人会:
- 澄清上面的限制,所以我可以便携地使用 JavaScript 和 LESS 来完成这个任务
- 说明如何解决这个问题(例如,使用“shell 转义”或任何可以迭代处理字符串的评估环境)和/或
- 说一下如何用这种文本处理能力来扩展 LESS 编译器,就像一个“真正的”JavaScript 引擎。