يوم جيد يا اصدقاء!
ما زلت للنشر ترجمة لهذا البرنامج التعليمي نود.جي إس .
الأجزاء الأخرى:
الجزء الأول
الجزء الثاني
الجزء الثالث
الجزء الرابع
محرك JavaScript V8
V8 هو اسم محرك JavaScript المدعوم من Google Chrome. هذا هو الشيء الذي يأخذ كود JavaScript الخاص بك وتشغيله في المتصفح.
بعبارة أخرى ، V8 هو وقت تشغيل JavaScript. يتعرض المتصفح وواجهات برمجة تطبيقات الويب الأخرى من خلال المتصفح.
محرك جافا سكريبت مستقل عن المتصفح. هذا ما أدى إلى ظهور Node.js. تم اختيار V8 كمحرك لـ Node.js في عام 2009 ، ومع تزايد شعبية Node.js ، أصبح V8 هو الأساس لكثير من JavaScript من جانب الخادم.
النظام البيئي Node.js ضخم وبفضل V8 نحن قادرون على إنشاء تطبيقات سطح المكتب باستخدام Electron على سبيل المثال.
محركات شبيبة أخرى
المتصفحات الأخرى لها محركات جافا سكريبت خاصة بها:
- فايرفوكس - SpiderMonkey
- Safari - JavaScriptCore (نيترو)
- Edge - شقرا
إلخ
تطبق جميع هذه المحركات معيار ECMA ES-262 (ECMAScript) ، وهو المعيار الذي تستخدمه JavaScript.
عن الأداء
V8 مكتوب بلغة C ++ ويستمر في التطور. يعمل على جميع أنظمة التشغيل.
لن نفكر في ميزات تطبيق V8: يمكنك العثور عليها هنا ، فهي تتغير من وقت لآخر ، غالبًا بشكل جذري.
يتطور V8 باستمرار ، مثل محركات JavaScript الأخرى ، لزيادة سرعة الويب والنظام البيئي Node.js.
هناك منافسة في الأداء على الويب مستمرة منذ سنوات ، ونحن (كمستخدمين ومطورين) نحصل على الكثير من هذه المنافسة حيث نحصل على أدوات أسرع وأفضل كل عام.
التحويل البرمجي
عادةً ما يتم وضع جافا سكريبت كلغة مترجمة ، لكن المحركات الحديثة لا تفسر جافا سكريبت فقط ، بل تقوم بتجميعها.
كان هذا يحدث منذ عام 2009 ، عندما تمت إضافة مترجم SpiderMonkey JavaScript في Firefox 3.5.
تم تجميع جافا سكريبت على الطاير بواسطة V8 (في الوقت المناسب ، JIT ، الترجمة الديناميكية) لتسريع تنفيذها.
قد يبدو الأمر غير بديهي ، ولكن مع ظهور خرائط Google في عام 2004 ، تطورت جافا سكريبت من لغة يتم فيها كتابة كتل صغيرة من التعليمات البرمجية إلى لغة يتم فيها إنشاء تطبيقات كاملة ، تتكون من مئات أو آلاف الأسطر من التعليمات البرمجية التي يتم تنفيذها في المتصفح.
اليوم ، يمكن تشغيل تطبيقات المتصفح الخاصة بنا لساعات ؛ لم تعد أدوات بسيطة لحل المهام البدائية مثل التحقق من صحة النموذج.
في عالم اليوم ، يعد تجميع جافا سكريبت منطقيًا: على الرغم من أن الأمر يستغرق وقتًا أطول لإعداد الشفرة ، إلا أن أدائها يتجاوز بشكل كبير أداء الشفرة المفسرة.
تشغيل البرامج النصية Node.js من سطر الأوامر
الطريقة القياسية لتشغيل برامج Node.js هي تشغيل أمر عام
node
وتمرير اسم الملف القابل للتنفيذ.
إذا تم استدعاء الملف الرئيسي لتطبيق Node.js
app.js
، فيمكنك تسميته على النحو التالي :
node app.js
عند تنفيذ الأمر المحدد ، تأكد من أنك في الدليل بالملف
app.js
.
كيف أخرج من Node.js؟
هناك طرق مختلفة لإيقاف تطبيق Node.js.
عندما تقوم بتشغيل برنامج من خلال الوحدة الطرفية ، يمكنك إغلاقه مع
ctrl-C
ذلك ، فلنناقش الطرق الآلية.
لنبدأ بالأكثر تطرفًا ونتحدث عن سبب عدم استخدامه.
و(، وحدة النواة العالمية) وحدة رئيسية
process
توفر طريقة سهلة للخروج من تطبيق البرمجيات نود.جي إس: process.exit()
.
عندما يصل Node.js إلى هذا السطر من التعليمات البرمجية ، تنتهي عملية تنفيذ البرنامج على الفور.
وهذا يعني أن جميع عمليات الاسترداد قيد التقدم ، والطلبات المقدمة (المعلقة) ، والوصول المفتوح لنظام الملفات ، والكتابة إلى ،
stdout
أو stderr
- - سيتم إجهاضها بالكامل.
إذا كان هذا مقبولًا بالنسبة لك ، يمكنك تمرير
exit()
عدد صحيح إلى الطريقة - إشارة لإكمال الرمز:
process.exit(1)
رمز الخروج الافتراضي هو 0 ، مما يشير إلى النجاح. رموز الخروج المختلفة لها معاني مختلفة ، يمكنك استخدامها للتأكد من أن بعض البرامج تتفاعل مع الآخرين.
يمكنك قراءة المزيد حول رموز الخروج هنا .
يمكنك أيضًا تعيين قيمة مناسبة للخاصية
exitCode
:
process.exitCode = 1
وبعد انتهاء البرنامج ، ستقوم Node.js بإرجاع هذا الرمز.
سينتهي تنفيذ البرنامج بلطف عند اكتمال جميع العمليات.
في Node.js ، غالبًا ما نبدأ الخادم:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hi!')
})
app.listen(3000, () => console.log('Server ready'))
لن ينتهي هذا البرنامج أبداً. إذا اتصلت
process.exit()
، سيتم إلغاء جميع الطلبات المعلقة أو قيد التشغيل. ليست باردة.
في هذه الحالة ، من الضروري إرسال أمر إشارة
SIGTERM
ومعالجته باستخدام معالج إشارة المعالج ( process
لا حاجة للاتصال ، فهو متوفر افتراضيًا):
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hi!')
})
const server = app.listen(3000, () => console.log('Server ready'))
process.on('SIGTERM', () => {
server.close(() => {
console.log('Process terminated')
})
})
ما هي الإشارات؟ الإشارات هي نظام اتصال POSIX: لإخطار العملية بحدوث حدث.
SIGKILL
- إشارة حول الانتهاء الفوري للعملية ، مماثلة process.exit()
.
SIGTERM
- إشارة حول النهاية الناعمة للعملية. يمكن إرسال هذه الإشارة من خلال نظام التحكم في العملية ، مثل upstart
، supervisord
وما إلى ذلك.
يمكنك إرسال هذه الإشارة داخل البرنامج من خلال وظيفة أخرى:
process.kill(process.id, 'SIGTERM')
أو من برنامج Node.js آخر أو أي تطبيق آخر يعمل على النظام ، بشرط أن يعرفوا PID للعملية التي تريد إنهاءها.
كيف أقرأ متغيرات البيئة في Node.js؟
تحتوي الوحدة النمطية الرئيسية Node.js
process
على خاصية env
تحتوي على كافة متغيرات البيئة التي تم تعيينها عند بدء العملية.
فيما يلي مثال للوصول إلى متغير البيئة NODE_ENV الافتراضي
development
:
process.env.NODE_ENV // development
تعيين قيمة في الإنتاج قبل تشغيل البرنامج النصي سيخبر Node.js أن لديه بيئة إنتاج أمامه.
بطريقة مماثلة ، يمكنك الوصول إلى أي متغير بيئة محدد.
كيفية استخدام Node.js REPL
يتم
node
استخدام الأمر لتشغيل البرامج النصية Node.js:
node script.js
إذا حذفنا اسم الملف ، ندخل في وضع REPL:
node
REPL (تشغيل تقييم طباعة حلقة) هي بيئة تنفيذ التعليمات البرمجية (عادة نافذة طرفية) تأخذ تعبيرًا أدخله المستخدم وترجع نتيجة تقييم هذا التعبير.
إذا دخلت
node
في المحطة ، يحدث ما يلي:
>
سوف يدخل الجهاز في وضع الاستعداد.
لكي نكون أكثر دقة ، ينتظر الجهاز الطرفي في هذه الحالة إدخال بعض رموز JavaScript.
دعونا نقدم ما يلي:
> console.log('test')
test
undefined
>
القيمة الأولى ،
test
هي ما قلناه للإخراج إلى وحدة التحكم ، ثم نحصل على undefined
القيمة التي أرجعها التنفيذ ، console.log()
وبعد ذلك يمكننا إدخال شيء آخر.
استخدم tab
للإكمال التلقائي
REPL تفاعلي.
إذا تم الضغط عليه
tab
أثناء كتابة التعليمات البرمجية ، فسيحاول REPL إكمال ما كتبه عن طريق الاختيار من بين المتغيرات المحددة مسبقًا أو المحددة مسبقًا.
كائنات جافا سكريبت
جرب كتابة اسم فئة JavaScript ، على سبيل المثال ،
Number
أضف نقطة إليها وانقر tab
.
سيعرض REPL جميع خصائص وأساليب هذه الفئة:
كائنات عمومية
يمكنك الحصول على قائمة بالكائنات العمومية بكتابة
global.
والضغط على tab
:
متغير خاص _
إذا قمت بكتابة في نهاية الرمز
_
، سيتم عرض نتيجة العملية الأخيرة.
أوامر بعد النقطة
يحتوي REPL على بعض الأوامر الخاصة التي تبدأ بنقطة. ها هم:
.help
- يعرض قائمة بالأوامر المتاحة.editor
- يتيح وضع التحرير لكتابة كود JavaScript متعدد الأسطر. لتنفيذ التعليمات البرمجية في هذا الوضع ، اضغط علىctrl-D
.break
- توقف عن إدخال رمز متعدد الخطوط. على غرار الضغطctrl-C
.clear
- إعادة تعيين سياق REPL إلى كائن فارغ ، وإزالة جميع التعليمات البرمجية المدخلة.load
- يقوم بتحميل ملف JavaScript موجود في دليل (العمل) الحالي.save
- يحفظ جلسة REPL في ملف بالاسم المحدد.exit
- الخروج من REPL. نفس النقر المزدوجctrl-C
تدرك REPL أنك تقوم بإدخال رمز متعدد الخطوط دون الاتصال
.editor
.
على سبيل المثال ، إذا بدأت في تنفيذ التكرار:
[1, 2, 3].forEach(num => {
والضغط عليها
enter
، سوف يقفز REPL إلى سطر جديد بثلاث نقاط في البداية ، مما يشير إلى أنه يمكنك مواصلة العمل مع كتلة التعليمات البرمجية:
... console.log(num)
... })
إذا أدخلت
.break
في النهاية ، فسيتوقف وضع الاتصال متعدد الخطوط ولن يتم تنفيذ التعبير.
تمرير الحجج باستخدام سطر الأوامر
عند تشغيل تطبيق Node.js ، يمكنك تمرير أي عدد من الوسيطات إليه.
يمكن أن تكون الحجج قائمة بذاتها أو مفتاح وقيمة.
فمثلا:
node app.js joe
أو
node app.js name=joe
تعتمد كيفية استرداد القيمة في كود Node.js على ذلك.
يتم استخدام كائن مضمن لاسترداد القيم
process
.
تحتوي خاصية
argv
هذا الكائن على صفيف من الوسيطات التي تم تمريرها من خلال سطر الأوامر.
الحجة الأولى هي المسار الكامل للأمر
node
.
والثاني هو المسار الكامل للملف القابل للتنفيذ.
تبدأ الحجج التي تهمنا في الموضع الثالث (فهرس المصفوفة).
يمكنك التكرار فوق الوسيطات (بما في ذلك مسار العقدة ومسار الملف) باستخدام حلقة:
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`)
})
يمكن الحصول على الوسيطات التي تم تمريرها من خلال إنشاء مصفوفة جديدة بدون أول معلمتين:
const args = process.argv.slice(2)
إذا كان لدينا وسيطة واحدة بدون فهرس (مفتاح):
node app.js joe
يمكننا الحصول عليه على النحو التالي:
const args = process.argv.slice(2)
args[0]
في هذه الحالة:
node app.js name=joe
args[0]
- لهذا name=joe
السبب نحتاج إلى تحليلها. أفضل طريقة للقيام بذلك هي استخدام مكتبة مصغرة مصممة للعمل مع الحجج:
const args = require('minimist')(process.argv.slice(2))
args['name'] // joe
هنا تحتاج إلى استخدام شرطة مزدوجة قبل كل وسيطة:
node app.js --name=joe
إخراج النتائج إلى سطر الأوامر باستخدام Node.js
الإخراج القياسي عبر الوحدة النمطية console
يوفر Node.js وحدة تحكم تحتوي على العديد من الطرق المفيدة جدًا للتفاعل مع سطر الأوامر.
يبدو أنه كائن
console
مستعرض.
إحدى الطرق الرئيسية لهذه الوحدة هي
console.log()
، التي تطبع السلسلة التي تم تمريرها إلى وحدة التحكم.
إذا قمت بتمرير كائن ، سيتم تحويله إلى سلسلة.
يمكننا تمرير
console.log
عدة متغيرات:
const x = 'x'
const y = 'y'
console.log(x, y)
و Node.js سيخرج كلاهما.
يمكننا أيضًا تنسيق السلسلة باستخدام المحددات:
على سبيل المثال:
console.log('My %s has %d years', 'cat', 2)
%s
- ينسق المتغير كسلسلة%d
- ينسق المتغير كرقم%i
- يحول المتغير إلى عدد صحيح%o
- ينسق المتغير ككائن
فمثلا:
console.log('%o', Number)
تنظيف وحدة التحكم
console.clear()
مسح وحدة التحكم (يعتمد السلوك على وحدة التحكم المستخدمة).
عد العناصر
console.count()
هي طريقة مناسبة.
افحص هذا الرمز:
const x = 1
const y = 2
const z = 3
console.count(
'The value of x is ' + x +
' and has been checked .. how many times?'
)
console.count(
'The value of x is ' + x +
' and has been checked .. how many times?'
)
console.count(
'The value of y is ' + y +
' and has been checked .. how many times?'
)
يحسب العداد عدد شاشات الخط ويعرض هذا الرقم.
The value of x is 1 and has been checked .. how many times?: 1
The value of x is 1 and has been checked .. how many times?: 2
The value of y is 2 and has been checked .. how many times?: 1
لذلك يمكنك حساب عدد التفاح والبرتقال:
const oranges = ['orange', 'orange']
const apples = ['just one apple']
oranges.forEach(fruit => console.count(fruit))
apples.forEach(fruit => console.count(fruit))
عرض تتبع المكدس
هناك حالات تحتاج فيها إلى عرض تتبع مكدس دالة ، على سبيل المثال ، للإجابة على السؤال "كيف وصلنا إلى هذا الجزء من التعليمات البرمجية؟"
يمكنك القيام بذلك مع
console.trace()
:
const function2 = () => console.trace()
const function1 = () => function2()
function1()
سيؤدي هذا إلى طباعة تتبع المكدس إلى وحدة التحكم. هذا ما نراه في سطر الأوامر إذا قمنا بتنفيذ الكود أعلاه في Node.js REPL:
Trace
at function2 (repl:1:33)
at function1 (repl:1:25)
at repl:1:1
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at REPLServer.defaultEval (repl.js:239:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:440:10)
at emitOne (events.js:120:20)
at REPLServer.emit (events.js:210:7)
عد وقت تنفيذ التعليمات البرمجية
يمكنك بسهولة حساب المدة التي تم فيها تشغيل الوظيفة
time()
و timeEnd()
:
const doSomething = () => console.log('test')
const measureDoingSomething = () => {
console.time('doSomething()')
// -
doSomething()
console.timeEnd('doSomething()')
}
measureDoingSomething()
stdout و stderr
كما نعلم ، فإن console.log رائع لإخراج الرسائل إلى وحدة التحكم. وهذا ما يسمى الإخراج القياسي أو
stdout
.
console.error
يعرض الدفق stderr
.
لا يتم إخراج هذا الدفق إلى وحدة التحكم ، ولكنه مكتوب في سجل الأخطاء.
تصميم الناتج
يمكنك تلوين إخراج النص إلى وحدة التحكم باستخدام تسلسلات الهروب . هذه التسلسلات هي مجموعة من الأحرف التي تحدد اللون.
فمثلا:
console.log('\x1b[33m%s\x1b[0m', 'hi!')
إذا قمت بكتابة الرمز في Node.js REPL ،
hi!
فسيكون أصفر.
الطريقة المدروسة شاقة إلى حد ما. إن أبسط طريقة لتلوين إخراج وحدة التحكم هي استخدام مكتبة. إحدى هذه المكتبات هي Chalk ، والتي ، بالإضافة إلى تحديد اللون ، تسمح لك بجعل النص غامقًا أو مائلاً أو تحته خط.
قم بتثبيت المكتبة باستخدامها
npm install chalk
واستخدامها على النحو التالي:
const chalk = require('chalk')
console.log(chalk.yellow('hi!'))
الاستخدام
chalk.yellow
أسهل بكثير من حفظ التسلسلات المعقدة. كما أنه يجعل الرمز أكثر قابلية للقراءة.
إنشاء شريط تقدم
تقدم هي مكتبة رائعة لإنشاء أشرطة التقدم في المحطة. تثبيته مع
npm install progress
.
ينشئ هذا المقتطف شريط تقدمًا من 10 خطوات. يتم تنفيذ خطوة واحدة كل 100 مللي ثانية. عند ملء المؤشر ، نقوم بتعطيل العداد:
const ProgressBar = require('progress')
const bar = new ProgressBar(':bar', { total: 10 })
const timer = setInterval(() => {
bar.tick()
if (bar.complete) clearInterval(timer)
}, 100)
شكرا لكم على اهتمامكم يا اصدقاء. إذا وجدت أخطاء وأخطاء مطبعية لا تتردد في الكتابة في PM ، سأكون ممتنا.
يتبع…