منذ ظهور لغة جافا سكربت JavaScript عام 1995، اقتصر استعمالها على التفاعل مع حركة المستخدم في موقع الويب. وإظهار بعض الحركات وتغيير طريقة عرض بعض مكونات الصفحة.

ومن بداية ظهورها حتى عام 2015 تعرضت لغة جافا سكربت لكثير من الانتقادات لأنها لا تملك مميزات اللغات الآخرى.

وأهم تلك الميزات البرمجة الكائنية Object-Oreinted Programming وأنها ليست Static Type Language أي لا يمكن تحديد نوع المتغيرات عند تعريفها أو ما نوع المخرجات التي تعيدها دالة معينة.

//C#
int age = 24;
//Javascript
var age = 24
view raw static type.js hosted with ❤ by GitHub

لكن كل ذلك تغير مع ظهور بيئة Node.js وتطور لغة جافا سكربت إلى ES6 عام 2015. كما ساعدت أيضًا شركة مايكروسوفت Microsoft بإصدار TypeScript وهي ليست لغة برمجية جديدة، وإنما هي مجموعة من الحزم البرمجية Packages التي تمكنك من كتابة لغة جافا سكربت واستعمال Static Type بالإضافة إلى البرمجة الكائنية والمزيد من المميزات حتى تصبح لغة جافا سكربت أشبه بلغة C#.

// typescript
var age:number = 24;
// javascript
var age = 24
view raw index.js hosted with ❤ by GitHub

ولا تعمل TypeScript على المتصفحات لذا في نهاية الأمر كل ما ستكتبه في TypeScript يُحول إلى لغة جافا سكربت.

سأشارككم في هذا المقال وعدة مقالات قادمة عن تاريخ لغة جافا سكربت من البداية وحتى العام 2019.

وأبرز التغييرات التي حصلت لها، وما المجالات التي اقتحتمها هذه اللغة وما وصلت إليه من تقدم وتوسع غير مسبوق لتصبح من أكثر اللغات طلبًا.

تاريخ لغة جافا سكربت

ظهرت لغة جافا سكربت لأول مرة عام 1995 عن طريق شركة Netscape وطورتها في مدة لا تتجاوز 15 يومًا.

والسؤال الذي يطرحه الجميع هل هي لغة قريبة من لغة جافا JAVA؟

في الحقيقة سًُميت بهذا الاسم لأسبات تسويقية بحتة، نظرًا لشهرة لغة جافا في ذلك الوقت وتصدرها لغات البرمجة في العالم آنذاك

ومرت لغة جافا سكربت بالكثير من التعديلات والتغييرات إلى أن وصلت لنسخة مستقرة عام 1999 والتي تدعى ES5.

إلى ماذا ترمز ES؟

ترمز ES أو ECMASCRIPT إلى محددات اللغة والتي تم إنشائها من أجل لتوحيد قواعد لغة جافا سكربت في كل متصفحات الويب.

ظهور مكتبة JQuery

في العام 2006 تم إطلاق مكتبة JQuery على يد John Resig كمكتبة جافا سكربت مفتوحة المصدر Open Source، والتي كان هدفها الأساسي تسهيل كتابة أوامر جافا سكربت وتوفير الكثير من الوقت على مطوري الويب عند محاولة كتابة شيفرات جافا سكربت.

فعلى سبيل المثال إذا أردنا برمجة معرض صور ، في لغة جافا سكربت ربما سيكلف حوالي 100 سطر برمجي لكن باستخدام JQuery والمزايا التي تقدمها لنا ربما ستكلف حوالي 10 أسطر فقط وبوقت أقل بكثير.

ومن أهم المشاكل التي تعالجها مكتبة JQuery أيضًا هي توافق المتصفحات فبعض أوامر جافا سكربت لا تعمل بنفس الآلية على جميع المتصفحات وبعضها لا يعمل أبدًا على متصفحنا المحبوب Internet Expolrer :(

تبع ظهور مكتبة JQuery العديد من المكتبات المنافسة، ولكن لم يصمد أي منها في وجه مكتبة JQuery.

شهدت هذه الفترة انفجار في ظهور إضافات جافا سكربت التي تعتمد على مكتبة JQuery بشكل كلي في عملها.

ومع ظهور إطار اعمل بوتسترات Bootstrap Framework عام 2011 وهو إطار عمل يساعد في بناء الواجهات بسرعة والذي يعتمد على مكتبة JQuery في الجانب الخاص بجافا سكربت.

من أهم العوامل التي ساعدت في انتشار مكتبة JQuery هو سهولة تعلمها من دون المعرفة الكبيرة في لغة جافا سكربت والتي تعد نقطة سلبية وإيجابية في نفس الوقت.

فعلى افتراض أن العميل طلب أن يكون المشروع بلا إطار عمل لضمان سرعة موقعه ولم تكن مهاراتك بلغة جافا سكربت جيدة ستقع في مأزق لأنك ستحتاج للكثير من البحث والتحري وحل مشاكل توافق المتصفحات مع الشيفرة البرمجية المكتوبة.

الحاجة إلى المزيد وظهور Node.js

مع تطور تطبيقات الويب وازدياد حجمها زادت الحاجة إلى مزيد المميزات التي تفتقدها لغة جافا سكربت وأهم تلك المميزات كانت مشكلة فصل ملفات المشروع عن بعضها والحاجة إلى استدعاء ملفات جافا سكربت داخل بعضها أي نظام وحدات Module System.

فكما نعلم لكي نستخدم مكتبة من مكتبات جافا سكربت نستدعي الملفات تحت بعضها بهذا الشكل في صفحة HTML.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="path/to/file1"></script>
<script src="path/to/file2"></script>
<script src="path/to/file3"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

لكن ماذا لو كان لدينا قاعدة شيفرات كبيرة جدًا ونريد فصلها ضمن وحدات منطقية

هنا ظهرت بيئة Node.js التي تم تعريفها بأنها بيئة تشغل شيفرات جافا سكربت في الخادم Server، أي تعطينا الإمكانية لإنشاء تطبيقات ويب كاملة بلغة جافا سكربت والتعامل مع قواعد البيانات باستخدامها، وسيصبح تطبيق الويب من طرف الخادم ومن طرف المستخدم يعمل بلغة جافا سكربت.

تملك بيئة Node.js الكثير من المزايا التي سيطول شرحها ولكن توفر لنا نظام وحدات منفصلة Module System.

وتمكننا من إنشاء تطبيقات أكبر وتوزيع الشيفرات على عدة ملفات يمكن الاعتماد على بعضها وفي النهاية عند استخدامها في HTML سيتم تجميع وضغط كل ملفات جافا سكربت في ملف واحد نستدعيه في صفحة HTML بدلًا من الإكثار من طلبات Http مما يوفر الكثير من الوقت لتحميل التطبيق أو صفحة الويب.

لكن كيف سنستخدم Node.js في مشاريعنا

مدير الحزم Npm

أتت Node.js مع مدير حزم يدعى Npm اختصارًا ل Node Package Manager، ومهمة مدير الحزم كما هو واضح من اسمه إدارة عملية تثبيت مكتبات جافا سكربت بأوامر بسيطة نكتبها في سطر الأوامر cmd بدلًا من الذهاب إلى موقع كل مكتبة وتثبيتها يدويًا وتضمينها في صفحة HTML.

تحدثنا كثيرًا لنقم بمثال عملي على ذلك.

التطبيق

التطبيق ببساطة هو عبارة عن تطبيق لتحديد عمرك بالسنوات حيث يقوم المستخدم بإدخال سنة الميلاد ضمن حقل في صفحة HTML.

سنستخدم لذلك مكتبتي Moment.js الخاصة بالتواريخ ومكتبة JQuery.

شنشرح التطبيق مرة بدون استخدام Node.js وبعدها ندخل Node.js خطوة بخطوة من أجل تفصيل العملية.

يمكنك تحميل ملفات التطبيق كاملًا بنسخة من دون استعمال Node.js ونسخة معتمدة على Node.js على الرابط التالي في موقع Github.

لنبدأ بشرح شيفرة التطبيق من المجلد start ونفتح ملف index.html في المتصفح لرؤية التطبيق.

Age_calc_app

التطبيق عبارة عن صفحة واحدة ولها بعض تنسيقات Css الموجودة في ملف style.css ضمن المجلد css، ولدينا form لاستقبال مدخلات المستخدم.

وفي أسفل الملف قبل إغلاق عنصر body نستدعي مكتبتي JQuery و Moment.js وملف index.js الذي سيتم ضمنه كتابة الشيفرات الخاصة بحسات عمر المستخدم وكل هذه الملفات متواجدة في مجلد js.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
<title>Calculator</title>
</head>
<body>
<div class="container">
<h1>Age Calculator</h1>
<form>
<input type="date" class="date-input">
<input type="submit" value="calculate">
</form>
</div>
<script src="js/jquery.js"></script>
<script src="js/moment.js"></script>
<script src="js/index.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

الآن لنشرح شيفرات ملف index.js:

$(function(){
$('form').on('submit', function(event) {
event.preventDefault();
var dateValue = $('.date-input').val();
if (!dateValue) {
alert('Please enter valid value');
return;
}
var age = moment().diff(dateValue, 'years');
alert(age);
});
});
view raw index.js hosted with ❤ by GitHub

  • يُطلق الحدث submit عند ينقر المستخدم على زر Calculate.
  • نمنع إعادة تحميل الصفحة باستخدام الدالة preventDefualt.
  • بعد ذلك أحضرنا مدخلات المستخدم من حقل التاريخ باستخدام مكتبة JQuery.
  • ثم نتأكد أن الحقل غير فارغ وأظهرنا رسالة تنبه المستخدم إلى ذلك.
  • ثم نستخدم الدالة diff الموجودة في مكتبة Moment.js لحساب الفرق بالسنوات بين التاريخ المدخل وتاريخ اليوم.
  • في النهاية نظهر عمر المستخدم على الواجهة.

يمكنك استخدام التطبيق لحساب العمر والاطلاع على النتيجة.

استخدام Node.js

لاستخدام Node.js يجب أولًا تثبيت Node.js موقعها الرسمي

Node_site

للتأكد نفتح سطر الأوامر cmd ونكتب الأمر التالي node -v لكي نرى رقم النسخة المثبتة.

Node_site

ونتأكد أيضًا من وجود npm بالأمر npm -v:

Node_site

ملاحظة ليس من الضروري أن تكون نسخة Node.js التي لديك مطابقة للنسخة المتواجدة في الصور.

إضافة الحزم اللازمة

في البداية نحذف مكتبتي JQuery و Moment.js من مجلد js ونحذف التضمينات من ملف index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
<title>Calculator</title>
</head>
<body>
<div class="container">
<h1>Age Calculator</h1>
<form>
<input type="date" class="date-input">
<input type="submit" value="calculate">
</form>
</div>
<script src="js/index.js"></script>
</body>
</html>
view raw index.js hosted with ❤ by GitHub

الآن نعود إلى سطر الأوامر ونتجه من خلاله إلى المجلد start ونكتب الأمر:

npm init

ستظهر مجموعة من الأسئلة يمكنك تجاوزها بالضغط على زر enter على لوحة المفاتيح لكل الأسئلة، سنلاحظ بأنه تم توليد ملف باسم package.json.

ملف package.json

يتولد هذا الملف بواسطة npm وهذا الملف هو ملف تعريفي بالحزم والمكتبات التي تستخدمها في مشروعك حيث يحوي على بعض الخصائص وأسماء الحزم البرمجية المستخدمة.

وعند تنصيب أي حزمة باستخدام npm يجب أن تكون متواجد في نفس المجلد الذي يحوي هذا الملف لأنه يعد نقطة البداية لتثبيت أي حزمة وعند تثبيت الحزمة يحفظ اسمها ورقم النسخة الخاصة بها.

لذا عندما يعمل مشروعك مطور آخر يمكنه أن يعرف ما الحزم الذي يستخدمها مشروعك ويقوم يثبتها عنده.

الآن بعد أن استغنينا عن مكتبتي JQuery و Moment.js يجب أن نقوم بتثبيتها باستخدام npm، احرص أن تكون في نفس مسار ملف packages.json ونكتب الأمر التالي:

npm install jquery moment --save

عند تنفيذ هذا الأمر نلاحظ في سطر الأوامر تثبيت عدة ملفات وعند انتهاء التثبيت يتولد مجلد باسم node_modules والذي يُنزل عدة حزم ومكتبات وملفات مساعدة بالإضافة إلى مكتبتي JQuery و Moment.js.

مجلد node_modules هو المجلد الذي يحمل جميع المكتبات التي تُثبت باستخدام npm.

ملاحظة هامة: عندما تعمل على مشروع فيه المجلد node_modules يجب أن لا ترفع هذا الملف إلى Source Control الذيي تتعامل معه ك Github أو Bitbucket. لأن حجم هذا الملف كبير جدًا وبالتالي وجود ملف package.json مهم جدًا ويجب أن ترفعه لأنه يحوي أسماء المكتبات والحزم الخاصة بمشروعك ويمكن لأي أحد يعمل على نفس المشروع أن يقوم بنفس عملك ولكن على حاسوبه الخاص ويدخل الأمر:

npm install

الآن بعد تثبيت المكتبات اللازمة يمكننا استخدامها في ملف index.js.

في Node.js يمكنك استدعاء أي مكتبة من مجلد node_modules بكتابة اسم المكتبة فقط ولا داعي لذكر المسار لأن Node.js ستتكفل في هذه العملية.

لذا نستدعي مكتبة JQuery على الشكل التالي:

var $ = require('jquery');
view raw index.js hosted with ❤ by GitHub

لكن ما زلنا نحتاج إلى مكتبة Moment.js لكن نستدعيها هنا بل نقوم بإنشاء ملف منفصل لكي نطلع على كيفية استدعاء ملفات جافا سكربت التي نقوم بإنشاءها وسنسمي هذا الملف calculator.js وسيكون ضمن مجلد js ومحتواه على الشكل التالي:

var moment = require('moment');
exports.getAge = function (date) {
return moment().diff(date, 'years');
}
view raw calculator.js hosted with ❤ by GitHub

في هذا الملف :

  • استدعاء مكتبة Moment.js
  • إنشاء دالة getAge التي تأخذ تاريخ كوسيط وتعيد لنا فرق السنوات بين هذا التاريخ وتاريخ اليوم.
  • لاحظ أننا قمنا بتصدير هذه الدالة باستخدام الكلمة المحجوزة exports لأنه لا يمكن لأي ملف آخر الإطلاع على هذه الدالة إذا لم يتم تصديرها.

الآن نستدعي ملف calculator.js في ملف index.js على الشكل التالي:

var $ = require('jquery');
var calculator = require('./calculator');
$(function(){
$('form').on('submit', function(event) {
event.preventDefault();
var dateValue = $('.date-input').val();
if (!dateValue) {
alert('Please enter valid value');
return;
}
var age = calculator.getAge(dateValue);
alert(age);
});
});
view raw index.js hosted with ❤ by GitHub

إذا قمنا الآن بتحديث صفحة index.html في المتصفح نجد أن التطبيق لا يعمل ويظهر لنا هذا الخطأ في النافذة console.

Node_site

لماذا لم تعمل دالة require التي تستدعي المكتبات وملف calculator.js؟

هذا بسبب أن المتصفحات لم تدعم نظام ملفات ووحدات حتى الآن، لذا يجب أيضًا تحويل كل هذه الشيفرات إلى نسخة جافا سكربت المستقرة والتي تعمل على جميع المتصفحات ومن أجل ذلك يجب استخدام مُحزم Buldler.

ما هو المُحزم؟

هو عبارة عن تقنية تمكننا من جمع ملفات جافا سكربت مع بعضها وضغطها والحصول على ملف جافا سكربت واحد يعمل على كل شيفرات جافا سكربت.

طبعًا تعريف المُحزم ووظائفه أشمل من ذلك لكن لا أود الإطالة وسأشرح عنه في مقالة ثانية بإذن الله.

أشهر هذه المُحزمات الآن والذي سنستخدمه هو Webpack وهذا المُحزم أيضًا مبني بلغة جافا سكربت لذا يمكن تثبيته باستخدام npm بكتابة الأمر التالي:

npm install webpack webpack-cli --save -dev

بعد ان تنتهي عملية التثبيت نقوم بإنشاء ملف باسم webpack.config.js ونكتب فيه الإعدادات الخاصة بعملية التحزيم Bundling:

var path = require('path');
module.exports = {
entry: "./js/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
}
};
view raw webpack.config.js hosted with ❤ by GitHub

سنشرح عمل هذه الشيفرة بشكل سريع:

  • قمنا باستدعاء مكتبة path الموفرة في Node.js تلقائيًا.
  • قمنا بتصدير كائن Object يحوي الإعدادات.
  • الخاصية entry تأخذ مسار ملف جافا سكربت الأساسي في المشروع.
  • خاصية output هي عبارة عن كائن يأخذ الخاصية path لتحديد الملف واسم المجلد الذي سيتم وضع كل شيفرات جافا سكربت في الملف والذي يُنشأ من قبل المُحزم واسم الملف bundle.js.

الآن يجب استدعاء ملف bundle.js من مجلد dist بدلًا من ملف index.js:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
<title>Calculator</title>
</head>
<body>
<div class="container">
<h1>Age Calculator</h1>
<form>
<input type="date" class="date-input">
<input type="submit" value="calculate">
</form>
</div>
<script src="dist/bundle.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

الآن نشغل المُحزم لكي يُنشأ ملف bundle.js:

npm webpack

سنلاحظ الآن تشكل ملف dist وبداخله ملف bundle.js الذي يحوي كل مكتبات جافا سكربت التي استدعيناها كمكتبة JQuery و Moment.js وحتى الشيفرة التي كتبناها في ملف index.js.

وعند تحديث نافذة المتصفح نجرب التطبيق الآن نلاحظ بأنه يعمل كما كان سابقًا.

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

في الأسبوع القادم بإذن الله سأتابع في هذا المسار وسأكمل شرح تطور لغة جافا سكربت والمكتبات الجديدة التي ظهرت وما المجالات التي دخلتها لغة جافا سكربت.