2010-02-03 2 views
7

여기에 거래 우리는 우리가 압축 할 큰 JS 라이브러리를 가지고 있지만, 그것이 "평가"문을 발견하면 완전히 코드를 YUI compressor 압축하지 않습니다이다 두려움에서 다른 것을 깨뜨릴 것입니다. 위대한 모든,하지만 우리는 eval'd지고 정확히 알고, 그래서 Mootools의 JSON.decode의 평가 문이 있기 때문에 우리는어떻게 자바 스크립트에서 "평가"를 작성하지 않고 "평가"를 실행합니다

그래서 기본적으로 문제는, 거기에 어떤이다이 보수적 싶어하지 않는 eval 함수를 반환하는 표현식을 작성하는 대체 (어쩌면 독창적 인) 방법? 나는 몇 가지를 시도,하지만 주사위 :

window['eval'](stuff); 
window['e'+'val'](stuff); 
// stuff runs in the global scope, we need local scope 

this['eval'](stuff); 
// this.eval is not a function 

(new Function("with(this) { return " + '(' + stuff + ')' + "}"))() 
// global scope again 

어떤 아이디어가? 들으

+0

'eval'은 일반적인 기능으로 간주되지 않으므로 엉망이되고 있습니다. YUI 컴프레서보다 현명 할 지 모르지만, 다른 이름으로'eval'을 호출하지 않거나 곧 호출하지 못하게하는 브라우저를 실행하게됩니다. –

답변

3

감사합니다, 나는 그냥 출력 빌드 스크립트에서 텍스트 교체하고 결국 다른 이름의 함수의 JS는 기본적으로 EVAL $을 eval로 바꾸고 모든 것이 압축 된 후에 수행됩니다. 여기에 내가 무엇을 발견, 나는 순수 JS 방법을 기대했다,하지만 너무 많은 다른 평가 브라우저 구현과, 그냥 디미타르의 대답에

만 평가하지만 기반 두는 것이 좋습니다 일부는 주위를 손보는. 는 이유처럼 보인다 이유 [ '평가'] 작동되지는 Mootools의 JSON.decode에서 일어나는 장소, 또한 내부 해시이기 때문이다 : 나는를 저장하는 경우, 그러나

var JSON = new Hash({ 
// snip snip 
decode: function(string, secure){ 
    if ($type(string) != 'string' || !string.length) return null; 
    if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null; 

    return this.eval('(' + string + ')'); // Firefox says: TypeError: this.eval is not a function 
} 

}); 

"최고 수준의"로컬 범위 (Mootools의를 포함한 모든 코드, 익명 함수 내에서 실행)를 선택한 다음, 그것을 작동 :

var TOP = this; 
var JSON = new Hash({ 
// snip snip 
decode: function(string, secure){ 
    if ($type(string) != 'string' || !string.length) return null; 
    if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null; 

    return TOP.eval('(' + string + ')'); // All good, things run within the desired scope. 
} 

}); 

을하지만이 그래서 결론은, 사파리에서 작동하지 않습니다 내가 무엇을하려고했다 해야 할 일은 교차 호환으로 할 수 없습니다. eval은 특별한 까다로운 함수이며 모든 브라우저가 다르게 처리합니다.

0
var e = "e"; 
window[e+"val"](stuff); 
+0

그래도 작동하지 않으면 모든 것이 글로벌 범위에서 실행됩니다. 또한 이식성이없는 것 같아서, 웹킷 문제 – adamJLev

+0

'window [ "e"+ "val"] (stuff)'? – elcuco

+0

'window.eval === window [ 'eval'] === 창 [ 'e'+ 'val']'그래서 주사위 .. 물건이 우리가 필요로하지 않는 창 범위에서 eval'd를 얻습니다. – adamJLev

0

YUI는 마을의 유일한 게임이 더 이상되지 않기 때문에 당신이 다른 압축 라이브러리 중 하나 시도 할 수 있습니다 가능하면.

다음은 사용 가능한 다른 압축 도구에 대한 몇 가지 기사입니다. http://www.coderjournal.com/2010/01/performance-optimizations-made-by-microsoft-google-and-yahoo-javascript-minimizers/

MS와 구글

  • http://www.coderjournal.com/2010/01/yahoo-yui-compressor-vs-microsoft-ajax-minifier-vs-google-closure-compiler/

      어쨌든 유이보다 더 나은 일을 할 것 같다.

  • +0

    제안을 위해. Google Closure로 게임을 해봤지만 너무 힘들어서 이름을 너무 많이 바꾸고 코드를 어기 게됩니다. 코드가 실행되도록 약간의 시간이 필요하고 아마도 새로운 버그가 생길 것입니다. 그리고 MS 자료를 확인하는 것이 좋겠지 만 Google은 Java/OSX 샵입니다. – adamJLev

    +0

    Google Closure의 트릭은 Simple 압축을 사용하는 것이고 공백을 사용하지 않으면 실패합니다. 어느 것이 안전한 대안이며 모든 공백을 제거합니다. 이것은 아무것도없는 것보다 낫습니다. –

    +0

    그건 YUI와도 비슷 하긴하지만, 그 모든 것을 축소시키고 있습니다. 그러나 evals 때문에 짧은 변수 이름을 긴 변수 이름으로 대체하지 않습니다. – adamJLev

    1

    은 압축 된 파일의 일부가 아닌 일부 외부 심 기능에 대한 평가 호출을 리팩토링 수 있을까요?

    3

    확실하지 난 당신을 이해하지만, 특정 지역 (이) 범위에 함수를 적용 할 경우 :

    var x = 5; 
    
    var f = new Function('alert(this.x)'); 
    
    function A(x){ 
        this.x = x; 
        f.apply(this,[]); 
    } 
    
    a = new A(10); 
    

    이 F로 10 A.this에 적용되는 경고

    1

    내가 무언가를 놓침?

    var noteval = this.eval; // can be defined before the file is loaded 
    noteval("alert('not eval. at all');"); 
    
    (function() { 
        console.log(this); 
        noteval("alert('chavs!');"); 
    }).bind(window)(); 
    
    (function() { 
        console.log(this); 
        noteval("alert('crappy parents');"); 
    }).bind(window.parent)(); 
    

    는 다른 평가의 범위와 프레임 http://www.jsfiddle.net/nGL79/ 확인합니다. Mootools의에

    특정 :

    window["ev"+"al"].pass("alert('what');")(); 
    this["ev"+"al"].pass("alert('no!');")(); // local scope too? 
    

    그 중 일부는 도움이

    var noteval = window["ev"+"al"].create({ 
        bind: this 
    }); 
    

    희망을 ... 당신이 eval 함수를 직접 호출해야하지 않는 희망, 그리고 방법에 의해 모든 아이디어를

    하지만
    +0

    아이디어를 주셔서 감사합니다. 적어도 this.eval이 작동하지 않는 이유를 이해합니다. 내 대답을 한번 보아라. – adamJLev

    0

    이 방법은 jQuery가 필요합니다.

    function NotEval(code, callBack) { 
        $.ajax({ 
         url: 'data:application/javascript;charset=utf-8,' + encodeURIComponent(code), 
         cache:true, 
         success: function (r) { 
          if (typeof callBack === "function") { 
           callBack() 
          } 
         }, 
         error: function (r) { 
          console.log("Eval error"); 
          console.log(r) 
         } 
        }) 
    } 
    
    관련 문제