2012-06-09 6 views
14

私のjsライブラリの良いビルド環境を準備しようとしています。ウェブ上のレビューによると、UglifyJSはNodeJSの下で働いている最善の圧縮モジュールのようです。だからここにコードを縮小化する最良の推奨される方法である:ここで見られるように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)は、変数名をマングル必要がありますが、それはしていません。私はこのパイプから抜け出すだけで、スペースなしのjavascriptコードです。最初は自分のコードが圧縮のために最適化されていないと思ったが、Google Closureでそれを試してみたところ、(圧縮された変数名とすべてで)かなり圧縮されていた。

UglifyJSのエキスパートは、私が間違っていることを知っていますか?

UPDATE

実際のコードはここに参照するためには大きすぎるが、このようにもスニペットがマングルされません。これは私が得るものです

;(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

私は行方不明のオプションがあったと思った。小さなスニペットで今すぐ更新。明らかに、私の環境には何かがありますか?デバッグを開始する場所や、uglify-jsに悪影響を与える可能性のあるものは、いつ要求されますか。 – jayarjo

+1

さて、UglifyJSのウェブサイトでは、私は次のようになっています: '(function a、b、c){function d(a){return typeof a!=" string "?a:b.getElementById(a)} a.mOxie = ao = d})(window、document) '正しいスイッチをオンにしてもよろしいですか? –

答えて

11

Uglify JSの最新バージョンでは、mangleオプションが明示的にtrueとして渡される必要があります。そうでない場合、何も変更されません。このように:

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

それぞれ ast = uglify.uglify.ast_mangle(ast、{toplevel:true}); – axkibe

+1

すべての私のコードは、匿名の自己呼び出し関数にカプセル化されています。私はスニペットで私の質問を更新しました。どのように状況をデバッグすることができるかのヒント? – jayarjo

+1

Thx、私のために働く –

0

グローバルスコープの変数は他のスクリプトでも使用できます。したがって、実際に表示する必要がある場合に備えて特別な切り替えを行わずにUglifyで変更することはできません。 -mt/toplevelのスイッチ/設定を使用することもできますが、グローバルスコープの汚染を防ぐこともできます。また、これらの変数を外部に表示するつもりはないが、コードを匿名の自己呼び出し関数に組み込むことができます。プライベートスコープとして機能します。

+0

「自分のコードを匿名の自己呼び出し関数にフレーミングする」ということは、私が実際にやっていることです。 1つのトップレベルオブジェクトのみが公開されます。 – jayarjo

+1

あなたの例のすべての変数は、外側のグローバルスコープの変数です。 –

+1

はい、外部スコープの変数は、引数として自己呼び出し匿名関数に渡されます。これは(機能の中で)マングリングのためにそれらを利用可能にしないのですか? – 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)); 
    }); 
} 

のみ上記のこの1つはグローバル関数の呼び出しで動作しますが、それはあなたにウォーカーが不明の呼び出しは(グローバル見つけたように実行されるコールバックを与えます) 方法。これは、コールbar(1)しかしないbar(2)またはbar(3)を見つけるだろう

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

:たとえば

は、以下の入力が与えられました。

関連する問題