Closure编译器选择性优化?

时间:2014-07-09 05:23:53

标签: javascript google-closure-compiler

我正在使用Google的闭包编译器优化(简单优化)来减少我的一些JS脚本文件的大小。虽然这很好用但我在一些函数中遇到了 eval 语句的问题,其中编译器替换局部变量会造成严重破坏。我可以尝试重新编码有问题的功能以击败编译器,但这可能会很痛苦 - 从长远来看很危险,因为我今天使用的技巧明天可能无法工作。如果我可以简单地标记我希望编译器不受影响的代码位,那就更好了。目前我正在考虑使用所有使用evals的函数,将它们放在一个单独的文件中,并在编译器输出的末尾标记该文件。但是,在我这样做之前,我认为值得在这里问一下 - 有没有办法告诉编译器跳过对某些函数的优化。 e.g。

//  @compilation_level SIMPLE_OPTIMIZATIONS
function test(one,two)
{

}

function testTwo(alpha,beta)
{

}

// @Closure:Skip

function evalFunc(one,two)
{
 //eval code here
}

//@Closure:EndSkip

最终结果 - Skip,EndSkip部分之间的代码在没有任何更改的情况下通过编译器。

我查看了文档,但没有找到任何可能做到的事情。我非常感谢任何帮助

3 个答案:

答案 0 :(得分:1)

documentation中有关于此问题的一些提示。在大多数情况下,提议的跳过功能可能无法解决任何问题,因为编译eval通常会失败。

如果您没有访问evalFunc范围之外的任何变量,您可以尝试使用括号表示法将所有局部变量重构为属性并将所有属性名称放在引号中,这样它们{{3 }}。

例如,

function evalFunc(one) {
    this['foo'] = one;
    eval('alert(foo);');
}
evalFunc.call({}, 1);

将粗略编译为

function(a) {
    this.foo = a; 
    eval("alert(foo);");
};
a.call({}, 1);

保持评估工作。它适用于简单和高级模式。

答案 1 :(得分:1)

谢谢,@ kapep。正如我常常想的那样(当我没有大声思考的时候),这是一个很棒的小论坛!为了其他任何寻求做类似事情的人的利益 - 我需要处理的原始问题是

function evalFunc(leNom)
{
 var str,obj = {'age':18};
 obj.name = leNom;
 str = 'var out = obj.name + " is " + obj.age + " years old"';
 eval(str);
 alert(out);
}

通过Closure的简单优化运行

  function evalFunc(a){eval('var out = obj.name + " is " + obj.age + " years old"');
  alert(out)};

它的表面平坦。

将此更改为

function evalFunc(leNom)
{
 var str;
 this['obj'] = {'age':18};
 this['obj'].name = leNom;
 str = 'var out = obj.name + " is " + obj.age + " years old"';
 eval(str);
 alert(out);
}

和Closure回来了

function evalFunc(a){this.obj={age:18};this.obj.name=a;
eval('var out = obj.name + " is " + 
obj.age + " years old"');alert(out)};

完美无缺!

* ------------------ 一些测试后的脚注。如果像我一样,你无法避免你的JS中的逃避,并希望压缩或以其他方式混淆你的代码,请注意前方的道路上充满了陷阱。只需粗心编辑即可破解您的代码。微软的AJAX minifier提供了对包含evals的代码的更多控制,因此它可能是一个更好的解决方案。但是,到目前为止,最安全的做法是简单地将包含evals OUT的所有函数放在一个单独的文件中并将其标记为压缩输出。在任何编写良好的代码中,具有evals的函数应该相对不常见。这与gzip压缩一起确保了良好的带宽使用,同时避免了压缩后出错的恶意攻击的噩梦。

答案 2 :(得分:0)

如果代码太复杂,你可以使用函数构造函数:

新功能(" a"," b""返回评估(' a + b')");