2012-06-09 36 views
14

Js kütüphanem için iyi bir yapı ortamı hazırlamaya çalışıyorum. Web üzerindeki incelemelere göre UglifyJS, NodeJS altında çalışan en iyi sıkıştırma modülleri arasında görünüyor. Yani burada kodunu küçültmek en iyi tavsiye yoludur: Burada görüldüğü gibiUglify-js, değişken isimleri karıştırmıyor

var jsp = require("uglify-js").parser; 
var pro = require("uglify-js").uglify; 

var orig_code = "... JS code here"; 
var ast = jsp.parse(orig_code); // parse code and get the initial AST 
ast = pro.ast_mangle(ast); // get a new AST with mangled names 
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations 
var final_code = pro.gen_code(ast); // compressed code here 

, pro.ast_mangle(ast) değişken isimleri bozmak gerekir, ancak öyle değil. Bu pipetten çıkmış olduğum tek şey, boşluk içermeyen javascript kodu. İlk başta kodumun sıkıştırma için optimize edilmediğini düşündüm, ama sonra Google Closure ile denedim ve oldukça sıkıştırılmış oldum (karışık değişken isimleri ve her şey ile).

UglifyJS uzmanları, yanlış yaptığım şeylere ipucu veriyorlar mı?

GÜNCELLEME:

Gerçek kod burada başvurmak çok büyük, ama böyle bile pasajı parçalanmış almaz: Bu bana seni mi

;(function(window, document, undefined) { 

    function o(id) { 
     if (typeof id !== 'string') { 
      return id; 
     } 
     return document.getElementById(id); 
    } 

    // ... 

    /** @namespace */ 
    window.mOxie = o; 

}(window, document)); 

(sadece boşluk soyulmuş olsun I) tahmin: varsayılan çirkinleştirmek By

(function(window,document,undefined){function o(id){return typeof id!="string"?id:document.getElementById(id)}window.mOxie=window.o=o})(window,document) 
+0

Küçük bir kod parçacığı ve sorun bulduğunuz sonuçları gönderirseniz yardımcı olurum. –

+0

Belki de eksik olduğum bir seçenek var diye düşündüm. Şimdi küçük snippet ile güncellendi.Açıkçası bu benim çevre ile bir şeydir? .. Bu hata ayıklama başlatmaya veya istendiğinde ne çirkinleştirmek-JS parçalamaya yeteneğini etkileyen olabileceği yerleri emin olmasa da. – jayarjo

+1

Eh, UglifyJS web sitesi aracılığıyla, I got:!? '(Function a = "dizesi" typeof (a, b, c) {function d (a) {return a: b.getElementById (a)} a.mOxie = ao = d}) (pencere, belge) 'Doğru anahtarları açtığınızdan emin misiniz? –

cevap

11

Tamam, görünüşe göre Uglify JS'nin en son sürümü, mangle seçeneğinin açık olarak doğru olarak iletilmesini gerektiriyor, aksi halde hiçbir şey karıştırmayacak. Bunun gibi:

var jsp = require("uglify-js").parser; 
var pro = require("uglify-js").uglify; 

var orig_code = "... JS code here"; 
var options = { 
    mangle: true 
}; 

var ast = jsp.parse(orig_code); // parse code and get the initial AST 
ast = pro.ast_mangle(ast, options); // get a new AST with mangled names 
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations 
var final_code = pro.gen_code(ast); // compressed code here 
8

toplevel isimleri bozmak olmaz, belki görmüş thats ne?

Şunları deneyin: -mt veya --mangle-toplevel - üst düzey kapsamdaki mandal adları da (varsayılan olarak bunu yapmıyoruz).

+1

sırası ile ast = uglify.uglify.ast_mangle (AST, {üst düzey olarak: gerçek}); – axkibe

+1

Tüm kodları anonim self-invoking işlevi içine kapsüllü. Sorumu bir snippet ile güncelledim. Ve durumu nasıl ayıklayabilirim? – jayarjo

+1

Thx, benim için çalışıyor –

0

Global kapsamdaki değişkenler, başka bir betik için kullanılabilir, bu nedenle Uglify, onları gerçekten görünür olmalarına gereksinim duyduğunuzda, özel anahtar olmadan değiştirmez. -mt/toplevel anahtarını/ayarını kullanabilir veya daha iyi, ancak, genel kapsamı kirletmeyi durdurabilir ve bu değişkenlerin dışarıda görülmesini istemediğinizi açıkça belirtebilirsiniz, ancak kodunuzu, kimliğinizi anonim, kendi kendine çalışan bir işleve dönüştürecek şekilde belirtebilirsiniz. özel kapsam olarak hizmet eder.

+0

"kodunuzu anonim self-invoking işlevine çerçevelemek" aslında yaptığım şey. Sadece bir üst düzey nesne ortaya çıkar. – jayarjo

+1

Örneğindeki her değişken, dışsal, global kapsamdaki bir değişkendir. –

+1

Evet, dış kapsamdaki değişkenler argüman olarak kendi kendine çalışan anonim işlevine geçirilir. Bu onları mangalı hale getirmez mi (fonksiyonun içinde)? – jayarjo

1

Uglify2 kullanıyorsanız, TopLevel.figure_out_scope()'u kullanabilirsiniz. http://lisperator.net/uglifyjs/scope

Uglify1 kullanıyorsanız, biraz daha karmaşıktır. İşte Uglify's squeeze_more.js file kod değiştirerek araya bazı kod:

function eachGlobalFunctionCall(ast, callback) { 
    var w = uglify.uglify.ast_walker(), 
     walk = w.walk, 
     MAP = uglify.uglify.MAP, 
     scope; 

    function with_scope(s, cont) { 
    var save = scope, ret; 
    scope = s; 
    ret = cont(); 
    scope = save; 
    return ret; 
    } 

    function _lambda(name, args, body) { 
    return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ]; 
    } 

    w.with_walkers({ 
    "function": _lambda, 
    "defun": _lambda, 
    "toplevel": function(body) { 
     return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ]; 
    }, 
    "call": function(expr, args) { 
     var fnName = expr[1]; 

     if (!scope.has(fnName)) { // <--- here's the important part 
     callback(fnName, args, scope); 
     } 
    } 
    }, function() { 
    return walk(uglify.uglify.ast_add_scope(ast)); 
    }); 
} 

sadece yukarıda Bu bir genel fonksiyon çağrılarda çalışır, ancak yürüteç küresel bilinmeyen bir çağrı (bulur olarak size yürütüldüğünde bir geri arama verir) yöntem. Aşağıdaki giriş Verilen örnek için

: Bu çağrıyı bulacağını

function foo() { 
    bar(1); 
    (function() { 
    function bar() { } 
    bar(2); 
    (function() { 
     bar(3); 
    }()); 
    }()); 
} 

bar(1) ama değil bar(2) veya bar(3).