Javascript在LESS中显得步履蹒跚:解决方案?

Javascript在LESS中显得步履蹒跚:解决方案?,javascript,css,node.js,svg,less,Javascript,Css,Node.js,Svg,Less,我发现LESS有一个蹒跚的JavaScript求值器,至少我使用它的方式是,在将*.LESS文件上传到web服务器之前,在客户端将其编译成*.css 我知道编译可能更多地是在服务器端完成的,但为了性能和简单性,我们只希望服务器上有CSS文件。我在FedoraLinux上编译较少的文件,并将lesscruby gem安装到节点包管理器中,如中所示 编译器工作得很好,但据我所知,JavaScript表达式的计算非常有限。我相信这也适用于服务器端JavaScript表达式评估,基于此评估,JavaSc

我发现LESS有一个蹒跚的JavaScript求值器,至少我使用它的方式是,在将*.LESS文件上传到web服务器之前,在客户端将其编译成*.css

我知道编译可能更多地是在服务器端完成的,但为了性能和简单性,我们只希望服务器上有CSS文件。我在FedoraLinux上编译较少的文件,并将
lessc
ruby gem安装到节点包管理器中,如中所示

编译器工作得很好,但据我所知,JavaScript表达式的计算非常有限。我相信这也适用于服务器端JavaScript表达式评估,基于此评估,JavaScript引擎如何插入到更少的环境中存在不确定性

我只能使用简单的逗号分隔表达式,如下所示:

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

div.test-thing {
  content: 5;
}
当我试图定义一个函数时,编译器会发出barfs(无论表达式中的分号是否为反斜杠转义):

似乎也没有任何循环方式,即使您试图像上面的“忽略的字符串表达式”一样欺骗它来计算循环,例如:

@foo: `x = 0,
for (var n = 0; n <= 10; n++) { x++; },
x
`;
div.test-thing { content: ~"@{bar}"; }
何必费事?为了能够少编译此文件:

@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>';
使用,不管该算法是用JavaScript、PHP、Perl、UNIX shell还是其他语言实现的。这种处理可以在没有函数定义的情况下完成,但不能没有循环,没有函数甚至不能有递归

鉴于函数和循环都是复合语句,可能不会作为表达式进行计算(它不是LISP),这可能是失败的基础。。。它不是一个完整的JavaScript解释器。所以我希望真正了解较少编译器的人会:

  • 澄清上面的限制,这样我就可以使用JavaScript来完成这项任务&不易移植
  • 说明如何解决此问题(例如,使用“shell转义”或任何可以迭代处理字符串的评估环境)和/或
  • 说明如何使用这种文本处理功能(如“真正的”JavaScript引擎)扩展LESS编译器

我想你想要的是一堆关于在更少的时间内使用javascript的令人沮丧的小事情的混合体

  • 所有javascript必须在一行上。(我……甚至……不管怎样。)
  • 所有javascript都必须返回一些内容,否则会出现完全无用的错误“无法读取未定义的属性'value'”
  • 所有javascript必须是一条语句。这源于最初的用例,他们认为您应该执行@foo:~'something.javascript.is.good.at({@bar});' 第一个是格式化,第二个只是意味着即使你不使用它,你也需要返回一些东西,但是第三个让很多人措手不及。要绕过它,只需将“一件事”设置为一个自动执行的匿名函数

    例如:

    因此,较少的解析器看到了这一点(确保所有内容都在一行中,而不是我是如何编写的!),将其作为单个执行捆绑到javascript land,读取返回值,并在一天内调用它

    如果你想看到它的实际应用,我最近写了一篇关于减少混音的文章,用了所有这些疯狂的东西

    希望有帮助

    data-uri()函数现在内置在以下内容中:


    这会有帮助吗?

    我知道这篇文章已经有好几年的历史了,但是嵌入较少内容的javascript非常方便,所以我想我会发布一些提示:

     //All javascript must 
     // a. be on the rhs of an assignment   e.g.  @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";
     }
    
    //所有javascript都必须
    //a。位于赋值的右侧,例如@x:`var x=@{val}+7`;
    //b。必须评估为一个值
    //c。不能以“;”结尾
    //
    //为了解决这个问题,可以将多行代码打包到一个iLife中。。。。。。
    @val:7;
    @循环:`(函数(val){
    var总和=0;
    
    对于(var i=0;我不知道如何修复LESS编译器,但生成SVG背景的想法是天才!你非常善良@Duopixel-准备好波尔卡虚线按钮和糖果条菜单。如果LESS不支持,我将不得不添加第二阶段编译器,一个从站点构建Makefile运行的脚本,以从LESS m转换假样式类似于
    pseudo gradient:#COLOR1#COLOR2
    的IXIN插入到相应的base64编码SVG背景属性中。任何需要字符串处理的CSS功能过于复杂而无法用较少的字符串处理,都可以在第二阶段编译器中处理。光荣的发现:Node.js中较少包的JavaScript引擎支持
    escape()
    function。因此,更少的代码看起来像:
    background:~`“url(数据:image/svg+xml,“+escape(@{svgSource})+”)”`
    。这意味着具有可变功能的SVG图像可以用更少的资源编码为数据URI;除非您确实需要base64编码或其他更复杂的字符串处理,否则不需要其他预处理器。很好!但未编码的
    SVG
    仅受Webkit支持。背景:~
    “url(数据:image/SVG+xml;base64,”+新缓冲区(@{svgSource}).toString('base64')+”)“
    ;工作?自从我的转义或URI编码(不是base64编码)以来,我仔细检查了IE9限制SVG背景在IE9中工作得非常好,只是我做了第一次更改。根据IE9对数据URI的唯一限制是字符串大小。我认为您提到的区别在于。无论如何,轮到我惊讶于
    缓冲区。toString
    构造工作得非常好!
    @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>';
    
    background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgeDE9IjAiIHkxPSIwIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzU3OWRkYiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAwMjIiIC8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIiAvPjwvc3ZnPg==);
    
    (function(){
        do.some.cool.stuff(); 
        other.cool.things();
        return('Fry');
    })();
    
     //All javascript must 
     // a. be on the rhs of an assignment   e.g.  @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";
     }