2014-07-09 146 views
1

我正在使用Google的闭包编译器优化(简单优化)来减少我的一些JS脚本文件的大小。虽然这个效果很好,但我遇到了eval语句,这些语句在我的一些函数中被编译器替换为局部变量破坏了大肆破坏。我可以尝试重新编写违规函数来击败编译器,但这可能会很痛苦 - 并且从长远来看,这是很危险的,因为我今天使用的技巧明天可能无法运行。如果我能简单地标记我希望编译器保持不动的代码位,那将会更好。目前我正在考虑使用所有使用evals的函数,将它们放在一个单独的文件中,并在编译器输出结尾标记该文件。然而,在我这样做之前,我认为这值得在这里问 - 有没有办法告诉编译器跳过对某些函数的优化。例如关闭编译器选择性优化?

// @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部分之间的代码在没有任何更改的情况下通过编译器。

我已经浏览了文档,但还没有发现任何可能做到这一点。我非常感谢任何帮助

+0

[部分跳过使用Google Closure编译器的部分]的重复部分(http://stackoverflow.com/questions/10449195/partially-skip-sections-with-google-closure-compiler) –

+0

供参考:我问过那个问题在github上:https://github.com/google/closure-compiler/issues/1282 – BlaM

回答

1

documentation有几个关于这个问题的提示。提议的跳过功能可能不会解决任何问题,因为编译eval通常会失败。

如果您不访问evalFunc范围之外的任何变量,您可以尝试使用括号表示将所有局部变量重构为属性,并将所有属性名称放在引号中,以便它们won't be renamed

例如,

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

大致会编译为

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

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

+0

编译器应该抱怨危险使用'this'关键字作为例子。最好使用'window'或者明确的对象。 –

+0

这个解决方案似乎是一个非常糟糕的主意。你基本上把所有的值都放到全局范围内,并可能覆盖全局值。 – John

+0

你说得对,我已经添加了一些显式的函数上下文。 – Kapep

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); 
} 

运行是通过封闭的简单优化的线路,你会得到

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); 
} 

和关闭回来了

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缩小器提供了对包含evals的代码的更多控制,因此它可能是更好的解决方案。但是,最安全的做法是简单地将所有包含evals OUT的函数放在一个单独的文件中,并将其标记为压缩输出。在任何写得很好的代码函数中,evals应该是相对罕见的。这与gzip压缩一起确保了良好的带宽使用率,同时避免了压缩后出现错误的恶意代码的噩梦。

+0

看到编译器根本没有碰到字符串,也许你可以通过从一个字符串创建整个函数来把它放在你的优势。 – Robert

0

您可以使用函数构造函数如果代码是不是太复杂:

新功能( “A”, “B”, “返回的eval( 'A + B')”);