Ahmad Masykur

Share your knowledge although one function!

About the author

Ahmad Masykur is a Software Architecture Engineer at PT. Freeport Indonesia Jakarta Indonesia.
In this blog, I share things of interest to me. Most topics are likely to be related to software development, but don't hold me to it.

Certificates



Awards


Powered by

Widget Prayer Time not found.

There is an error in XML document (4, 16278).X

Page List

Validators


Ahmad Masykur

JavaScript Code Compressor

JavaScript code compressor sudah banyak kita jumpai, mulai dari yang gratis sampai yang berbayar, dari yang dicompress secara online maupun software yang ditanam di komputer kita. Terdapat dua macam JavaScript code compressor yaitu: (1) bekerja dengan hanya menghilangkan komentar dan whitespace; (2) selain menghilangkan komentar dan whitespace juga menyingkat semua nama variabel dan fungsi menjadi beberapa karakter yang lebih pendak.

Dalam tulisan kali ini, saya hanya akan membahas code compressor yang pertama. Sepintas untuk menghilangkan whitespace dan komentar tampak mudah. Whitespace dapat dihilangkan dengan menghilangkan spasi di depan dan akhir kode. Komentar dapat dikenali dengan karakter pembukan dan penutup pada komentar multibaris atau pembuka komentar pada komentar baristunggal. Permasalahan timbul jika terdapat karakter pembuka komentar yang terdapat pada string, misalhnya string "http://www.masykur.web.id". String tersebut mengandung karakkter komentar, jika tidak hati hati karakter di belakang // akan ikut dihilangkan. Permasalahan tidak hanya terjadi pada string namun juga pada regular expression. Keduanya dapat berisi semua bentuk string termasuk penanda komentar.

Untuk mengatasi permasalahan ini, semua string dan regular expression harus diselamatkan dari pembersihan. Untuk itu sebelum dilakukan pembersihan, simpan dulu semua string dan regular expression ke dalam array/collection yang pada akhir pembersihan string dan regular expression tersebut dikembalikan dengan bentuk seperti semula. Pada contoh sebelumnya, string dapat diganti menjadi sebuah tanda yang unik seperti "_____STRINGREGEX_n_STRINGREGEX____", dengan n adalah nomor urut string yang ditemukan. Metode ini yang saya terapkan pada code compressor BlogEngine.NET.

Penyimpanan string dapat dilakukan dengan mencari pattern string dan regular expression menggunakan regular expression. Jika ada pattern yang cocok, hasilnya dimasukkan dalam collection. Kode dapat dilihat pada contoh berikut. (Pada contoh script disimpan dalam variable body).


// mark strings and regular expressions
Regex re = new Regex("\"(([^\"\\r\\n])|(\\\"))*\"|'[^'\\r\\n]*'|/[^/\\*](?<![/\\S]/.)([^/\\\\\\r\\n]|\\\\.)*/(?=[ig]{0,2}[^\\S])", RegexOptions.Compiled | RegexOptions.Multiline);
List<string> strs = new List<string>();
MatchCollection m = re.Matches(body);
for (int i=0; i < m.Count; i++)
{
    strs.Add(m[i].Value);
    // replace string and regular expression with marker
    StringBuilder sb = new StringBuilder();
    sb.Append("_____STRINGREGEX_");
    sb.Append(i.ToString());
    sb.Append("_STRINGREGEX_____");
    body = re.Replace(body, sb.ToString(), 1);
}

Pada contoh di atas, regular expression akan mencari semua pattern untuk string dan regular expression. String dalam JavaScript dapat berupa karakter yang berada di dalam tanda kutip tunggal maupun kutip ganda. Oleh karena itu pada regular expression harus mengecek keduanya. Setelah pattern ditemukan, hasilnya disimpan dalam collection dan ganti pattern string/regular expression dengan tanda yang unik.

Setalah kode bersih dari string dan regular expression, selanjutnya kita dengan mudah dapat membersihkan whitespace dan komentar yang ada dengan regular expression juga seperti pada kode berikut.


// remove line comments
body = Regex.Replace(body, "//.*[\r\n]", String.Empty, RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove C styles comments
body = Regex.Replace(body, "/\\*.*?\\*/", String.Empty, RegexOptions.Compiled | RegexOptions.Singleline);
// trim left
body = Regex.Replace(body, "^\\s*", String.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
// trim right
body = Regex.Replace(body, "\\s*[\\r\\n]", "\r\n", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of left curly braced
body = Regex.Replace(body, "\\s*{\\s*", "{", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of right curly braced
body = Regex.Replace(body, "\\s*}\\s*", "}", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of coma
body = Regex.Replace(body, "\\s*,\\s*", ",", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of semicolon
body = Regex.Replace(body, "\\s*;\\s*", ";", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove newline after keywords
body = Regex.Replace(body, "\\r\\n(?<=\\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|default|delete|do|double|else|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|while|with)\\r\\n)", " ", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove all newline
body = Regex.Replace(body, "\\r\\n", "", RegexOptions.Compiled | RegexOptions.ECMAScript);

Setelah kode bersih dari whitespace dan komentar, kembalikan lagi string dan regular expression yang telah disimpan sebelumnya dengan mengganti tanda unik dengan string yang disimpan dalam collection.


// restore marked strings and regular expressions
for (int i = 0; i < strs.Count; i++)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("_____STRINGREGEX_");
    sb.Append(i.ToString());
    sb.Append("_STRINGREGEX_____");
    body = Regex.Replace(body, sb.ToString(), strs[i]);
}

Dengan kompresi tersebut, kode JavaScript akan menjadi lebih kecil karena semua whitespace dan komentar telah dibersihkan. Baris kode secara lengkap dapat dilihat pada kode berikut.


/// <summary>
/// Strips the whitespace from any .js file.
/// <remarks>Modified by Ahmad Masykur - "http://www.masykur.web.id">http://www.masykur.web.id, modified date: March 03, 2008 2:50PM+7</remarks>
/// </summary>
private static string StripWhitespace(string body)
{
    // mark strings and regular expressions
    Regex re = new Regex("\"(([^\"\\r\\n])|(\\\"))*\"|'[^'\\r\\n]*'|/[^/\\*](?<![/\\S]/.)([^/\\\\\\r\\n]|\\\\.)*/(?=[ig]{0,2}[^\\S])", RegexOptions.Compiled | RegexOptions.Multiline);
    List<string> strs = new List<string>();
    MatchCollection m = re.Matches(body);
    for (int i=0; i < m.Count; i++)
    {
        strs.Add(m[i].Value);
        // replace string and regular expression with marker
        StringBuilder sb = new StringBuilder();
        sb.Append("_____STRINGREGEX_");
        sb.Append(i.ToString());
        sb.Append("_STRINGREGEX_____");
        body = re.Replace(body, sb.ToString(), 1);
    }
    // remove line comments
    body = Regex.Replace(body, "//.*[\r\n]", String.Empty, RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove C styles comments
    body = Regex.Replace(body, "/\\*.*?\\*/", String.Empty, RegexOptions.Compiled | RegexOptions.Singleline);
    // trim left
    body = Regex.Replace(body, "^\\s*", String.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
    // trim right
    body = Regex.Replace(body, "\\s*[\\r\\n]", "\r\n", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of left curly braced
    body = Regex.Replace(body, "\\s*{\\s*", "{", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of right curly braced
    body = Regex.Replace(body, "\\s*}\\s*", "}", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of coma
    body = Regex.Replace(body, "\\s*,\\s*", ",", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of semicolon
    body = Regex.Replace(body, "\\s*;\\s*", ";", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove newline after keywords
    body = Regex.Replace(body, "\\r\\n(?<=\\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|default|delete|do|double|else|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|while|with)\\r\\n)", " ", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove all newline
    body = Regex.Replace(body, "\\r\\n", "", RegexOptions.Compiled | RegexOptions.ECMAScript);

    // restore marked strings and regular expressions
    for (int i = 0; i < strs.Count; i++)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("_____STRINGREGEX_");
        sb.Append(i.ToString());
        sb.Append("_STRINGREGEX_____");
        body = Regex.Replace(body, sb.ToString(), strs[i]);
    }

    return body;
}

Yang perlu diingat dari kompresi javascript ini adalah, kita harus menambahkan tanda titik koma (;) pada setiap pernyataan JavaScript. Kode berikut akan dieksekusi dengan benar oleh broser jika pada kondisi tanpa terkompress, namun akan terjadi error setelah dilakukan kompresi.


var xfnRelationships = ['friend', 'acquaintance', 'contact', 'met'
                                    , 'co-worker', 'colleague', 'co-resident'
                                    , 'neighbor', 'child', 'parent', 'sibling'
                                    , 'spouse', 'kin', 'muse', 'crush', 'date'
                                    , 'sweetheart', 'me']
// Applies the XFN tags of a link to the title tag
function HightLightXfn()
{
  var content = $('content')
  if (content == null)
    return;
  var links = document.getElementsByTagName('a')
  for (i = 0; i < links.length; i++)
  {
    var link = links[i];
    var rel = link.getAttribute('rel');
    if (rel && rel != "nofollow")
    {
      for (j = 0; j < xfnRelationships.length; j++)
      {
        if(rel.indexOf(xfnRelationships[j]) > -1)
        {
          link.title = 'XFN relationship: ' + rel;
          break;
        }
      }
    }
  }
}

Baris 5, 9, dan 12 merupakan kode yang benar dalam JavaScript tapi ketika kode tersebut dikompres, akan menimbulkan kesalahan karena akan menyatu dengan baris berikutnya, seperti terlihat pada kode berikut.


<dipotong>...,'sweetheart','me']function HightLightXfn(){var content=$('content')if(content==null)return;var links=document.getElementsByTagName('a')for(i=0;i<links.length;i++)...<dipotong>

Kode diatas sengaja dipotong karena akan terlalu panjang jika ditulis semua. Dari kode tersebut akan terjadi kesalahan karena antara array dan fungsi tidak ada pemisah, deklarasi variable content menjadi error karena nilainya kacau (pernyataan if ikut ke dalam nilai content karena tanpa pemisah). Dan kode lainnya yang tidak mengguakan akhiran titik koma menjadi error.


Categories: JavaScript | Tips
Permalink | Comments (15) | Post RSSRSS comment feed

Comments

geeks.netindonesia.net | Reply

Monday, March 03, 2008 6:16 PM

pingback

Pingback from geeks.netindonesia.net

JavaScript Code Compressor - Ahmad Masykur

rudy Indonesia | Reply

Monday, March 03, 2008 6:26 PM

rudy

great job, saya biasanya pake http://developer.yahoo.com/yui/compressor/ tapi itu saya pake gak on the fly.
kalo yang di BlogEngine memang on the fly tuh, sip deh...

Ahmad Masykur Indonesia | Reply

Monday, March 03, 2008 6:40 PM

Ahmad Masykur

Hari ini, code compressor BlogEngine.NET masih terbatas, belum bisa membersihkan komentar dengan baik. Tadi siang saya upload patch ke tim BlogEngine.NET dengan code compressor yang saya tulis ini.

BRaM Indonesia | Reply

Thursday, May 15, 2008 9:04 AM

BRaM

Mas Ahmad kalo mo kursus, bisa ga?

Ahmad Masykur Indonesia | Reply

Thursday, May 15, 2008 9:49 AM

Ahmad Masykur

Maksudnya kursus gimana?

busby seo challenge United States | Reply

Tuesday, August 26, 2008 11:23 AM

busby seo challenge

nice codes.... http://pinayspeak.com | http://alaminos.net

zeolite | Reply

Thursday, December 18, 2008 2:44 PM

zeolite

Code compression in JavaScript is generally used for JavaScript library files. (There is also a trade-off between having a huge library file and putting everything needed in it versus having small snippets tailored to each page, keeping code-size small and having no library at all. The former will increase page-load time considerably and may be annoying for visitors. The latter will be rewriting, copy & pasting code around, which will be annoying for you as a developer. To find the optimum point in between is up to you.)

Search Engine Marketing Company United States | Reply

Monday, December 29, 2008 11:31 AM

Search Engine Marketing Company

Javascript Compressor
This utility removes all comments and extra white space from Javascript code. Doing this is a bit tricky because white space inside quoted text must remain intact. Your Javascript code must be free of errors and properly formatted or this utility will just make matters worse. By removing all of the extra space, the file size is greatly reduced. The compressed code is also much less readable which may discourage some people from "borrowing" it.

Cayenne Pepper Diet United States | Reply

Wednesday, January 07, 2009 3:01 AM

Cayenne Pepper Diet

Mas Ahmad kalo mo kursus, bisa ga?

cayennepepper-diet.com | Reply

Saturday, January 10, 2009 1:44 AM

pingback

Pingback from cayennepepper-diet.com

Easy way to lose weight with lemon cayenne pepper diet | Cayenne Pepper Diet Information

cayennepepperdiet21.wordpress.com | Reply

Tuesday, January 13, 2009 6:21 AM

pingback

Pingback from cayennepepperdiet21.wordpress.com

Easy way to lose weight with lemon cayenne pepper diet « Cayenne Pepper Diet Blog

Gucci Clothes United States | Reply

Friday, January 16, 2009 4:10 PM

Gucci Clothes

Tool for compressing JavaScript source code. Eliminates comments, white spaces, line feeds, and other unnecessary characters, making your JavaScript source code substantially smaller so that it can be downloaded faster.

NFL Tickets United Kingdom | Reply

Friday, January 23, 2009 11:57 AM

NFL Tickets

kode yang benar dalam JavaScript tapi ketika kode

Immediate Fixed Annuities United Kingdom | Reply

Saturday, January 24, 2009 6:22 PM

Immediate Fixed Annuities

Doing this is a bit tricky because white space inside quoted text must remain intact. Your Javascript code must be free of errors and properly formatted or this utility will just make matters worse.

Wow accounts Jamaica | Reply

Friday, January 30, 2009 11:52 AM

Wow accounts

Mas Ahmad kalo mo kursus, bisa ga?

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading