JavaScript中的LESS似乎蹒跚作响:解决方法?

我发现LESS有一个懒散的JavaScript评估器,至less是我使用它的方式,也就是在将客户端上传到Web服务器之前,将* .less文件编译成* .css文件。

我知道,编译可能更经常在服务器端完成,但为了性能和简单性,我们只需要服务器上的CSS文件。 我正在编译Fedora Linux上的LESS文件,并在这些指令中安装了lessc ruby gem安装到Node Package Manager中。

编译器工作正常,但据我所知,JavaScriptexpression式评估非常有限。 我相信这也适用于基于此发布的服务器端JavaScriptexpression式评估, 这表明了JavaScript引擎如何插入到LESS环境中的不确定性。

我可以使用的只是简单的,逗号分隔的expression式,如下所示:

 @bar: ` "ignored-string-expression" , 5 `; div.test-thing { content: ~"@{bar}"; } 

编译成:

 div.test-thing { content: 5; } 

当我尝试定义一个函数时,编译器barfs(无论expression式中的分号是否反斜线):

 [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()` ... 

也似乎没有任何循环的方式,即使你试图欺骗它评估一个循环,就像你上面的“ignored-string-expression”一样,如:

 @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==); 

使用这样的程序 ,不pipealgorithm是用JavaScript,PHP,Perl,UNIX shell还是其他的东西来实现的。 这个处理可能没有函数定义,但没有循环,没有函数甚至不能recursion。

鉴于函数和循环都是复合语句,可能不被评估为expression式(它不是LISP),这可能是失败的基础…它不是一个完全的JavaScript解释器。 所以我希望一个真正了解LESS编译器的人能够:

  • 澄清以上的限制,所以我可以使用JavaScript和LESS portably这个任务
  • 说出这个问题是如何解决的(例如,用“shell逃生”或任何可以迭代处理string的评估环境)和/或
  • 说如何用这样的文本处理能力来扩展LESS编译器,比如“真正的”JavaScript引擎。

我认为你所寻找的是一个关于在LESS中使用JavaScript的一些令人沮丧的事情的混合物。

  1. 所有的JavaScript必须在一行。 (我…甚至不..什么的。)
  2. 所有的JavaScript必须返回的东西,或者你得到完全无用的错误“无法读取属性值的未定义”
  3. 所有的JavaScript必须是一个声明。 这来自原来的用例,他们认为你会做像@foo:〜'something.javascript.is.good.at({@ bar});'

数字1是格式化的,2意味着即使你不使用它也需要返回一些东西,但是数字3会让很多人望而生畏。 为了解决这个问题,只要让你“一件事”成为一个自我执行的匿名函数。

例如:

 (function(){ do.some.cool.stuff(); other.cool.things(); return('Fry'); })(); 

因此,LESSparsing器会看到(确保它全部在一行中,而不是我写的!),将其作为单个执行绑定到javascript地址,读取返回值,并将其称为一天。

如果你想看到它的实际效果,我最近写了LESS mixin来制作RGBA 1×1像素的背景填充等,这些都使用了这种疯狂。

希望有所帮助!

data-uri()函数现在被构build到LESS中:

http://lesscss.org/functions/#misc-functions-data-uri

这会有帮助吗?

我知道这个职位是几年,但JavaScriptembedded在LESS可以非常方便,所以我虽然我会发布一些提示:

  //All javascript must // a. be on the rhs of an assignment eg @x:` var x = @{val}+7`; // b. must evaluate to a value // c. cannot be terminated by a ';' // // To get around this, multiline code can be packed into an IIFE...... @val:7; @loop:`(function(val){ var sum=0; for(var i=0; i<val; i++){sum+=i;} return sum; } )(@{val})`; .test{ content:@loop; // content: 21; } // console.log writes directly to the beginning of the output file @x:`console.log('/*...... loop = @{loop}.......*/')`; // /*...... loop = 21.......*/ // you can use the global variable. Here we attach a library module to it..... @x:`global.myLib={}`; // Then add a method to the module.............. @btoa:`myLib.btoa=function(str){ var buffer = new Buffer((str).toString(), 'binary'); return buffer.toString('base64'); }`; // And invoke the method to encode some text............................ @sometext:'LESS is more (more or less)'; .test2{ content:`myLib.btoa(@{sometext})`;// content: "TEVTUyBpcyBtb3JlIChtb3JlIG9yIGxlc3Mp"; }