Closure Compiler使ってますか?
JavaScriptのコードを圧縮してくれるGoogleのサービスです.
圧縮してくれるだけじゃなくて, ちゃんとErrorやWarningも吐いてくれるので,
私はJavaScriptのコードの検証にも使っています.
さて, このClosure CompilerにはAPIがあって, 詳しいチュートリアルがあるのですが(Googleのチュートリアルはいつも詳しい!),
サンプルがPythonです.
JavaScriptなんだからJavaScriptから叩きたいよね〜
ってことで, 練習も兼ねて書いてみました.
node.jsはインストールしているものとします.
#! /usr/bin/env node var http = require('http'), querystring = require('querystring'); var compile = function (code, callback, option) { // compile(JavaScript_code, callback , option); // JavaScript_code :: String // callback :: Function // callback = function (error, result) {} // option :: Object (optional) // option = { // // 'SIMPLE_OPTIMIZATIONS' (default) or 'WHITESPACE_ONLY' or 'ADVANCED_OPTIMIZATIONS' // compilation_level: 'SIMPLE_OPTIMIZATIONS', // output_info: 'compiled_code', // (default) or 'warnings' or 'errors' or 'statistics' // // OR set output_info in Array // output_info: ['compiled_code', 'warnings', 'errors', 'statistics'], // } // var option = option || {}, info = option.output_info; if(Object.prototype.toString.call(info) === '[object Array]') { for(var i = -1, l = info.length, o = option; ++i < l;) { o.output_info = info[i]; compile(code, callback, o); } return; } try { if(option.compilation_level && ['SIMPLE_OPTIMIZATIONS', 'WHITESPACE_ONLY', 'ADVANCED_OPTIMIZATIONS'] .indexOf(option.compilation_level) < 0) { throw 'unknown compilation_level: ' + option.compilation_level; } if(option.output_info && ['compiled_code', 'warnings', 'errors', 'statistics'] .indexOf(option.output_info) < 0) { throw 'unknown output_info: ' + option.output_info; } var client = http.createClient(80, 'closure-compiler.appspot.com') .on('error', callback), req = client .request('POST', '/compile', { 'host': 'closure-compiler.appspot.com', 'Content-Type': 'application/x-www-form-urlencoded' }) .on('error', callback); req.on('response', function (r) { r.setEncoding('utf8'); r.on('data', function (c) { if(c === '' || c === '\n') { // Code was invalid. compile( code, function (e, c) { console.log(c.toString()); }, { output_info: 'errors', compilation_level: option.compilation_level } ); return; } callback(null, c); }); }); req.end( querystring.stringify({ js_code: code.toString('utf-8'), output_format: 'text', output_info: option.output_info || 'compiled_code', compilation_level: option.compilation_level || 'SIMPLE_OPTIMIZATIONS' }) ); } catch (e) { callback(e); } }; compile( '(function () {var hoge = {}; var f = function () {return parseInt(2);}; hoge["foo"]= 2; /* comment */ ;;if( f() > 0) { alert(hoge["foo"])}; console.log(f()); })()', function (e, c) { if(e) { console.log(e.toString()); return; } console.log(c); } );
このコードをclosureCompile.jsとして保存して, 実行すれば,
$ chmod +x closureCompile.js $ ./closureCompile.js (function(){var a={};a.foo=2;parseInt(2)>0&&alert(a.foo);console.log(parseInt(2))})();
と表示されるはずです.
第三引数にオプションを付けることも出来ます.
output_infoには, 文字列でも配列でも与えることが出来ます.
compile( 'alert( 10 * 2);', function (e, c) { if(e) { console.log(e.toString()); return; } console.log(c); }, { compilation_level: 'ADVANCED_OPTIMIZATIONS', output_info: ['compiled_code', 'statistics'] } );
alert(20);
Original Size: 16
Original Gzip Size: 36
Compressed Size: 10
Compressed Gzip Size: 30
Compilation Time: 0
ファイルに書き込むときはリダイレクトを使いましょう.
発展編
ここまで来てなんですが, モジュールとして作ってくれた親切な方がいます.Use the Google Closure Service With Node.jsです.
使い方はこんな感じです.
1. サイトの下の方の"Get the code here."をクリックすると, githubへ.
2. ダウンロードする. 必要なファイルはlib/closure.jsだけ.
3. closure.jsと同じディレクトリに次のようなJavaScriptコードを書く.
#! /usr/bin/env node var closure = require('./closure'); closure.compile( '(function () {var variable = 10 * 20; /* comment */ ;; alert ( variable );})();', function (e, c) { if(e) { console.log(e.toString()); return; } console.log(c); } );
4. 実行権限を与えて実行すれば, alert(200);と表示されます.
モジュールになってるから使いやすいですね(^^
ただ, オプションがADVANCED_OPTIMIZATIONSになっているので,
SIMPLE_OPTIMIZATIONSに書きなおしておいたほうがいいかと.
コード見てみても, 私の書いたものとあんまり変わりませんね!
あ, 違います. 参考にして書いただけですごめんなさい.
ファイルの書き込みはnode.jsのfs.writeFileを使いましょう.
あと, Closure CompilerのAPIを叩き過ぎると規制がかかります.
気を付けましょう.
結論: node.jsやばい.