كيفية الترحيل من jQuery إلى Next.js
نشرت: 2022-03-10تم دعم هذه المقالة بلطف من قبل أصدقائنا الأعزاء في Netlify وهم مجموعة متنوعة من المواهب الرائعة من جميع أنحاء العالم ويقدمون منصة لمطوري الويب الذين يضاعفون الإنتاجية. شكرا لك!
عندما ظهر jQuery في عام 2006 ، بدأ الكثير من المطورين والمؤسسات في اعتماده لمشاريعهم. إن إمكانية توسيع ومعالجة DOM التي توفرها المكتبة رائعة ، ولدينا أيضًا العديد من المكونات الإضافية لإضافة سلوك إلى صفحاتنا في حال احتجنا إلى القيام بمهام لا تدعمها مكتبة jQuery الرئيسية. لقد سهلت الكثير من العمل للمطورين ، وفي تلك اللحظة ، جعلت JavaScript لغة قوية لإنشاء تطبيقات الويب أو تطبيقات الصفحة الواحدة.
لا تزال نتيجة شعبية jQuery قابلة للقياس حتى اليوم: ما يقرب من 80٪ من مواقع الويب الأكثر شهرة في العالم لا تزال تستخدمها. بعض أسباب شعبية jQuery هي:
- يدعم معالجة DOM.
- يوفر معالجة CSS.
- يعمل بنفس الطريقة على جميع متصفحات الويب.
- يلتف أساليب الحدث HTML.
- من السهل إنشاء مكالمات AJAX.
- تأثيرات ورسوم متحركة سهلة الاستخدام.
على مر السنين ، تغيرت JavaScript كثيرًا وأضفت العديد من الميزات التي لم تكن لدينا في الماضي. مع إعادة تعريف وتطوير ECMAScript ، تمت إضافة بعض الوظائف التي قدمها jQuery إلى ميزات JavaScript القياسية ودعمها جميع متصفحات الويب. مع حدوث ذلك ، لم تعد هناك حاجة لبعض عروض jQuery الخاصة بالسلوك ، حيث يمكننا القيام بنفس الأشياء باستخدام JavaScript عادي.
من ناحية أخرى ، بدأت طريقة جديدة في التفكير وتصميم واجهات المستخدم في الظهور. تسمح الأطر مثل React أو Angular أو Vue للمطورين بإنشاء تطبيقات ويب تعتمد على مكونات وظيفية قابلة لإعادة الاستخدام. تعمل React ، أي ، مع "DOM الظاهري" ، وهو تمثيل DOM في الذاكرة ، بينما يتفاعل jQuery مباشرةً مع DOM ، بطريقة أقل أداءً. تقدم React أيضًا ميزات رائعة لتسهيل تطوير ميزات معينة ، مثل إدارة الحالة. مع هذا النهج الجديد والشعبية التي بدأت تكتسبها تطبيقات الصفحة الواحدة ، بدأ الكثير من المطورين في استخدام React لمشاريع تطبيقات الويب الخاصة بهم.
وتطور تطوير الواجهة الأمامية بشكل أكبر ، مع وجود أطر عمل تم إنشاؤها فوق أطر أخرى. هذا هو الحال ، على سبيل المثال ، في Next.js. كما تعلم على الأرجح ، فهو إطار عمل React مفتوح المصدر يوفر ميزات لإنشاء صفحات ثابتة ، وإنشاء صفحات معروضة من جانب الخادم ، ودمج كلا النوعين في نفس التطبيق. كما يسمح بإنشاء واجهات برمجة تطبيقات بدون خادم داخل نفس التطبيق.
هناك سيناريو غريب: على الرغم من أن أطر الواجهة الأمامية هذه أصبحت أكثر شيوعًا على مر السنين ، إلا أن jQuery لا يزال معتمدًا من قبل الغالبية العظمى من صفحات الويب. أحد أسباب حدوث ذلك هو أن النسبة المئوية لمواقع الويب التي تستخدم WordPress مرتفعة حقًا ، ويتم تضمين jQuery في نظام إدارة المحتوى . سبب آخر هو أن بعض المكتبات ، مثل Bootstrap ، تعتمد على jQuery ، وهناك بعض القوالب الجاهزة للاستخدام التي تستخدمها ومكوناتها الإضافية.
ولكن هناك سبب آخر لهذا الكم من مواقع الويب التي تستخدم jQuery وهو تكلفة ترحيل تطبيق ويب كامل إلى إطار عمل جديد. إنها ليست سهلة وليست رخيصة وتستغرق وقتًا طويلاً. ولكن في النهاية ، فإن العمل باستخدام أدوات وتقنيات جديدة يجلب الكثير من الفوائد: دعم أوسع ، ومساعدة مجتمعية ، وتجربة مطور أفضل ، وسهولة جعل الأشخاص يعملون في المشروع.
هناك العديد من السيناريوهات التي لا نحتاج فيها (أو لا نريد) لاتباع البنية التي تفرضها علينا أطر مثل React أو Next.js ، وهذا أمر جيد. ومع ذلك ، فإن jQuery مكتبة تحتوي على الكثير من التعليمات البرمجية والميزات التي لم تعد مطلوبة بعد الآن. يمكن إنجاز العديد من الميزات التي يقدمها jQuery باستخدام وظائف JavaScript أصلية حديثة ، وربما بطريقة أكثر فاعلية.
دعونا نناقش كيف يمكننا التوقف عن استخدام jQuery وترحيل موقعنا الإلكتروني إلى تطبيق ويب React أو Next.js.
تحديد استراتيجية الهجرة
هل نحتاج مكتبة؟
اعتمادًا على ميزات تطبيق الويب الخاص بنا ، يمكننا حتى أن نحصل على الحالة التي لا نحتاج فيها إلى إطار عمل. كما ذكرنا سابقًا ، تم تضمين العديد من ميزات jQuery (أو على الأقل ميزة مشابهة جدًا) لأحدث إصدارات الويب القياسية. لذلك ، مع الأخذ في الاعتبار أن:
- يمكن استبدال نمط
$(selector)
من jQuery بـquerySelectorAll()
.
بدلًا من القيام بما يلي:
$("#someId");
يمكننا القيام به:
document.querySelectorAll("#someId");
- لدينا الآن
Element.classList
إذا أردنا معالجة فئات CSS.
بدلًا من القيام بما يلي:
$(selector).addClass(className);
يمكننا القيام به:
element.classList.add(className);
- يمكن عمل العديد من الرسوم المتحركة مباشرةً باستخدام CSS ، بدلاً من تنفيذ JavaScript.
بدلًا من القيام بما يلي:
$(selector).fadeIn();
يمكننا القيام به:
element.classList.add('show'); element.classList.remove('hide');
وقم بتطبيق بعض أنماط CSS:
.show { transition: opacity 400ms; } .hide { opacity: 0; }
- لدينا الآن وظيفة addEventListener إذا أردنا التعامل مع الأحداث.
بدلًا من القيام بما يلي:
$(selector).on(eventName, eventHandler);
يمكننا القيام به:
element.addEventListener(eventName, eventHandler);
- بدلاً من استخدام jQuery Ajax ، يمكننا استخدام
XMLHttpRequest
.
بدلًا من القيام بما يلي:
$.ajax({ type: 'POST', url: '/the-url', data: data });
يمكننا القيام به:
var request = new XMLHttpRequest(); request.open('POST', '/the-url', true); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); request.send(data);
لمزيد من التفاصيل ، يمكنك إلقاء نظرة على مقتطفات كود Vanilla JavaScript هذه.
تحديد المكونات
إذا كنا نستخدم jQuery في تطبيقنا ، فيجب أن يكون لدينا بعض محتوى HTML الذي يتم إنشاؤه على خادم الويب ، وشفرة JavaScript التي تضيف التفاعل إلى الصفحة. من المحتمل أننا نضيف معالجات الأحداث عند تحميل الصفحة والتي ستتعامل مع DOM عند حدوث الأحداث ، وربما يتم تحديث CSS أو نمط العناصر. يمكننا أيضًا استدعاء خدمات الواجهة الخلفية لتنفيذ الإجراءات التي يمكن أن تؤثر على DOM للصفحة أو حتى إعادة تحميلها.
ستكون الفكرة هي إعادة تشكيل شفرة JavaScript التي تعيش في الصفحات وبناء مكونات React. سيساعدنا هذا على الانضمام إلى التعليمات البرمجية ذات الصلة وتكوين العناصر التي ستكون جزءًا من تكوين أكبر. من خلال القيام بذلك ، سنتمكن أيضًا من التعامل بشكل أفضل مع حالة تطبيقنا. عند تحليل الواجهة الأمامية لتطبيقنا ، يجب أن نقسمها إلى أجزاء مخصصة لمهمة معينة ، حتى نتمكن من إنشاء مكونات بناءً على ذلك.
إذا كان لدينا زر:
<button>Click</button>
بالمنطق التالي:
var $btnAction = $("#btn-action"); $btnAction.on("click", function() { alert("Button was clicked"); });
يمكننا ترحيله إلى مكون React:
import React from 'react'; function ButtonComponent() { let handleButtonClick = () => { alert('Button clicked!') } return <button onClick={handleButtonClick}>Click</button> }
ولكن يجب علينا أيضًا تقييم كيفية إنجاز عملية الترحيل نظرًا لأن تطبيقنا يعمل ويتم استخدامه ، ولا نريد التأثير عليه (أو على الأقل التأثير عليه بأقل قدر ممكن).
الهجرة الجيدة
الترحيل الجيد هو الترحيل الذي يتم فيه ترحيل جميع أجزاء التطبيق بالكامل إلى إطار العمل أو التقنية الجديدة. سيكون هذا هو السيناريو المثالي لتطبيقنا لأننا سنحافظ على مزامنة جميع الأجزاء ، وسنستخدم أداة موحدة وإصدارًا مشارًا فريدًا.
عادةً ما يتضمن الترحيل الجيد والكامل إعادة كتابة كاملة لشفرة تطبيقنا ، وهذا أمر منطقي. إذا أنشأنا تطبيقًا من البداية ، فلدينا إمكانية تحديد الاتجاه الذي نريد أن نتخذه مع الكود الجديد. يمكننا استخدام وجهة نظر جديدة حول أنظمتنا الحالية وسير العمل لدينا ، وإنشاء تطبيق جديد بالكامل بالمعرفة التي لدينا في هذه اللحظة ، وهو أكثر اكتمالاً من الذي كان لدينا عندما أنشأنا تطبيق الويب لأول مرة.
لكن إعادة الكتابة الكاملة بها بعض المشاكل. بادئ ذي بدء ، إنها تتطلب الكثير من الوقت. كلما كان التطبيق أكبر ، سنحتاج إلى مزيد من الوقت لإعادة كتابته. مشكلة أخرى هي مقدار العمل ، وكمية المطورين ، التي يتطلبها الأمر. وإذا لم نقم بالترحيل التدريجي ، فعلينا التفكير في مقدار الوقت الذي لن يكون فيه تطبيقنا متاحًا.
عادة ، يمكن إنجاز إعادة كتابة كاملة بالمشاريع الصغيرة ، أو المشاريع التي لا تتغير بشكل متكرر ، أو التطبيقات التي ليست بالغة الأهمية لأعمالنا.
الهجرة السريعة
طريقة أخرى هي تقسيم التطبيق إلى أجزاء أو أجزاء. نقوم بترحيل التطبيق جزءًا تلو الآخر ، ونصدر تلك الأجزاء عندما تكون جاهزة. لذلك ، قمنا بترحيل أجزاء من تطبيقنا المتاح للمستخدمين ، والتعايش مع تطبيق الإنتاج الحالي لدينا.
من خلال هذا الترحيل التدريجي ، نقدم ميزات منفصلة لمشروعنا بطريقة أسرع للمستخدمين ، حيث لا يتعين علينا انتظار إعادة كتابة التطبيق الكامل. نحصل أيضًا على تعليقات أسرع من المستخدمين ، مما يسمح لنا باكتشاف الأخطاء أو المشكلات مسبقًا.
لكن الترحيل التدريجي يدفعنا إلى امتلاك أدوات ومكتبات وتبعيات وأطر عمل مختلفة. أو يمكننا حتى دعم إصدارات مختلفة من نفس الأداة. يمكن أن يؤدي هذا الدعم الموسع إلى حدوث تضارب في طلبنا.
يمكن أن نواجه مشاكل إذا كنا نطبق سياسات في النطاق العالمي لأن كل جزء من الأجزاء التي تم ترحيلها يمكن أن يعمل بطريقة مختلفة ، ولكن يتأثر بالشفرة التي تحدد المعلمات العالمية لنظامنا. مثال على ذلك هو استخدام منطق التسلسل لتصميم CSS.
تخيل أننا نعمل مع إصدارات مختلفة من jQuery عبر تطبيق الويب الخاص بنا لأننا أضفنا وظائف من الإصدارات الأحدث إلى الوحدات التي تم إنشاؤها لاحقًا. ما مدى تعقيد ترحيل جميع تطبيقاتنا إلى إصدار أحدث من jQuery؟ الآن ، تخيل نفس السيناريو ولكن انتقل إلى إطار عمل مختلف تمامًا مثل Next.js. يمكن أن يكون ذلك معقدًا.
هجرة فرانكشتاين
كتب Denys Mishunov مقالًا في Smashing Magazine يقدم بديلاً لهاتين الفكرتين للهجرة ، في محاولة للحصول على أفضل ما في المقاربتين السابقتين: The Frankenstein Migration. تؤسس عملية الترحيل في مكونين رئيسيين: الخدمات المصغرة ومكونات الويب.
تتكون عملية الترحيل من قائمة بالخطوات التي يجب اتباعها:
1. تحديد الخدمات المصغرة
بناءً على كود التطبيق الخاص بنا ، يجب أن نقسمه إلى أجزاء مستقلة مخصصة لوظيفة واحدة صغيرة. إذا كنا نفكر في استخدام React أو Next.js ، فيمكننا ربط مفهوم الخدمات المصغرة بالمكونات المختلفة التي لدينا.
لنفكر في تطبيق قائمة البقالة كمثال. لدينا قائمة بالأشياء التي يجب شراؤها ، ومدخلات لإضافة المزيد من الأشياء إلى القائمة. لذلك ، إذا أردنا تقسيم تطبيقنا إلى أجزاء صغيرة ، فيمكننا التفكير في مكون "قائمة العناصر" و "إضافة عنصر". عند القيام بذلك ، يمكننا فصل الوظيفة والترميز المتعلقين بكل جزء من هذه الأجزاء إلى مكونات React مختلفة.
للتأكد من أن المكونات مستقلة ، يجب أن نتمكن من إزالة أحدها من التطبيق ، ولا ينبغي أن تتأثر المكونات الأخرى بذلك. إذا حصلنا على خطأ عند إزالة الترميز والوظيفة من إحدى الخدمات ، فنحن لا نحدد المكونات بشكل صحيح ، أو نحتاج إلى إعادة تشكيل الطريقة التي تعمل بها التعليمات البرمجية الخاصة بنا.
2. السماح بوصول مضيف إلى أجنبي
"المضيف" هو تطبيقنا الحالي. "Alien" هو الذي سنبدأ في إنشائه ، مع إطار العمل الجديد. يجب أن يعمل كلاهما بشكل مستقل ، ولكن يجب أن نوفر الوصول من المضيف إلى الكائن الفضائي. يجب أن نكون قادرين على نشر أي من التطبيقين دون كسر التطبيق الآخر ، مع الحفاظ على الاتصال بينهما.
3. اكتب مكونًا غريبًا
أعد كتابة خدمة من تطبيق Host الخاص بنا إلى تطبيق Alien الخاص بنا ، باستخدام إطار العمل الجديد. يجب أن يتبع المكون نفس مبدأ الاستقلال الذي ذكرناه من قبل.
دعنا نعود إلى مثال قائمة البقالة. حددنا مكون "إضافة عنصر". باستخدام jQuery ، سيبدو ترميز المكون على النحو التالي:
<input class="new-item" />
وسيكون كود JavaScript / jQuery لإضافة العناصر إلى القائمة شيئًا كالتالي:
var ENTER_KEY = 13; $('.new-item').on('keyup', function (e) { var $input = $(e.target); var val = $input.val().trim(); if (e.which !== ENTER_KEY || !val) { return; } // code to add the item to the list $input.val(''); });
بدلاً من ذلك ، يمكننا إنشاء مكون AddItem
React:
import React from 'react' function AddItemInput({ defaultText }) { let [text, setText] = useState(defaultText) let handleSubmit = e => { e.preventDefault() if (e.which === 13) { setText(e.target.value.trim()) } } return <input type="text" value={text} onChange={(e) => setText(e.target.value)} onKeyDown={handleSubmit} /> }
4. كتابة غلاف مكون الويب حول خدمة الكائنات الفضائية
قم بإنشاء مكون غلاف يقوم باستيراد خدمة Alien التي أنشأناها للتو ويقوم بعرضها. تكمن الفكرة في إنشاء جسر بين تطبيق Host وتطبيق Alien. ضع في اعتبارك أننا قد نحتاج إلى أداة تجميع حزم لإنشاء كود JavaScript يعمل في تطبيقنا الحالي لأننا سنحتاج إلى نسخ مكونات React الجديدة الخاصة بنا وجعلها تعمل.
باتباع مثال قائمة البقالة ، يمكننا إنشاء ملف AddItem-wrapper.js
في مشروع المضيف. سيحتوي هذا الملف على الكود الذي يلف مكون AddItem
الذي تم إنشاؤه بالفعل ، وينشئ معه عنصرًا مخصصًا:
import React from "../alien/node_modules/react"; import ReactDOM from "../alien/node_modules/react-dom"; import AddItem from "../alien/src/components/AddItem"; class FrankensteinWrapper extends HTMLElement { connectedCallback() { const appWrapper = document.createElement("div"); appWrapper.classList.add("grocerylistapp"); ... ReactDOM.render( <HeaderApp />, appWrapper ); … } } customElements.define("frankenstein-add-item-wrapper", FrankensteinWrapper);
يجب أن نحضر وحدات ومكونات العقدة الضرورية من مجلدات تطبيق Alien لأننا نحتاج إلى استيرادها لجعل المكون يعمل.
5. استبدال خدمة المضيف بمكون الويب
سيحل مكون المجمع هذا محل المكون الموجود في تطبيق المضيف ، وسنبدأ في استخدامه. لذلك ، سيكون التطبيق في الإنتاج مزيجًا من مكونات المضيف والمكونات الملفوفة الغريبة.
في مثالنا لتطبيق المضيف ، يجب أن نستبدل:
<input class="new-item" />
مع
<frankenstein-add-item-wrapper></frankenstein-add-item-wrapper> ... <script type="module" src="js/AddItem-wrapper.js"></script>
6. شطف وكرر
انتقل من خلال الخطوات 3 و 4 و 5 لكل خدمة من الخدمات المصغرة المحددة.
7. التبديل إلى أجنبي
المضيف الآن عبارة عن مجموعة من مكونات الغلاف التي تتضمن جميع مكونات الويب التي أنشأناها في تطبيق Alien. نظرًا لأننا قمنا بتحويل جميع الخدمات المصغرة المحددة ، يمكننا القول أن تطبيق Alien قد انتهى وتم ترحيل جميع الخدمات. نحتاج فقط إلى توجيه مستخدمينا إلى تطبيق Alien الآن.
تعمل طريقة فرانكنشتاين للهجرة كمزيج من النهجين الصالح والسريع. نقوم بترحيل التطبيق الكامل ولكن نقوم بإصدار المكونات المختلفة عند الانتهاء. لذلك ، فهي متاحة للاستخدام في وقت قريب وتقييمها من قبل المستخدمين في الإنتاج.
ومع ذلك ، علينا أن نأخذ في الاعتبار أننا نقوم ببعض العمل الزائد مع هذا النهج. إذا أردنا استخدام المكونات التي أنشأناها لتطبيق Alien الخاص بنا ، فعلينا إنشاء مكون غلاف لتضمينه في تطبيق المضيف. هذا يجعلنا نقضي الوقت في تطوير الكود الخاص بعناصر الغلاف هذه. أيضًا ، من خلال استخدامها في تطبيق المضيف الخاص بنا ، فإننا نكرر تضمين الكود والتبعيات ، ونضيف رمزًا سيؤثر على أداء تطبيقنا.
تطبيق Strangler
نهج آخر يمكننا اتباعه هو خنق التطبيق القديم. نحدد حواف تطبيق الويب الحالي ، وكلما احتجنا إلى إضافة وظائف إلى تطبيقنا ، نقوم بذلك باستخدام إطار عمل أحدث حتى يتم "خنق" النظام القديم. يساعدنا هذا الأسلوب على تقليل المخاطر المحتملة التي يمكننا تجربتها أثناء ترحيل التطبيق.
لاتباع هذا النهج ، نحتاج إلى تحديد المكونات المختلفة ، كما نفعل في هجرة فرانكنشتاين. بمجرد تقسيم تطبيقنا إلى أجزاء مختلفة من التعليمات البرمجية الضرورية ذات الصلة ، نقوم بلفها في مكونات React جديدة. لا نضيف أي سلوك إضافي ، نحن فقط ننشئ مكونات React التي تعرض المحتوى الموجود لدينا.
دعونا نرى مثالاً لمزيد من التوضيح. افترض أن لدينا كود HTML هذا في تطبيقنا:
<div class="accordion"> <div class="accordion-panel"> <h3 class="accordion-header">Item 1</h3> <div class="accordion-body">Text 1</div> </div> <div class="accordion-panel"> <h3 class="accordion-header">Item 2</h3> <div class="accordion-body">Text 2</div> </div> <div class="accordion-panel"> <h3 class="accordion-header">Item 3</h3> <div class="accordion-body">Text 3</div> </div>> </div>
وشيفرة JavaScript هذه (لقد استبدلنا بالفعل وظائف jQuery بميزات JavaScript القياسية الجديدة).
const accordions = document.querySelectorAll(".accordion"); for (const accordion of accordions) { const panels = accordion.querySelectorAll(".accordion-panel"); for (const panel of panels) { const head = panel.querySelector(".accordion-header"); head.addEventListener('click', () => { for (const otherPanel of panels) { if (otherPanel !== panel) { otherPanel.classList.remove('accordion-expanded'); } } panel.classList.toggle('accordion-expanded'); }); } }
هذا تطبيق شائع لمكون accordion
لجافا سكريبت. نظرًا لأننا نريد تقديم React هنا ، فنحن بحاجة إلى تغليف كودنا الحالي بمكوِّن React جديد:
function Accordions() { useEffect(() => { const accordions = document.querySelectorAll(".accordion") for (const accordion of accordions) { const panels = accordion.querySelectorAll(".accordion-panel") for (const panel of panels) { const head = panel.querySelector(".accordion-header") head.addEventListener("click", () => { for (const otherPanel of panels) { if (otherPanel !== panel) { otherPanel.classList.remove("accordion-expanded") } } panel.classList.toggle("accordion-expanded") }); } } }, []) return null } ReactDOM.render(<Accordions />, document.createElement("div"))
المكون لا يضيف أي سلوك أو ميزة جديدة. نستخدم useEffect
لأنه تم تركيب المكون في المستند. هذا هو سبب إرجاع الدالة فارغة لأن الخطاف لا يحتاج إلى إرجاع مكون.
لذلك ، لم نضف أي وظائف جديدة إلى تطبيقنا الحالي ، لكننا قدمنا React دون تغيير سلوكه. من الآن فصاعدًا ، كلما أضفنا ميزات أو تغييرات جديدة إلى الكود الخاص بنا ، سنفعل ذلك باستخدام إطار العمل المحدد الأحدث.
العرض من جانب العميل أم العرض من جانب الخادم أم الجيل الثابت؟
يمنحنا Next.js إمكانية اختيار الطريقة التي نريد بها عرض كل صفحة من صفحات تطبيق الويب الخاص بنا. يمكننا استخدام العرض من جانب العميل الذي تقدمه لنا React بالفعل لإنشاء المحتوى مباشرة في متصفح المستخدم. أو يمكننا عرض محتوى صفحتنا في الخادم باستخدام العرض من جانب الخادم. أخيرًا ، يمكننا إنشاء محتوى صفحتنا في وقت الإنشاء باستخدام الجيل الثابت.
في تطبيقنا ، يجب أن نقوم بتحميل وعرض التعليمات البرمجية عند تحميل الصفحة ، قبل أن نبدأ في التفاعل مع أي مكتبة أو إطار عمل JavaScript. قد نستخدم لغة أو تقنية برمجة عرض من جانب الخادم ، مثل ASP.NET أو PHP أو Node.js. يمكننا الاستفادة من ميزات Next.js واستبدال طريقة العرض الحالية بطريقة العرض Next.js من جانب الخادم . عند القيام بذلك ، نحتفظ بكل السلوك داخل نفس المشروع ، الذي يعمل تحت مظلة إطار العمل الذي اخترناه. أيضًا ، نحتفظ بمنطق صفحتنا الرئيسية ومكونات React في نفس الكود الذي يولد كل المحتوى المطلوب لصفحتنا.
دعنا نفكر في صفحة لوحة القيادة كمثال. يمكننا إنشاء كل الترميز الأولي للصفحة في وقت التحميل ، في الخادم ، بدلاً من الاضطرار إلى إنشائها باستخدام React في متصفح الويب الخاص بالمستخدم.
const DashboardPage = ({ user }) => { return ( <div> <h2>{user.name}</h2> // User data </div> ) } export const getServerSideProps = async ({ req, res, params }) => { return { props: { user: getUser(), }, } }, }) export default DashboardPage
إذا كان الترميز الذي نعرضه عند تحميل الصفحة يمكن التنبؤ به ويعتمد على البيانات التي يمكننا استردادها في وقت الإنشاء ، فسيكون الإنشاء الثابت خيارًا جيدًا. سيؤدي إنشاء أصول ثابتة في وقت الإنشاء إلى جعل تطبيقنا أسرع وأكثر أمانًا وقابلية للتطوير وأسهل في الصيانة. وفي حالة احتياجنا إلى إنشاء محتوى ديناميكي على صفحات تطبيقنا ، يمكننا استخدام عرض React من جانب العميل لاسترداد المعلومات من الخدمات أو مصادر البيانات.
تخيل أن لدينا موقع مدونة به العديد من منشورات المدونات. إذا استخدمنا Static Generation ، فيمكننا إنشاء ملف [blog-slug].js
عام في تطبيق Next.js الخاص بنا ، وإضافة الكود التالي سننشئ جميع الصفحات الثابتة لمنشورات مدونتنا في وقت الإنشاء.
export const getStaticPaths = async () => { const blogPosts = await getBlogPosts() const paths = blogPosts.map(({ slug }) => ({ params: { slug, }, })) return { paths, fallback: false, } } export const getStaticProps = async ({ params }) => { const { slug } = params const blogPost = await getBlogPostBySlug(slug) return { props: { data: JSON.parse(JSON.stringify(blogPost)), }, } }
إنشاء API باستخدام مسارات API
إحدى الميزات الرائعة التي يقدمها Next.js هي إمكانية إنشاء مسارات API. بواسطتهم ، يمكننا إنشاء وظائف بدون خوادم خاصة بنا باستخدام Node.js. يمكننا أيضًا تثبيت حزم NPM لتوسيع الوظائف. الشيء الرائع في هذا الأمر هو أن واجهة برمجة التطبيقات الخاصة بنا ستغادر في نفس المشروع / التطبيق مثل الواجهة الأمامية ، لذلك لن نواجه أي مشكلات في CORS.
إذا احتفظنا بواجهة برمجة تطبيقات يتم استدعاؤها من تطبيق الويب الخاص بنا باستخدام وظيفة jQuery AJAX ، فيمكننا استبدالها باستخدام مسارات API . عند القيام بذلك ، سنحتفظ بكافة التعليمات البرمجية لتطبيقنا في نفس المستودع ، وسنجعل نشر تطبيقنا أكثر بساطة. إذا كنا نستخدم خدمة جهة خارجية ، فيمكننا استخدام مسارات واجهة برمجة التطبيقات لـ "إخفاء" عناوين URL الخارجية.
يمكن أن يكون لدينا مسار API /pages/api/get/[id].js
الذي يعرض البيانات التي نستخدمها على صفحتنا.
export default async (req, res) => { const { id } = req.query try { const data = getData(id) res.status(200).json(data) } catch (e) { res.status(500).json({ error: e.message }) } }
وندعوها من كود صفحتنا.
const res = await fetch(`/api/get/${id}`, { method: 'GET', }) if (res.status === 200) { // Do something } else { console.error(await res.text()) }
انشر في Netlify
Netlify عبارة عن نظام أساسي كامل يمكن استخدامه لأتمتة تطبيقات الويب وإدارتها وبناءها واختبارها ونشرها واستضافتها. يحتوي على الكثير من الميزات التي تجعل تطوير تطبيقات الويب الحديثة أسهل وأسرع. بعض ميزات Netlify المميزة هي:
- منصة استضافة عالمية لشبكة CDN ،
- دعم وظائف Serverless ،
- نشر المعاينات بناءً على طلبات Github Pull ،
- ويب هوك ،
- التراجع الفوري ،
- التحكم في الوصول على أساس الدور.
يعد Netlify نظامًا أساسيًا رائعًا لإدارة واستضافة تطبيقات Next.js الخاصة بنا ، ومن السهل جدًا نشر تطبيق ويب باستخدامه.
بادئ ذي بدء ، نحتاج إلى تتبع كود تطبيق Next.js في مستودع Git. يتصل Netlify بـ GitHub (أو منصة Git التي نفضلها) ، وعندما يتم إدخال تغيير على فرع (التزام أو طلب سحب) ، سيتم تشغيل مهمة "إنشاء ونشر" تلقائية.
بمجرد أن يكون لدينا مستودع Git به كود تطبيقنا ، نحتاج إلى إنشاء "موقع Netlify" له. للقيام بذلك ، لدينا خياران:
- استخدام Netlify CLI
بعد تثبيت CLI (npm install -g netlify-cli
) وتسجيل الدخول إلى حساب Netlify الخاص بنا (ntl login
) ، يمكننا الانتقال إلى الدليل الجذر لتطبيقنا وتشغيلntl init
واتباع الخطوات. - باستخدام تطبيق الويب Netlify
يجب أن نذهب إلى https://app.netlify.com/start. اتصل بموفر Git الخاص بنا ، واختر مستودع التطبيق الخاص بنا من القائمة ، وقم بتكوين بعض خيارات البناء ، ثم انشر.
لكلتا الطريقتين ، علينا أن نأخذ في الاعتبار أن أمر البناء الخاص بنا سيكون next build
وأن الدليل الذي سيتم نشره out
.
أخيرًا ، يتم تثبيت المكون الإضافي Essential Next.js تلقائيًا ، مما يسمح لنا بنشر واستخدام مسارات واجهة برمجة التطبيقات والمسارات الديناميكية ووضع المعاينة. وهذا كل شيء ، لدينا تطبيق Next.js الخاص بنا وتشغيله في خدمة استضافة CDN سريعة ومستقرة.
خاتمة
في هذه المقالة ، قمنا بتقييم مواقع الويب باستخدام مكتبة jQuery ، وقمنا بمقارنتها بأطر جديدة للواجهة الأمامية مثل React و Next.js. لقد حددنا كيف يمكننا بدء الترحيل ، في حالة ما إذا كان ذلك مفيدًا لنا ، إلى أداة أحدث. قمنا بتقييم استراتيجيات الترحيل المختلفة ورأينا بعض الأمثلة على السيناريوهات التي يمكننا ترحيلها إلى مشاريع تطبيقات الويب Next.js. أخيرًا ، رأينا كيفية نشر تطبيق Next.js الخاص بنا على Netlify وتشغيله.
مزيد من القراءة والموارد
- هجرة فرانكشتاين: نهج الإطار الحيادي
- إزالة jQuery من الواجهة الأمامية لـ GitHub.com
- الابتداء مع Next.js
- كيفية نشر مواقع Next.js على Netlify
- مقالات Next.js في مدونة Netlify