ضغط الملفات باستخدام واجهة برمجة تطبيقات Closure Compiler Service

تم إيقاف خدمة المحول للتجميع نهائيًا وستتم إزالتها. يُرجى تجربة تشغيل المحول البرمجي محليًا بدلاً من ذلك.

نظرة عامة

وصف الاتصال بواجهة برمجة التطبيقات أساسيات كيفية الاتصال بخدمة Closure Compiler، ولكنه وضح فقط استخدام الخدمة لإزالة التعليقات من سطر واحد من جافا سكريبت. يوضح هذا البرنامج التعليمي كيفية استخدام خدمة Closure Compiler في سيناريو أكثر واقعية للتطوير: معالجة ملف جافا سكريبت بالكامل لتحقيق تقليل كبير في الحجم.

يفترض هذا البرنامج التعليمي أن لديك معرفة أساسية بجافا سكريبت وHTTP. وعلى الرغم من استخدام النص البرمجي Python لإرسال جافا سكريبت إلى خدمة Closure Compiler، إلا أنه لا يلزمك معرفة Python لاتباع المثال.

  1. ضغط ملف
  2. تحسين الضغط
    1. ما هو حجم الرمز المسموح به؟
    2. كيف ساهمت خدمة تجميع المحتوى في جعل البرنامج أصغر؟
  3. الخطوات التالية

ضغط ملف

في المثال الوارد في التواصل مع واجهة برمجة التطبيقات، تم تمرير سلسلة JavaScript كمعلمة سطر أوامر إلى النص البرمجي للتجميع. إلا أن هذا الأسلوب لن يعمل بشكل جيد مع برنامج جافا سكريبت ذي الحجم الفعلي، نظرًا لأن سلسلة جافا سكريبت تصبح غير عملية بسرعة عندما يزيد طول الشفرة عن بضعة أسطر. بالنسبة إلى البرامج الأكبر حجمًا، يمكنك استخدام معلَمة طلب code_url لتحديد اسم ملف JavaScript المطلوب معالجته. يمكنك استخدام code_url بالإضافة إلى js_code، أو بدلاً من js_code.

على سبيل المثال، جرب برنامج جافا سكريبت التالي:

/**
 * A simple script for adding a list of notes to a page. The list diplays
 * the text of each note under its title.
 */

/**
 * Creates the DOM structure for a note and adds it to the document.
 */
function makeNoteDom(noteTitle, noteContent, noteContainer) {
  // Create DOM structure to represent the note.
  var headerElement = document.createElement('div');
  var headerText = document.createTextNode(noteTitle);
  headerElement.appendChild(headerText);

  var contentElement = document.createElement('div');
  var contentText = document.createTextNode(noteContent);
  contentElement.appendChild(contentText);

  var newNote = document.createElement('div');
  newNote.appendChild(headerElement);
  newNote.appendChild(contentElement);

  // Add the note's DOM structure to the document.
  noteContainer.appendChild(newNote);
}

/**
 * Iterates over a list of note data objects and creates a DOM
 */
function makeNotes(data, noteContainer) {
  for (var i = 0; i < data.length; i++) {
    makeNoteDom(data[i].title, data[i].content, noteContainer);
  }
}

function main() {
  var noteData = [
      {title: 'Note 1', content: 'Content of Note 1'},
      {title: 'Note 2', content: 'Content of Note 2'}];
  var noteListElement = document.getElementById('notes');
  makeNotes(noteData, noteListElement);
}

main();

يمكنك تمرير هذا البرنامج إلى خدمة Closure Compiler بشكل أكثر ملاءمة كملف بدلاً من سلسلة واحدة كبيرة. اتبع الخطوات التالية لمعالجة ملف باستخدام الخدمة:

  1. احفظ جافا سكريبت في ملف.
  2. اجعل الملف قابلاً للدخول إليه على الويب (عن طريق تحميله على خادم الويب مثلاً).
  3. قدِّم طلب POST إلى خدمة Closure Compiler كما هو موضّح في التواصل مع واجهة برمجة التطبيقات، ولكن استخدِم المَعلمة js_code بدلاً من المَعلمة code_url. يجب أن تكون قيمة code_url هي عنوان URL لملف JavaScript الذي تم إنشاؤه في الخطوة 1.

على سبيل المثال، يمكنك العثور على رمز JavaScript لهذا المثال في الملف tutorial2.js. لمعالجة هذا الملف باستخدام واجهة برمجة تطبيقات Closure Compiler، يمكنك تغيير برنامج python من الاتصال مع واجهة برمجة التطبيقات لاستخدام code_url، كما يلي:

#!/usr/bin/python2.4

import httplib, urllib, sys

# Define the parameters for the POST request and encode them in
# a URL-safe format.

params = urllib.urlencode([
    ('code_url', sys.argv[1]), # <--- This parameter has a new name!
    ('compilation_level', 'WHITESPACE_ONLY'),
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

# Always use the following value for the Content-type header.
headers = { "Content-type": "application/x-www-form-urlencoded" }
conn = httplib.HTTPSConnection('closure-compiler.appspot.com')
conn.request('POST', '/compile', params, headers)
response = conn.getresponse()
data = response.read()
print data
conn.close()

ملاحظة: لإعادة إنتاج هذا المثال، قد يحتاج مستخدمو Windows إلى تثبيت Python. يمكنك الاطّلاع على الأسئلة الشائعة حول Python Windows للحصول على تعليمات عن كيفية تثبيت Python واستخدامها ضمن Windows.

أرسل الشفرة إلى خدمة Closure Compiler باستخدام الأمر التالي:

$ python compile.py https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js

تسترد خدمة Closure Compiler الملف من https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js وتعرض رمز JavaScript مضغوطًا في الاستجابة.

لتجميع ملفات إخراج متعددة معًا في ملف ناتج واحد، ضمِّن معلمات code_url متعددة، كما في هذا المثال:

params = urllib.urlencode([
    # Multiple code_url parameters:
    ('code_url', 'http://yourserver.com/yourJsPart1.js'),
    ('code_url', 'http://yourserver.com/yourJsPart2.js'),
    ('compilation_level', 'WHITESPACE_ONLY'),
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

تحسين الضغط

استخدمت الأمثلة حتى الآن compilation_level من WHITESPACE_ONLY، والتي تزيل فقط التعليقات والمسافة البيضاء. باستخدام مستوى ضغط SIMPLE_OPTIMIZATIONS يمكنك تحقيق معدلات ضغط أعلى بكثير. لاستخدام ضغط SIMPLE_OPTIMIZATIONS، غيّر معلمة compilation_level إلى SIMPLE_OPTIMIZATIONS:

params = urllib.urlencode([
    ('code_url', sys.argv[1]),
    ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),  # <--- This parameter has a new value!
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

وتشغيل النص البرمجي كما في السابق:

$ python compile.py https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js

من المفترض أن يظهر الناتج على النحو التالي:

var GLOBAL_document=document,$$PROP_appendChild="appendChild";function makeNoteDom(a,b,c){var d=GLOBAL_document.createElement("div");a=GLOBAL_document.createTextNode(a);d[$$PROP_appendChild](a);a=GLOBAL_document.createElement("div");b=GLOBAL_document.createTextNode(b);a[$$PROP_appendChild](b);b=GLOBAL_document.createElement("div");b[$$PROP_appendChild](d);b[$$PROP_appendChild](a);c[$$PROP_appendChild](b)}function makeNotes(a,b){for(var c=0;c<a.length;c++)makeNoteDom(a[c].title,a[c].content,b)}
function main(){var a=[{title:"Note 1",content:"Content of Note 1"},{title:"Note 2",content:"Content of Note 2"}],b=GLOBAL_document.getElementById("notes");makeNotes(a,b)}main();

وتصعب قراءة هذه الشفرة أكثر من البرامج المصدر، ولكنها أصغر حجمًا.

ما مدى حجم الرمز؟

إذا غيّرنا output_info في معلمات الطلب من compiled_code إلى statistics، يمكننا أن نرى حجم المساحة التي تم توفيرها بالضبط:

Original Size: 1372
Compressed Size: 677
Compilation Time: 0

جافا سكريبت الجديد أقل من نصف حجم النص الأصلي.

كيف جعلت خدمة تجميع محتويات البرنامج البرنامج أصغر؟

في هذه الحالة، تحقق أداة Closure Compiler انخفاضًا في الحجم جزئيًا من خلال إعادة تسمية المتغيرات المحلية. على سبيل المثال، يتضمن الملف الأصلي سطر الشفرة التالي:

var headerElement = document.createElement('div');

يغيّر Closure Compiler هذه العبارة إلى:

var d=document.createElement("div");

يغيّر مجمِّع الإغلاق الرمز headerElement إلى d في كل مكان داخل الدالة makeNoteDom، وبالتالي يحافظ على الوظائف. ولكن تم اختصار الأحرف الثلاثة عشرة من headerElement إلى حرف واحد في كل مكان من الأماكن الثلاثة التي تظهر فيها. يؤدي هذا إلى توفير إجمالي 36 حرفًا.

تحافظ التجميع باستخدام SIMPLE_OPTIMIZATIONS دائمًا على وظائف جافا سكريبت الصالحة من حيث البنية، شريطة ألا يصل الرمز إلى المتغيرات المحلية باستخدام أسماء السلاسل (باستخدام عبارات eval() مثلاً).

الخطوات التالية

بعد أن تعرّفت على SIMPLE_OPTIMIZATIONS والآليات الأساسية لاستخدام الخدمة، تتمثل الخطوة التالية في التعرّف على مستوى تجميع ADVANCED_OPTIMIZATIONS. يتطلب هذا المستوى بعض الخطوات الإضافية لضمان عمل جافا سكريبت بنفس الطريقة قبل التجميع وبعده، ولكنه يجعل جافا سكريبت أصغر حجمًا. اطّلِع على مقالة التجميع المتقدّم والمصادر الخارجية للتعرّف على معلومات عن ADVANCED_OPTIMIZATIONS.