2012-06-09 20 views
14

मेरी जेएस लाइब्रेरी के लिए अच्छा निर्माण वातावरण तैयार करने की कोशिश कर रहा है। वेब UglifyJS पर समीक्षाओं के मुताबिक, नोडजेएस के तहत काम कर रहे सबसे अच्छे संपीड़न मॉड्यूल में से एक प्रतीत होता है। तो यहाँ कोड को कम करने का सबसे अच्छा तरीका है सिफारिश:Uglify-js परिवर्तनीय नामों को मंगल नहीं करता

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) चर नाम वध करना चाहिए, लेकिन ऐसा नहीं है। मैं इस पाइप से बाहर निकलता हूं, बिना किसी रिक्त स्थान के जावास्क्रिप्ट कोड है। पहले मैंने सोचा था कि मेरा कोड संपीड़न के लिए अनुकूलित नहीं किया गया था, लेकिन फिर मैंने Google Closure के साथ इसे आजमाया और काफी संपीड़न (मैंगलेड वैरिएबल नाम और सब कुछ के साथ) मिला।

UglifyJS विशेषज्ञ, क्या मैं गलत कर रहा हूं के लिए कोई संकेत?

अद्यतन:

वास्तविक कोड यहाँ संदर्भ के लिए बहुत बड़ी है, लेकिन फिर भी इस तरह एक टुकड़ा घायल नहीं मिलता है:

;(function(window, document, undefined) { 

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

    // ... 

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

}(window, document)); 

यह मैं क्या मिलता है (केवल रिक्त स्थान छीन लिया हो मुझे लगता है):

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

मुझे लगता है कि अगर आप कोड का एक छोटा सा स्निपलेट पोस्ट करते हैं और परिणाम जो आपको समस्याएं मिलती हैं तो इससे मदद मिलेगी। –

+0

मैंने सोचा कि शायद कुछ विकल्प था जो मैं याद कर रहा था। छोटे स्निपेट के साथ अब अपडेट किया गया।जाहिर है यह मेरे पर्यावरण के साथ कुछ है? .. हालांकि यह सुनिश्चित नहीं है कि इसे डिबग करना शुरू करना है या जब अनुरोध किया जाता है, तो उलझाने की क्षमता को प्रभावित करने के लिए क्या हो सकता है। – jayarjo

+1

ठीक है, UglifyJS की वेबसाइट के माध्यम से, मुझे मिला: '(फ़ंक्शन (ए, बी, सी) {फ़ंक्शन डी (ए) {वापसी प्रकार एक! = "स्ट्रिंग"? ए: बी .getElementById (ए)} a.mOxie = एओ = डी}) (खिड़की, दस्तावेज) 'क्या आप वाकई सही स्विच चालू कर चुके हैं? –

उत्तर

11

ठीक है, ऐसा लगता है कि Uglify JS के नवीनतम संस्करण को मैंगल विकल्प को स्पष्ट रूप से सत्य के रूप में पारित करने की आवश्यकता है, अन्यथा यह कुछ भी उलझन में नहीं होगा। इस तरह:

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

डिफ़ॉल्ट रूप से uglify अपूर्ण नामों को उलझाना नहीं होगा, शायद आपने जो देखा है?

आज़माएं: -mt या --mangle-toplevel - उलझन में भी मैंगल नाम (डिफ़ॉल्ट रूप से हम ऐसा नहीं करते हैं)।

+1

respecively ast = uglify.uglify.ast_mangle (ast, {toplevel: true}); – axkibe

+1

मेरा पूरा कोड अज्ञात स्व-चालान फ़ंक्शन में समाहित है। मैंने एक स्निपेट के साथ अपना प्रश्न अपडेट किया। और संकेत कैसे मैं स्थिति को डीबग कर सकता हूं? – jayarjo

+1

Thx, मेरे लिए काम करता है –

0

वैश्विक दायरे में चर किसी भी अन्य स्क्रिप्ट के लिए उपलब्ध हैं, इसलिए अगर आपको वास्तव में दिखाई देने की आवश्यकता हो तो उग्लिफ़ उन्हें विशेष स्विच के बिना नहीं बदलेगा। आप या तो -mt/toplevel स्विच/सेटिंग का उपयोग कर सकते हैं, या बेहतर, अभी भी, वैश्विक दायरे को प्रदूषित करना बंद कर सकते हैं और स्पष्ट रूप से इंगित करते हैं कि आप उन चरों को बाहर देखने के लिए इरादा नहीं रखते हैं, लेकिन आपके कोड को अज्ञात स्व-चालान फ़ंक्शन में फ़्रेम करेंगे निजी दायरे के रूप में काम करते हैं।

+0

"अज्ञात स्व-चालान समारोह में अपना कोड तैयार करना" यही वह है जो मैं वास्तव में करता हूं। केवल एक शीर्ष स्तर वस्तु का खुलासा किया गया है। – jayarjo

+1

आपके उदाहरण में प्रत्येक चर बाहरी, वैश्विक दायरे से एक चर है। –

+1

हां, बाहरी दायरे से वेरिएबल के रूप में स्वयं-invoking अज्ञात कार्य में पारित कर रहे हैं। क्या यह उन्हें मैंगलिंग (फ़ंक्शन के अंदर) के लिए उपलब्ध नहीं बनाता है? – jayarjo

1

यदि आप Uglify2 का उपयोग कर रहे हैं, तो आप TopLevel.figure_out_scope() का उपयोग कर सकते हैं। http://lisperator.net/uglifyjs/scope

यदि आप Uglify1 का उपयोग कर रहे हैं, तो यह थोड़ा और जटिल है। यहाँ मैं Uglify's squeeze_more.js file से कोड को संशोधित करके एक साथ रखा कुछ कोड है:

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

केवल ऊपर यह एक वैश्विक फ़ंक्शन कॉल पर काम करता है, लेकिन जैसा कि वॉकर एक अज्ञात के लिए एक कॉल (वैश्विक पाता है तो यह आपको एक कॉलबैक जो निष्पादित किया जाता है देता है) तरीका।

उदाहरण के लिए, निम्नलिखित इनपुट दिया:

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

यह कॉल मिलेगा bar(1) लेकिन bar(2) या bar(3) नहीं।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^