วิธีการโยกย้ายจาก jQuery ไปยัง Next.js
เผยแพร่แล้ว: 2022-03-10บทความนี้ได้รับการสนับสนุนอย่างดีจากเพื่อนรักของเราที่ Netlify ซึ่งเป็นกลุ่มที่มีความสามารถอันน่าทึ่งจากทั่วทุกมุมโลก และมีแพลตฟอร์มสำหรับนักพัฒนาเว็บที่เพิ่มผลิตภาพ ขอขอบคุณ!
เมื่อ jQuery ปรากฏขึ้นในปี 2549 นักพัฒนาและองค์กรจำนวนมากเริ่มนำไปใช้ในโครงการของตน ความเป็นไปได้ในการ ขยายและจัดการ DOM ที่ไลบรารีนำเสนอนั้นยอดเยี่ยม และเรายังมีปลั๊กอินมากมายที่จะเพิ่มพฤติกรรมให้กับเพจของเรา ในกรณีที่เราจำเป็นต้องทำงานที่ไม่ได้รับการสนับสนุนโดยไลบรารีหลักของ jQuery มันทำให้งานจำนวนมากสำหรับนักพัฒนาง่ายขึ้น และในขณะนั้น มันทำให้ JavaScript เป็นภาษาที่ทรงพลังในการสร้างเว็บแอปพลิเคชันหรือแอปพลิเคชันหน้าเดียว
ผลลัพธ์ของ ความนิยม jQuery ยังคงวัดได้ในปัจจุบัน: เกือบ 80% ของเว็บไซต์ยอดนิยมที่สุดในโลกยังคงใช้งานอยู่ สาเหตุบางประการที่ jQuery ได้รับความนิยมคือ:
- รองรับการจัดการ DOM
- มันให้การจัดการ CSS
- ทำงานเหมือนกันในทุกเว็บเบราว์เซอร์
- มันห่อวิธีการเหตุการณ์ HTML
- สร้างการโทร AJAX ได้ง่าย
- เอฟเฟกต์และแอนิเมชั่นที่ใช้งานง่าย
หลายปีที่ผ่านมา JavaScript เปลี่ยนแปลงไปมากและเพิ่มคุณสมบัติหลายอย่างที่เราไม่เคยมีมาก่อน ด้วยการกำหนดนิยามใหม่และวิวัฒนาการของ ECMAScript ฟังก์ชันการทำงานบางอย่างที่ jQuery ให้มานั้นถูกเพิ่มเข้าไปในคุณสมบัติ JavaScript มาตรฐานและรองรับโดยเว็บเบราว์เซอร์ทั้งหมด เมื่อสิ่งนี้เกิดขึ้น พฤติกรรมบางอย่างที่ jQuery เสนอ ก็ไม่จำเป็นอีกต่อไป เนื่องจากเราสามารถทำสิ่งเดียวกันกับ JavaScript ธรรมดาได้
ในทางกลับกัน วิธีคิดและการออกแบบอินเทอร์เฟซผู้ใช้แบบใหม่เริ่มปรากฏขึ้น กรอบงานเช่น React, Angular หรือ Vue ช่วยให้นักพัฒนาสามารถสร้างเว็บแอปพลิเคชันตามส่วนประกอบการทำงานที่นำกลับมาใช้ใหม่ได้ React กล่าวคือ ทำงานร่วมกับ “virtual DOM” ซึ่งเป็นการแสดง DOM ในหน่วยความจำ ในขณะที่ jQuery โต้ตอบโดยตรงกับ DOM ด้วยวิธีที่มีประสิทธิภาพน้อยกว่า นอกจากนี้ React ยังนำเสนอฟีเจอร์เจ๋งๆ เพื่ออำนวยความสะดวกในการพัฒนาคุณสมบัติบางอย่าง เช่น การจัดการสถานะ ด้วยแนวทางใหม่และความนิยมที่ Single Page Applications เริ่มได้รับ นักพัฒนาจำนวนมากเริ่มใช้ React สำหรับโครงการเว็บแอปพลิเคชันของพวกเขา
และการพัฒนาส่วนหน้าก็มีการพัฒนามากยิ่งขึ้นด้วยเฟรมเวิร์กที่สร้างขึ้นบนเฟรมเวิร์กอื่นๆ นั่นคือกรณีของ Next.js อย่างที่คุณอาจทราบแล้ว มันเป็นเฟรมเวิร์ก React แบบโอเพ่นซอร์สที่มีคุณสมบัติในการสร้างเพจแบบสแตติก สร้างเพจที่แสดงผลฝั่งเซิร์ฟเวอร์ และรวมทั้งสองประเภทไว้ในแอปพลิเคชันเดียวกัน นอกจากนี้ยังอนุญาตให้สร้าง API แบบไร้เซิร์ฟเวอร์ภายในแอปเดียวกัน
มีสถานการณ์ที่น่าสงสัย: แม้ว่าเฟรมเวิร์กส่วนหน้าเหล่านี้จะได้รับความนิยมมากขึ้นเรื่อยๆ ในช่วงหลายปีที่ผ่านมา แต่ jQuery ยังคงถูกนำไปใช้โดยหน้าเว็บส่วนใหญ่ สาเหตุหนึ่งที่ทำให้เกิดเหตุการณ์นี้ก็คือเปอร์เซ็นต์ของเว็บไซต์ที่ใช้ WordPress นั้นสูงมาก และ jQuery ก็รวมอยู่ใน CMS อีกสาเหตุหนึ่งคือ ไลบรารีบางตัว เช่น 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 Code Snippets เหล่านี้ได้
ระบุส่วนประกอบ
หากเราใช้ jQuery ในแอปพลิเคชันของเรา เราควรมีเนื้อหา HTML ที่สร้างขึ้นบนเว็บเซิร์ฟเวอร์ และโค้ด JavaScript ที่เพิ่มการโต้ตอบให้กับเพจ เราอาจ เพิ่มตัวจัดการเหตุการณ์ ในการโหลดหน้าเว็บที่จะจัดการกับ DOM เมื่อเหตุการณ์เกิดขึ้น อาจเป็นการอัปเดต CSS หรือรูปแบบขององค์ประกอบ เราอาจเรียกบริการแบ็กเอนด์เพื่อดำเนินการ ซึ่งอาจส่งผลต่อ DOM ของเพจ หรือแม้แต่โหลดซ้ำ
แนวคิดคือการปรับ โครงสร้างโค้ด JavaScript ที่ อยู่ในหน้าเว็บและสร้างส่วนประกอบ React ซึ่งจะช่วยให้เรารวมโค้ดที่เกี่ยวข้องและเขียนองค์ประกอบที่จะเป็นส่วนหนึ่งขององค์ประกอบที่ใหญ่ขึ้น การทำเช่นนี้จะทำให้เราสามารถจัดการสถานะแอปพลิเคชันของเราได้ดียิ่งขึ้น การวิเคราะห์ส่วนหน้าของแอปพลิเคชันของเรา เราควรแบ่งส่วนนั้นออกเป็นส่วนๆ สำหรับงานเฉพาะ เพื่อให้เราสามารถสร้างส่วนประกอบตามนั้นได้
หากเรามีปุ่ม:
<button>Click</button>
ด้วยตรรกะดังนี้
var $btnAction = $("#btn-action"); $btnAction.on("click", function() { alert("Button was clicked"); });
เราสามารถย้ายไปยัง React Component:
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 โดยเป็นพื้นฐานของกระบวนการย้ายข้อมูลในสององค์ประกอบหลัก ได้แก่ Microservices และ Web Components
กระบวนการย้ายข้อมูลประกอบด้วยรายการขั้นตอนที่ต้องปฏิบัติตาม:
1. ระบุไมโครเซอร์วิส
ตามรหัสแอปของเรา เราควรแบ่งออกเป็นส่วนๆ ที่แยกจากกันซึ่งใช้สำหรับงานเล็กๆ งานเดียว หากเรากำลังคิดที่จะใช้ React หรือ Next.js เราสามารถเชื่อมโยงแนวคิดของไมโครเซอร์วิสกับส่วนประกอบต่างๆ ที่เรามี
ลองนึกถึงแอปพลิเคชันรายการขายของชำเป็นตัวอย่าง เรามีรายการของที่ต้องซื้อและอินพุตสำหรับเพิ่มสิ่งต่างๆ ในรายการ ดังนั้น หากเราต้องการแยกแอปของเราออกเป็นส่วนเล็กๆ เราอาจคิดถึงองค์ประกอบ "รายการสินค้า" และ "เพิ่มรายการ" การทำเช่นนี้ เราสามารถแยกการทำงานและมาร์กอัปที่เกี่ยวข้องกับแต่ละส่วนเหล่านั้นออกเป็นส่วนประกอบ React ที่แตกต่างกัน
เพื่อยืนยันองค์ประกอบเป็นอิสระ เราควรจะสามารถลบหนึ่งในองค์ประกอบออกจากแอป และองค์ประกอบอื่น ๆ ไม่ควรได้รับผลกระทบจากสิ่งนั้น หากเราได้รับข้อผิดพลาดขณะลบมาร์กอัปและฟังก์ชันการทำงานออกจากบริการ แสดงว่าเราไม่สามารถระบุส่วนประกอบได้อย่างถูกต้อง หรือเราจำเป็นต้องปรับโครงสร้างวิธีการทำงานของโค้ดใหม่
2. อนุญาตการเข้าถึงจากโฮสต์สู่เอเลี่ยน
“โฮสต์” คือแอปพลิเคชันที่มีอยู่ของเรา “เอเลี่ยน” คือสิ่งที่เราจะเริ่มสร้างด้วยเฟรมเวิร์กใหม่ ทั้งสองควรทำงานแยกกัน แต่เราควรให้การเข้าถึงจากโฮสต์ไปยังเอเลี่ยน เราควรจะสามารถปรับใช้แอปพลิเคชันใดก็ได้จากสองแอปพลิเคชันโดยไม่ทำให้แอปพลิเคชันอื่นเสียหาย แต่ยังคงรักษาการสื่อสารระหว่างแอปพลิเคชันเหล่านี้ไว้
3. เขียนส่วนประกอบต่างด้าว
เขียนบริการใหม่จากแอปพลิเคชันโฮสต์ของเราลงในแอปพลิเคชัน 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. เขียน Web Component Wrapper รอบ Alien Service
สร้างองค์ประกอบ wrapper ที่นำเข้าบริการ Alien ที่เราเพิ่งสร้างขึ้นและแสดงผล แนวคิดคือการสร้างสะพานเชื่อมระหว่างแอพ Host และแอพ Alien โปรดทราบว่าเราอาจต้องใช้แพ็คเกจ Bundler เพื่อสร้างโค้ด JavaScript ที่ทำงานในแอปพลิเคชันปัจจุบันของเรา เนื่องจากเราจะต้องคัดลอกส่วนประกอบ React ใหม่ของเราและทำให้ใช้งานได้
ตามตัวอย่างรายการขายของชำ เราสามารถสร้างไฟล์ AddItem-wrapper.js
ในโครงการ Host ไฟล์นี้จะมีโค้ดที่ล้อมองค์ประกอบ 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. แทนที่บริการโฮสต์ด้วยส่วนประกอบเว็บ
ส่วนประกอบ wrapper นี้จะแทนที่องค์ประกอบในแอปพลิเคชัน Host และเราจะเริ่มใช้งาน ดังนั้น แอปพลิเคชันในการผลิตจะเป็นการผสมผสานระหว่างส่วนประกอบโฮสต์และส่วนประกอบที่ห่อหุ้มด้วยเอเลี่ยน
ในตัวอย่างแอปพลิเคชัน Host ของเรา เราควรแทนที่:
<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. เปลี่ยนไปใช้เอเลี่ยน
ขณะนี้ Host เป็นชุดของส่วนประกอบ wrapper ที่รวมส่วนประกอบเว็บทั้งหมดที่เราสร้างขึ้นในแอปพลิเคชัน Alien เมื่อเราแปลงไมโครเซอร์วิสที่ระบุทั้งหมด เราสามารถพูดได้ว่าแอปพลิเคชัน Alien เสร็จสิ้นและบริการทั้งหมดได้รับการโยกย้ายแล้ว เราแค่ต้องชี้ผู้ใช้ของเราไปที่แอปพลิเคชัน Alien ทันที
วิธีการโยกย้ายแฟรงเกนสไตน์ทำงานเป็นการผสมผสานระหว่างแนวทางที่ดีและรวดเร็ว เราโยกย้ายแอปพลิเคชันที่สมบูรณ์ แต่ปล่อยส่วนประกอบต่างๆ เมื่อทำเสร็จแล้ว ดังนั้นจึงพร้อมใช้งานเร็วกว่านี้และประเมินโดยผู้ใช้ในการผลิต
อย่างไรก็ตาม เราต้องพิจารณาว่าเรากำลังทำงานมากเกินไปกับแนวทางนี้ หากเราต้องการใช้ส่วนประกอบที่เราสร้างขึ้นสำหรับแอปพลิเคชัน Alien ของเรา เราต้องสร้างส่วนประกอบห่อหุ้มเพื่อรวมไว้ในแอปโฮสต์ ทำให้เราใช้เวลาในการพัฒนาโค้ดสำหรับองค์ประกอบ wrapper เหล่านี้ นอกจากนี้ การใช้สิ่งเหล่านี้ในแอปพลิเคชันโฮสต์ เรากำลังทำซ้ำการรวมโค้ดและการพึ่งพา และเพิ่มโค้ดที่จะส่งผลต่อประสิทธิภาพของแอปพลิเคชันของเรา
แอพพลิเคชั่นคนแปลกหน้า
อีกแนวทางหนึ่งที่เราสามารถทำได้คือ Legacy Application Strangulation เราระบุขอบของเว็บแอปพลิเคชันที่มีอยู่ของเรา และเมื่อใดก็ตามที่เราต้องการเพิ่มฟังก์ชันการทำงานให้กับแอปของเรา เราจะดำเนินการโดยใช้เฟรมเวิร์กที่ใหม่กว่าจนกว่าระบบเก่าจะ "รัดคอ" แนวทางนี้ช่วยให้เราลดความเสี่ยงที่อาจเกิดขึ้นขณะทำการย้ายแอป
เพื่อให้เป็นไปตามแนวทางนี้ เราจำเป็นต้องระบุองค์ประกอบต่างๆ เช่นเดียวกับที่เราทำใน Frankenstein Migration เมื่อเราแบ่งแอปของเราออกเป็นโค้ดที่จำเป็นต่างๆ ที่เกี่ยวข้อง เราจะรวมแอปไว้ในส่วนประกอบ 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
สำหรับ JavaScript เนื่องจากเราต้องการแนะนำ 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
เนื่องจากมีการติดตั้งส่วนประกอบในเอกสาร นั่นคือเหตุผลที่ฟังก์ชันคืนค่า null เนื่องจาก hook ไม่จำเป็นต้องส่งคืนส่วนประกอบ
ดังนั้นเราจึงไม่ได้เพิ่มฟังก์ชันการทำงานใหม่ให้กับแอปที่มีอยู่ของเรา แต่เราแนะนำ 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 เพื่อขยายการทำงานได้อีกด้วย สิ่งที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้ก็คือ API ของเราจะปล่อยให้อยู่ในโปรเจ็กต์/แอปเดียวกันกับส่วนหน้า ดังนั้นเราจะไม่มีปัญหา CORS ใดๆ
หากเรารักษา API ที่เรียกจากเว็บแอปพลิเคชันของเราโดยใช้ฟังก์ชัน jQuery AJAX เราสามารถแทนที่ได้โดยใช้ เส้นทาง API การทำเช่นนี้ เราจะเก็บ codebase ทั้งหมดของแอปของเราไว้ในที่เก็บเดียวกัน และเราจะทำให้การปรับใช้งานแอปพลิเคชันของเราง่ายขึ้น หากเราใช้บริการของบุคคลที่สาม เราสามารถใช้เส้นทาง 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
- เว็บฮุค,
- ย้อนกลับทันที
- การควบคุมการเข้าถึงตามบทบาท
Netlify เป็นแพลตฟอร์มที่ยอดเยี่ยมในการจัดการและโฮสต์แอปพลิเคชัน Next.js ของเรา และมันค่อนข้างง่ายในการปรับใช้เว็บแอปด้วย
ก่อนอื่น เราต้อง ติดตามโค้ดแอป Next.js ของเรา ในที่เก็บ Git Netlify เชื่อมต่อกับ GitHub (หรือแพลตฟอร์ม Git ที่เราต้องการ) และเมื่อใดก็ตามที่มีการเปลี่ยนแปลงเกิดขึ้นในสาขา (การคอมมิตหรือคำขอดึง) งาน "สร้างและปรับใช้" อัตโนมัติจะถูกทริกเกอร์
เมื่อเรามีที่เก็บ Git ที่มีโค้ดของแอปแล้ว เราต้องสร้าง "Netlify Site" สำหรับมัน ในการทำเช่นนี้ เรามีสองตัวเลือก:
- การใช้ Netlify CLI
หลังจากที่เราติดตั้ง CLI (npm install -g netlify-cli
) และเข้าสู่บัญชี Netlify ของเรา (ntl login
) เราสามารถไปที่ไดเร็กทอรีรากของแอปพลิเคชันของเรา รันntl init
และทำตามขั้นตอนต่างๆ - การใช้เว็บแอป Netlify
เราควรเข้าไปที่ https://app.netlify.com/start เชื่อมต่อกับผู้ให้บริการ Git เลือกที่เก็บแอปพลิเคชันของเราจากรายการ กำหนดค่าตัวเลือกการสร้างและปรับใช้
สำหรับทั้งสองวิธี เราต้องพิจารณาว่าคำสั่ง build ของเราจะเป็น next build
และไดเร็กทอรีของเราจะใช้งานนั้น out
สุดท้าย ปลั๊กอิน Essential Next.js จะถูกติดตั้งโดยอัตโนมัติ ซึ่งช่วยให้เราปรับใช้และใช้เส้นทาง API เส้นทางแบบไดนามิก และโหมดแสดงตัวอย่างได้ และนั่นคือทั้งหมด เรามีแอปพลิเคชัน Next.js และทำงานในบริการโฮสติ้ง CDN ที่รวดเร็วและเสถียร
บทสรุป
ในบทความนี้ เราประเมินเว็บไซต์โดยใช้ไลบรารี jQuery และเปรียบเทียบกับเฟรมเวิร์กส่วนหน้าใหม่ เช่น React และ Next.js เรากำหนดวิธีที่เราสามารถเริ่มการย้ายข้อมูลในกรณีที่เป็นประโยชน์ต่อเรา ไปสู่เครื่องมือที่ใหม่กว่า เราประเมินกลยุทธ์การย้ายข้อมูลต่างๆ และได้เห็นตัวอย่างสถานการณ์ต่างๆ ที่เราสามารถย้ายไปยังโครงการเว็บแอปพลิเคชัน Next.js ในที่สุด เราก็ได้เห็นวิธีการปรับใช้แอปพลิเคชัน Next.js ของเรากับ Netlify และเริ่มต้นใช้งาน
การอ่านและทรัพยากรเพิ่มเติม
- การย้ายถิ่นของแฟรงเกนสไตน์: แนวทางกรอบงานไม่เชื่อเรื่องพระเจ้า
- การลบ jQuery ออกจากส่วนหน้าของ GitHub.com
- เริ่มต้นใช้งาน Next.js
- วิธีการปรับใช้ไซต์ Next.js กับ Netlify
- บทความ Next.js ใน Netlify Blog