هل حان الوقت لاستخدام العقدة 8؟
نشرت: 2022-03-11العقدة 8 خارج! في الواقع ، لقد خرج Node 8 لفترة طويلة بما يكفي لرؤية بعض الاستخدام القوي في العالم الحقيقي. لقد جاء بمحرك V8 جديد سريع وميزات جديدة ، بما في ذلك الخطاف غير المتزامن / انتظار ، و HTTP / 2 ، وخطافات غير متزامنة. لكن هل هو جاهز لمشروعك؟ هيا نكتشف!
ملاحظة المحرر: من المحتمل أنك تدرك أن Node 10 (التي تحمل الاسم الرمزي Dubnium ) قد خرجت أيضًا. نختار التركيز على Node 8 ( Carbon ) لسببين: (1) تدخل Node 10 الآن في مرحلة الدعم طويل المدى (LTS) ، و (2) تميزت Node 8 بتكرار أكثر أهمية مما فعلته Node 10 .
الأداء في Node 8 LTS
سنبدأ بإلقاء نظرة على تحسينات الأداء والميزات الجديدة لهذا الإصدار الرائع. أحد مجالات التحسين الرئيسية هو محرك JavaScript في Node.
ما هو محرك JavaScript بالضبط ، على أي حال؟
يقوم محرك JavaScript بتنفيذ التعليمات البرمجية وتحسينها. يمكن أن يكون مترجمًا قياسيًا أو مترجمًا في الوقت المناسب (JIT) يقوم بترجمة JavaScript إلى رمز ثانوي. محركات JS المستخدمة من قبل Node.js هي جميع برامج التحويل البرمجي لـ JIT وليست مترجمين فوريين.
محرك V8
استخدم Node.js محرك Google Chrome V8 JavaScript ، أو ببساطة V8 ، منذ البداية. تُستخدم بعض إصدارات Node للمزامنة مع إصدار أحدث من V8. لكن احرص على عدم الخلط بين V8 و Node 8 لأننا نقارن إصدارات V8 هنا.
من السهل تجاوز هذا الأمر ، نظرًا لأننا في سياقات البرامج غالبًا ما نستخدم "v8" كلغة عامية أو حتى شكل قصير رسمي لـ "الإصدار 8" ، لذلك قد يدمج البعض "Node V8" أو "Node.js V8" مع "NodeJS 8 ، "لكننا تجنبنا ذلك خلال هذه المقالة للمساعدة في توضيح الأمور: سيعني V8 دائمًا المحرك ، وليس إصدار Node.
الإصدار 5 من V8
يستخدم Node 6 الإصدار 5 من V8 كمحرك JavaScript. (تستخدم الإصدارات القليلة الأولى من Node 8 أيضًا الإصدار 5 من V8 ، لكنها تستخدم إصدارًا أحدث من V8 من Node 6.)
المجمعين
تحتوي إصدارات V8 5 وما قبلها على مترجمين:
- برنامج Full-codegen هو مترجم JIT بسيط وسريع ولكنه ينتج كود آلة بطيء.
- العمود المرفقي هو مترجم JIT معقد ينتج كود آلة محسن.
الخيوط
في العمق ، يستخدم V8 أكثر من نوع واحد من الخيوط:
- الخيط الرئيسي يجلب الكود ويجمعه ثم ينفذه.
- تقوم الخيوط الثانوية بتنفيذ التعليمات البرمجية بينما يقوم مؤشر الترابط الرئيسي بتحسين الكود.
- يقوم مؤشر ترابط ملف التعريف بإعلام وقت التشغيل حول الأساليب غير الفعالة. ثم يقوم العمود المرفقي بتحسين هذه الأساليب.
- خيوط أخرى تدير جمع القمامة.
عملية التجميع
أولاً ، يقوم برنامج التحويل البرمجي Full-codegen بتنفيذ كود JavaScript. أثناء تنفيذ التعليمات البرمجية ، يجمع مؤشر ترابط ملف التعريف البيانات لتحديد الطرق التي سيعمل المحرك على تحسينها. في مؤشر ترابط آخر ، يعمل العمود المرفقي على تحسين هذه الأساليب.
مشاكل
النهج المذكور أعلاه لديه مشكلتين رئيسيتين. أولاً ، إنه معقد من الناحية المعمارية. ثانيًا ، يستهلك رمز الآلة المترجمة ذاكرة أكبر بكثير. حجم الذاكرة المستهلكة مستقل عن عدد المرات التي يتم فيها تنفيذ الكود. حتى التعليمات البرمجية التي يتم تشغيلها مرة واحدة فقط تستهلك قدرًا كبيرًا من الذاكرة.
الإصدار 6 من V8
أول إصدار Node لاستخدام محرك الإصدار 6 من V8 هو Node 8.3.
في الإصدار 6 ، قام فريق V8 ببناء Ignition و TurboFan للتخفيف من هذه المشكلات. يحل الإشعال و TurboFan محل الكودجين الكامل والعمود المرفقي ، على التوالي.
الهيكل الجديد أكثر وضوحًا ويستهلك ذاكرة أقل.
يقوم Ignition بترجمة شفرة JavaScript إلى رمز ثانوي بدلاً من رمز الجهاز ، مما يوفر الكثير من الذاكرة. بعد ذلك ، TurboFan ، المترجم المحسن ، يولد كود الآلة المحسن من هذا الرمز الثانوي.
تحسينات أداء محددة
دعنا ننتقل إلى المجالات التي تغير فيها الأداء في Node 8.3+ بالنسبة لإصدارات Node الأقدم.
خلق الأشياء
يكون إنشاء الكائنات أسرع بخمس مرات تقريبًا في Node 8.3+ مما هو عليه في Node 6.
حجم الوظيفة
يقرر محرك V8 ما إذا كان يجب تحسين الوظيفة بناءً على عدة عوامل. عامل واحد هو حجم الوظيفة. تم تحسين الوظائف الصغيرة ، بينما الوظائف الطويلة ليست كذلك.
كيف يتم حساب حجم الوظيفة؟
يستخدم العمود المرفقي في محرك V8 القديم "عدد الأحرف" لتحديد حجم الوظيفة. تعمل المسافات البيضاء والتعليقات في إحدى الوظائف على تقليل فرص تحسينها. أعلم أن هذا قد يفاجئك ، ولكن في ذلك الوقت ، يمكن أن يؤدي التعليق إلى تقليل السرعة بنحو 10٪.
في Node 8.3+ ، لا تضر الأحرف غير الملائمة مثل المسافة البيضاء والتعليقات بأداء الوظيفة. لما لا؟
لأن TurboFan الجديد لا يحسب الأحرف لتحديد حجم الوظيفة. بدلاً من ذلك ، يحسب عقد شجرة بناء الجملة المجردة (AST) ، لذلك فهو يأخذ في الاعتبار تعليمات الوظيفة الفعلية فقط. باستخدام Node 8.3+ ، يمكنك إضافة تعليقات ومسافات بيضاء بقدر ما تريد.
Array
الحجج
تحمل الوظائف العادية في JavaScript كائن argument
ضمني يشبه Array
.
ماذا تعني Array
-like؟
كائن arguments
يعمل إلى حد ما مثل المصفوفة. لها خاصية length
ولكنها تفتقر إلى أساليب Array
المضمنة مثل forEach
و map
.
إليك كيفية عمل كائن arguments
:
function foo() { console.log(arguments[0]); // Expected output: a console.log(arguments[1]); // Expected output: b console.log(arguments[2]); // Expected output: c } foo("a", "b", "c");
فكيف يمكننا تحويل arguments
إلى مصفوفة؟ باستخدام Array.prototype.slice.call(arguments)
.
function test() { const r = Array.prototype.slice.call(arguments); console.log(r.map(num => num * 2)); } test(1, 2, 3); // Expected output: [2, 4, 6]
Array.prototype.slice.call(arguments)
يضعف الأداء في جميع إصدارات Node. لذلك ، فإن نسخ المفاتيح عبر حلقة for
يؤدي بشكل أفضل:
function test() { const r = []; for (index in arguments) { r.push(arguments[index]); } console.log(r.map(num => num * 2)); } test(1, 2, 3); // Expected output [2, 4, 6]
حلقة for
مرهقة بعض الشيء ، أليس كذلك؟ يمكننا استخدام عامل الانتشار ، لكنه بطيء في العقدة 8.2 وما بعدها:
function test() { const r = [...arguments]; console.log(r.map(num => num * 2)); } test(1, 2, 3); // Expected output [2, 4, 6]
لقد تغير الوضع في Node 8.3+. الآن يتم تنفيذ السبريد بشكل أسرع ، حتى أسرع من تنفيذ التكرار الحلقي.
التطبيق الجزئي (الكاري) والتجليد
التحليل هو تقسيم دالة تأخذ وسيطات متعددة إلى سلسلة من الوظائف حيث تأخذ كل دالة جديدة وسيطة واحدة فقط.
لنفترض أن لدينا وظيفة add
بسيطة. تأخذ النسخة المعالجة من هذه الدالة وسيطة واحدة ، num1
1. تُرجع دالة تأخذ وسيطة أخرى num2
وتُرجع مجموع num1
و num2
:
function add(num1, num2) { return num1 + num2; } add(4, 6); // returns 10 function curriedAdd(num1) { return function(num2) { return num1 + num2; }; } const add5 = curriedAdd(5); add5(3); // returns 8
تقوم طريقة bind
بإرجاع دالة معدة بصيغة موجزة.
function add(num1, num2) { return num1 + num2; } const add5 = add.bind(null, 5); add5(3); // returns 8
لذا فإن bind
أمر لا يصدق ، لكنه بطيء في إصدارات Node القديمة. في Node 8.3+ ، يكون bind
أسرع بكثير ويمكنك استخدامه دون القلق بشأن أي نتائج أداء.
التجارب
تم إجراء العديد من التجارب لمقارنة أداء العقدة 6 بالعقدة 8 على مستوى عالٍ. لاحظ أنه تم إجراؤها على Node 8.0 لذا فهي لا تتضمن التحسينات المذكورة أعلاه الخاصة بـ Node 8.3+ بفضل ترقية الإصدار 6 من V8.
كان وقت عرض الخادم في Node 8 أقل بنسبة 25٪ من العقدة 6. في المشاريع الكبيرة ، يمكن تقليل عدد مثيلات الخادم من 100 إلى 75. وهذا أمر مذهل. كان اختبار مجموعة من 500 اختبار في Node 8 أسرع بنسبة 10٪. كانت إصدارات Webpack أسرع بنسبة 7٪. بشكل عام ، أظهرت النتائج تحسنًا ملحوظًا في الأداء في Node 8.
ميزات العقدة 8
لم تكن السرعة هي التحسين الوحيد في العقدة 8. لقد جلبت أيضًا العديد من الميزات الجديدة المفيدة - ربما الأهم من ذلك ، عدم التزامن / الانتظار .
عدم التزامن / انتظار في العقدة 8
عادةً ما تُستخدم عمليات الاسترجاعات والوعود للتعامل مع التعليمات البرمجية غير المتزامنة في JavaScript. عمليات الاسترجاعات معروفة بإنتاج كود غير قابل للاستمرار. لقد تسببوا في الفوضى (المعروفة على وجه التحديد باسم جحيم معاودة الاتصال ) في مجتمع JavaScript. أنقذتنا الوعود من جحيم رد الاتصال لفترة طويلة ، لكنها ما زالت تفتقر إلى نظافة الشفرة المتزامنة. Async / await هو أسلوب حديث يسمح لك بكتابة رمز غير متزامن يشبه رمزًا متزامنًا.
وبينما يمكن استخدام async / await في إصدارات Node السابقة ، فقد تطلب الأمر مكتبات وأدوات خارجية - على سبيل المثال ، معالجة إضافية عبر Babel. الآن أصبح متاحًا أصليًا ، وبصورة خارج الصندوق.
سأتحدث عن بعض الحالات التي يتفوق فيها عدم التزامن / الانتظار على الوعود التقليدية.
الشرطية
تخيل أنك تجلب البيانات وستحدد ما إذا كانت هناك حاجة إلى استدعاء API جديد بناءً على الحمولة . ألق نظرة على الكود أدناه لترى كيف يتم ذلك من خلال نهج "الوعود التقليدية".
const request = () => { return getData().then(data => { if (!data.car) { return fetchForCar(data.id).then(carData => { console.log(carData); return carData; }); } else { console.log(data); return data; } }); };
كما ترى ، يبدو الكود أعلاه فوضويًا بالفعل ، فقط من شرط إضافي واحد. ينطوي عدم التزامن / انتظار على تداخل أقل:
const request = async () => { const data = await getData(); if (!data.car) { const carData = await fetchForCar(data); console.log(carData); return carData; } else { console.log(data); return data; } };
معالجة الأخطاء
يمنحك Async / await الوصول لمعالجة كل من الأخطاء المتزامنة وغير المتزامنة في try / catch. لنفترض أنك تريد تحليل JSON القادمة من استدعاء API غير متزامن. يمكن أن تتعامل محاولة / التقاط واحدة مع كل من أخطاء التحليل وأخطاء API.
const request = async () => { try { console.log(await getData()); } catch (err) { console.log(err); } };
القيم المتوسطة
ماذا لو احتاج الوعد إلى حجة يجب حلها من خلال وعد آخر؟ هذا يعني أنه يلزم إجراء المكالمات غير المتزامنة في سلسلة.
باستخدام الوعود التقليدية ، قد ينتهي بك الأمر برمز مثل هذا:
const request = () => { return fetchUserData() .then(userData => { return fetchCompanyData(userData); }) .then(companyData => { return fetchRetiringPlan(userData, companyData); }) .then(retiringPlan => { const retiringPlan = retiringPlan; }); };
يتألق Async / await في هذه الحالة ، حيث يلزم إجراء مكالمات غير متزامنة متسلسلة:
const request = async () => { const userData = await fetchUserData(); const companyData = await fetchCompanyData(userData); const retiringPlan = await fetchRetiringPlan(userData, companyData); };
غير متزامن بالتوازي
ماذا لو كنت تريد استدعاء أكثر من دالة غير متزامنة في نفس الوقت؟ في الكود أدناه ، سننتظر حتى يتم حل fetchHouseData
، ثم fetchCarData
. على الرغم من أن كل واحد من هؤلاء مستقل عن الآخر ، إلا أنه تتم معالجتهما بالتتابع. ستنتظر ثانيتين حتى يتم حل كل من واجهات برمجة التطبيقات. هذا ليس جيدا.

function fetchHouseData() { return new Promise(resolve => setTimeout(() => resolve("Mansion"), 1000)); } function fetchCarData() { return new Promise(resolve => setTimeout(() => resolve("Ferrari"), 1000)); } async function action() { const house = await fetchHouseData(); // Wait one second const car = await fetchCarData(); // ...then wait another second. console.log(house, car, " in series"); } action();
أفضل طريقة هي معالجة المكالمات غير المتزامنة بالتوازي. تحقق من الكود أدناه للحصول على فكرة عن كيفية تحقيق ذلك في حالة عدم التزامن / انتظار.
async function parallel() { houseDataPromise = fetchHouseData(); carDataPromise = fetchCarData(); const house = await houseDataPromise; // Wait one second for both const car = await carDataPromise; console.log(house, car, " in parallel"); } parallel();
معالجة هذه المكالمات بالتوازي تجعلك تنتظر ثانية واحدة فقط لكلا المكالمتين.
وظائف المكتبة الأساسية الجديدة
يجلب Node 8 أيضًا بعض الوظائف الأساسية الجديدة.
نسخ الملفات
قبل Node 8 ، لنسخ الملفات ، اعتدنا على إنشاء دفقين وبيانات الأنابيب من واحد إلى الآخر. يوضح الكود أدناه كيف يقوم دفق القراءة بتوجيه البيانات إلى دفق الكتابة. كما ترى ، فإن الكود مزدحم لمثل هذا الإجراء البسيط مثل نسخ ملف.
const fs = require('fs'); const rd = fs.createReadStream('sourceFile.txt'); rd.on('error', err => { console.log(err); }); const wr = fs.createWriteStream('target.txt'); wr.on('error', err => { console.log(err); }); wr.on('close', function(ex) { console.log('File Copied'); }); rd.pipe(wr);
في Node 8 fs.copyFile
و fs.copyFileSync
، تعد أساليب جديدة لنسخ الملفات بأقل قدر من المتاعب.
const fs = require("fs"); fs.copyFile("firstFile.txt", "secondFile.txt", err => { if (err) { console.log(err); } else { console.log("File copied"); } });
وعد و Callbackify
util.promisify
يحول الوظيفة العادية إلى وظيفة غير متزامنة. لاحظ أن الوظيفة المدخلة يجب أن تتبع أسلوب رد الاتصال Node.js الشائع. يجب أن تأخذ رد النداء كوسيطة أخيرة ، أي (error, payload) => { ... }
.
const { promisify } = require('util'); const fs = require('fs'); const readFilePromisified = promisify(fs.readFile); const file_path = process.argv[2]; readFilePromisified(file_path) .then((text) => console.log(text)) .catch((err) => console.log(err));
كما ترون ، فقد قام util.promisify
بتحويل fs.readFile
إلى وظيفة غير متزامنة.
من ناحية أخرى ، يأتي Node.js مع util.callbackify
. util.callbackify
هو عكس util.promisify
: فهو يحول وظيفة غير متزامنة إلى وظيفة نمط رد الاتصال Node.js.
destroy
وظيفة للقراءة والكتابة
وظيفة destroy
في Node 8 هي طريقة موثقة لتدمير / إغلاق / إحباط تدفق قابل للقراءة أو قابل للكتابة:
const fs = require('fs'); const file = fs.createWriteStream('./big.txt'); file.on('error', errors => { console.log(errors); }); file.write(`New text.\n`); file.destroy(['First Error', 'Second Error']);
ينتج عن الكود أعلاه إنشاء ملف جديد باسم big.txt
(إذا لم يكن موجودًا بالفعل) مع النص نص New text.
.
تصدر وظائف Readable.destroy
و Writeable.destroy
في Node 8 حدثًا close
وحدث error
اختياري - لا يعني destroy
بالضرورة حدوث أي خطأ.
عامل انتشار
عامل الانتشار (المعروف أيضًا باسم ...
) عمل في العقدة 6 ، ولكن فقط مع المصفوفات والمتكررات الأخرى:
const arr1 = [1,2,3,4,5,6] const arr2 = [...arr1, 9] console.log(arr2) // expected output: [1,2,3,4,5,6,9]
في العقدة 8 ، يمكن للكائنات أيضًا استخدام عامل الانتشار:
const userCarData = { type: 'ferrari', color: 'red' }; const userSettingsData = { lastLoggedIn: '12/03/2019', featuresPlan: 'premium' }; const userData = { ...userCarData, name: 'Youssef', ...userSettingsData }; console.log(userData); /* Expected output: { type: 'ferrari', color: 'red', name: 'Youssef', lastLoggedIn: '12/03/2019', featuresPlan: 'premium' } */
الميزات التجريبية في Node 8 LTS
الميزات التجريبية غير مستقرة ، وقد يتم إهمالها ، ويمكن تحديثها بمرور الوقت. لا تستخدم أيًا من هذه الميزات في الإنتاج حتى تصبح مستقرة.
خطاف غير متزامن
تتبع الخطافات غير المتزامنة عمر الموارد غير المتزامنة التي تم إنشاؤها داخل العقدة من خلال واجهة برمجة التطبيقات.
تأكد من فهم حلقة الحدث قبل المضي قدمًا في استخدام الخطافات غير المتزامنة. قد يساعد هذا الفيديو. الخطافات غير المتزامنة مفيدة لتصحيح أخطاء الوظائف غير المتزامنة. لديهم العديد من التطبيقات. أحدها هو تتبعات مكدس الأخطاء للوظائف غير المتزامنة.
ألق نظرة على الكود أدناه. لاحظ أن console.log
هي وظيفة غير متزامنة. وبالتالي لا يمكن استخدامه داخل خطافات غير متزامنة. يتم استخدام fs.writeSync
بدلاً من ذلك.
const asyncHooks = require('async_hooks'); const fs = require('fs'); const init = (asyncId, type, triggerId) => fs.writeSync(1, `${type} \n`); const asyncHook = asyncHooks.createHook({ init }); asyncHook.enable();
شاهد هذا الفيديو لمعرفة المزيد عن الخطافات غير المتزامنة. فيما يتعلق بدليل Node.js على وجه التحديد ، تساعد هذه المقالة في إزالة الغموض عن الخطافات غير المتزامنة من خلال تطبيق توضيحي.
وحدات ES6 في العقدة 8
يدعم Node 8 الآن وحدات ES6 ، مما يتيح لك استخدام بناء الجملة هذا:
import { UtilityService } from './utility_service';
لاستخدام وحدات ES6 في Node 8 ، عليك القيام بما يلي.
- أضف علامة
--experimental-modules
إلى سطر الأوامر - إعادة تسمية ملحقات الملفات من
.js
إلى.mjs
HTTP / 2
HTTP / 2 هو آخر تحديث لبروتوكول HTTP الذي لم يتم تحديثه كثيرًا ، ويدعمه Node 8.4+ محليًا في الوضع التجريبي. إنه أسرع وأكثر أمانًا وأكثر كفاءة من سابقه ، HTTP / 1.1. وتوصي Google باستخدامه. لكن ماذا تفعل غير ذلك؟
مضاعفة
في HTTP / 1.1 ، يمكن للخادم إرسال استجابة واحدة فقط لكل اتصال في المرة الواحدة. في HTTP / 2 ، يمكن للخادم إرسال أكثر من استجابة في نفس الوقت.
دفع الخادم
يمكن للخادم دفع استجابات متعددة لطلب عميل واحد. لماذا هذا مفيد؟ خذ تطبيق الويب كمثال. تقليديا ،
- يطلب العميل مستند HTML.
- يكتشف العميل الموارد المطلوبة من مستند HTML.
- يرسل العميل طلب HTTP لكل مورد مطلوب. على سبيل المثال ، يرسل العميل طلب HTTP لكل مورد JS و CSS مذكور في المستند.
تستفيد ميزة دفع الخادم من حقيقة أن الخادم يعرف بالفعل كل هذه الموارد. يدفع الخادم هذه الموارد إلى العميل. لذلك بالنسبة لمثال تطبيق الويب ، يدفع الخادم جميع الموارد بعد أن يطلب العميل المستند الأولي. هذا يقلل من الكمون.
تحديد الأولويات
يمكن للعميل وضع خطة تحديد الأولويات لتحديد مدى أهمية كل استجابة مطلوبة. يمكن للخادم بعد ذلك استخدام هذا النظام لتحديد أولويات تخصيص الذاكرة ووحدة المعالجة المركزية وعرض النطاق الترددي والموارد الأخرى.
التخلص من العادات السيئة القديمة
نظرًا لأن HTTP / 1.1 لا يسمح بتعدد الإرسال ، يتم استخدام العديد من التحسينات والحلول للتغطية على السرعة البطيئة وتحميل الملفات. لسوء الحظ ، تتسبب هذه التقنيات في زيادة استهلاك ذاكرة الوصول العشوائي وتأخير العرض:
- تقسيم المجال: تم استخدام نطاقات فرعية متعددة بحيث تشتت الاتصالات وتتم معالجتها بشكل متوازٍ.
- الجمع بين ملفات CSS و JavaScript لتقليل عدد الطلبات.
- خرائط الرموز المتحركة: دمج ملفات الصور لتقليل طلبات HTTP.
- مضمنة: يتم وضع CSS و JavaScript في HTML مباشرةً لتقليل عدد الاتصالات.
الآن مع HTTP / 2 ، يمكنك نسيان هذه الأساليب والتركيز على التعليمات البرمجية الخاصة بك.
لكن كيف تستخدم HTTP / 2؟
تدعم معظم المتصفحات HTTP / 2 فقط من خلال اتصال SSL آمن. يمكن أن تساعدك هذه المقالة في تكوين شهادة موقعة ذاتيًا. قم بإضافة ملف .key
.crt
دليل يسمى ssl
. بعد ذلك ، أضف الكود أدناه إلى ملف يسمى server.js
.
تذكر استخدام علامة --expose-http2
في سطر الأوامر لتمكين هذه الميزة. أي أمر التشغيل لمثالنا هو node server.js --expose-http2
.
const http2 = require('http2'); const path = require('path'); const fs = require('fs'); const PORT = 3000; const secureServerOptions = { cert: fs.readFileSync(path.join(__dirname, './ssl/server.crt')), key: fs.readFileSync(path.join(__dirname, './ssl/server.key')) }; const server = http2.createSecureServer(secureServerOptions, (req, res) => { res.statusCode = 200; res.end('Hello from Toptal'); }); server.listen( PORT, err => err ? console.error(err) : console.log(`Server listening to port ${PORT}`) );
بالطبع ، لا تزال Node 8 و Node 9 و Node 10 وما إلى ذلك تدعم HTTP 1.1 القديم - لن تكون وثائق Node.js الرسمية بشأن معاملة HTTP القياسية قديمة لفترة طويلة. ولكن إذا كنت تريد استخدام HTTP / 2 ، فيمكنك التعمق في دليل Node.js هذا.
لذا ، هل يجب أن أستخدم Node.js 8 في النهاية؟
وصل Node 8 مع تحسينات في الأداء ومع ميزات جديدة مثل async / await و HTTP / 2 وغيرها. أظهرت التجارب الشاملة أن العقدة 8 أسرع بنحو 25٪ من العقدة 6. وهذا يؤدي إلى توفير كبير في التكلفة. لذلك بالنسبة للمشاريع التأسيسية ، بالتأكيد! لكن بالنسبة للمشاريع الحالية ، هل يجب عليك تحديث Node؟
يعتمد ذلك على ما إذا كنت ستحتاج إلى تغيير الكثير من التعليمات البرمجية الحالية. يسرد هذا المستند جميع تغييرات كسر Node 8 إذا كنت قادمًا من Node 6. تذكر تجنب المشكلات الشائعة عن طريق إعادة تثبيت جميع حزم npm
الخاصة بمشروعك باستخدام أحدث إصدار من Node 8. أيضًا ، استخدم دائمًا إصدار Node.js نفسه على أجهزة التطوير كما هو الحال في خوادم الإنتاج. حظا سعيدا!
- لماذا بحق الجحيم سأستخدم Node.js؟ برنامج تعليمي لكل حالة على حدة
- تصحيح أخطاء الذاكرة في تطبيقات Node.js
- إنشاء واجهة برمجة تطبيقات آمنة لـ REST في Node.js
- تشفير حمى المقصورة: برنامج تعليمي للجهة الخلفية لـ Node.js