ก่อนอื่นฉันต้องการทราบว่า Hot Module Replacement (HMR) ยังคงเป็นคุณลักษณะทดลอง
HMR เป็นวิธีการแลกเปลี่ยนโมดูลในแอปพลิเคชันที่กำลังทำงาน (และการเพิ่ม / ลบโมดูล) โดยทั่วไปคุณสามารถอัปเดตโมดูลที่เปลี่ยนแปลงโดยไม่ต้องโหลดหน้าเต็ม
เอกสาร
Prerequirements:
มันไม่มากสำหรับ HMR แต่นี่คือลิงค์:
ฉันจะเพิ่มคำตอบเหล่านี้ลงในเอกสาร
มันทำงานยังไง?
จากมุมมองแอพ
รหัสแอปขอให้รันไทม์ HMR เพื่อตรวจสอบการอัพเดต HMR รันไทม์ดาวน์โหลดอัปเดต (async) และบอกรหัสแอพว่ามีการอัปเดต รหัสแอปขอให้รันไทม์ HMR เพื่อใช้การอัปเดต HMR รันไทม์ใช้การอัพเดต (ซิงค์) รหัสแอปอาจหรือไม่จำเป็นต้องมีการโต้ตอบกับผู้ใช้ในกระบวนการนี้ (คุณเป็นผู้ตัดสินใจ)
จากมุมมองคอมไพเลอร์ (webpack)
นอกเหนือจากเนื้อหาปกติคอมไพเลอร์ต้องปล่อย "อัปเดต" เพื่ออนุญาตการอัปเดตจากเวอร์ชันก่อนหน้าเป็นเวอร์ชันนี้ "อัพเดท" มีสองส่วน:
- ไฟล์อัพเดท (json)
- ชิ้นส่วนอัพเดทหนึ่งหรือหลายชิ้น (js)
ไฟล์ Manifest มีแฮชการคอมไพล์ใหม่และรายการรายการอัพเดตทั้งหมด (2)
ชิ้นส่วนอัปเดตมีรหัสสำหรับโมดูลที่อัปเดตทั้งหมดในกลุ่มนี้ (หรือตั้งค่าสถานะหากโมดูลถูกลบ)
คอมไพเลอร์เพิ่มเติมทำให้แน่ใจว่าโมดูลและรหัสก้อนมีความสอดคล้องกันระหว่างบิลด์เหล่านี้ มันใช้ไฟล์ "บันทึก" json เพื่อจัดเก็บระหว่าง build (หรือเก็บไว้ในหน่วยความจำ)
จากมุมมองโมดูล
HMR เป็นคุณสมบัติการเลือกใช้ดังนั้นจะมีผลกับโมดูลที่มีรหัส HMR เท่านั้น เอกสารอธิบายถึง API ที่มีอยู่ในโมดูล โดยทั่วไปผู้พัฒนาโมดูลจะเขียนตัวจัดการที่ถูกเรียกเมื่อมีการอัพเดทโมดูลนี้ พวกเขายังสามารถเขียนตัวจัดการที่เรียกว่าเมื่อโมดูลนี้มีการปรับปรุง
ในกรณีส่วนใหญ่ไม่จำเป็นต้องเขียนรหัส HMR ในทุกโมดูล หากโมดูลไม่มี HMR handler การอัพเดตจะเพิ่มขึ้น ซึ่งหมายความว่าตัวจัดการเดียวสามารถจัดการอัพเดตสำหรับแผนผังโมดูลที่สมบูรณ์ ถ้ามีการอัพเดตโมดูลเดียวในแผนผังนี้ทรีโมดูลที่สมบูรณ์จะถูกโหลดใหม่ (โหลดซ้ำเท่านั้นไม่ถูกถ่ายโอน)
จากมุมมองรันไทม์ HMR (ทางเทคนิค)
รหัสเพิ่มเติมถูกปล่อยออกมาสำหรับระบบ runtime โมดูลโมดูลในการติดตามและparents
children
ในด้านการจัดการการรันไทม์สนับสนุนสองวิธี: และcheck
apply
A check
จะทำการร้องขอ HTTP ไปยังไฟล์ Manifest Update เมื่อคำขอนี้ล้มเหลวจะไม่มีการอัปเดต บอกรายการของชิ้นส่วนที่อัพเดตแล้วเปรียบเทียบกับรายการของชิ้นส่วนที่โหลดอยู่ในปัจจุบัน สำหรับแต่ละกลุ่มที่โหลดโหลดกลุ่มที่เกี่ยวข้องจะถูกดาวน์โหลด การอัปเดตโมดูลทั้งหมดจะถูกเก็บไว้ในรันไทม์เป็นการอัพเดท รันไทม์เปลี่ยนเป็นready
สถานะซึ่งหมายความว่ามีการดาวน์โหลดการอัปเดตและพร้อมใช้งาน
สำหรับคำร้องขออันใหม่แต่ละอันในสถานะพร้อมอัพเดตชิ้นจะถูกดาวน์โหลดด้วย
apply
วิธีธงโมดูลการปรับปรุงทั้งหมดเป็นที่ไม่ถูกต้อง สำหรับแต่ละโมดูลที่ไม่ถูกต้องจะต้องมีตัวจัดการการอัปเดตในโมดูลหรือตัวจัดการการอัปเดตในทุกพาเรนต์ กำจัดฟองที่ไม่ถูกต้องออกไปและทำเครื่องหมายว่าผู้ปกครองทุกคนไม่ถูกต้องเช่นกัน กระบวนการนี้จะดำเนินต่อไปจนกว่าจะไม่มี "ฟองสบู่" เกิดขึ้นอีก ถ้ามันเป่าขึ้นไปถึงจุดเริ่มต้นกระบวนการล้มเหลว
ตอนนี้โมดูลที่ไม่ถูกต้องทั้งหมดจะถูกกำจัด (จัดการ handler) และยกเลิกการโหลด จากนั้นแฮชปัจจุบันจะถูกอัพเดตและตัวจัดการ "ยอมรับ" ทั้งหมดจะถูกเรียก รันไทม์สลับกลับไปเป็นidle
สถานะและทุกอย่างดำเนินต่อไปตามปกติ
ฉันจะทำอย่างไรกับมัน?
คุณสามารถใช้มันในการพัฒนาแทน LiveReload ที่จริงแล้ว webpack-dev-server รองรับโหมดร้อนซึ่งพยายามอัปเดตด้วย HMR ก่อนที่จะพยายามโหลดซ้ำทั้งหน้า คุณจะต้องเพิ่มwebpack/hot/dev-server
จุดเข้าและโทร dev --hot
เซิร์ฟเวอร์ด้วย
คุณยังสามารถใช้ในการผลิตเป็นกลไกการอัพเดท ที่นี่คุณต้องเขียนรหัสการจัดการของคุณเองที่รวม HMR เข้ากับแอปของคุณ
ตัวตักบางตัวสร้างโมดูลที่อัพเดตได้อย่างรวดเร็วอยู่แล้ว เช่นstyle-loader
สามารถแลกเปลี่ยนสไตล์ชีท คุณไม่จำเป็นต้องทำอะไรเป็นพิเศษ
สมมติว่าฉันต้องการอัปเดต CSS (หนึ่งสไตล์ชีท) และโมดูล JS เมื่อฉันบันทึกลงในดิสก์โดยไม่ต้องโหลดหน้าซ้ำและไม่ต้องใช้ปลั๊กอินเช่น LiveReload นี่เป็นสิ่งที่ Hot Module Replacement สามารถช่วยฉันได้หรือไม่
ใช่
ฉันต้องทำงานประเภทใดและ HMR ให้บริการอะไรแล้ว
นี่เป็นตัวอย่างเล็กน้อย: https://webpack.js.org/guides/hot-module-replacement/
สามารถอัปเดตโมดูลได้ต่อเมื่อคุณ "ยอมรับ" เท่านั้น ดังนั้นคุณต้องmodule.hot.accept
โมดูลในผู้ปกครองหรือผู้ปกครองของผู้ปกครอง ... เช่นเราเตอร์เป็นสถานที่ที่ดีหรือมุมมองย่อย
หากคุณต้องการใช้กับ webpack-dev-server เพียงเพิ่มwebpack/hot/dev-server
เป็นจุดเริ่มต้น อื่น ๆ ที่คุณต้องมีรหัสการจัดการ HMR บางอย่างที่โทรและcheck
apply
ความเห็น: อะไรทำให้มันเท่ห์
- มันเป็น LiveReload แต่สำหรับโมดูลทุกชนิด
- คุณสามารถใช้มันในการผลิต
- การอัปเดตเกี่ยวข้องกับการแยกรหัสของคุณและดาวน์โหลดเฉพาะการอัปเดตสำหรับชิ้นส่วนที่ใช้ของแอป
- คุณสามารถใช้มันเป็นส่วนหนึ่งของแอปพลิเคชันของคุณและจะไม่มีผลกับโมดูลอื่น ๆ
- หาก HMR ถูกปิดใช้งานรหัส HMR ทั้งหมดจะถูกลบออกโดยคอมไพเลอร์ (ห่อไว้ใน
if(module.hot)
)
คำเตือน
- มันเป็นการทดลองและไม่ผ่านการทดสอบอย่างดี
- คาดว่าข้อบกพร่องบางอย่าง
- ใช้ในทางทฤษฎีในการผลิต แต่อาจเร็วเกินไปที่จะใช้สำหรับบางสิ่งที่ร้ายแรง
- ID โมดูลจะต้องมีการติดตามระหว่างการรวบรวมดังนั้นคุณต้องเก็บไว้ (
records
)
- เครื่องมือเพิ่มประสิทธิภาพไม่สามารถปรับ ID โมดูลให้เหมาะสมได้อีกหลังจากการคอมไพล์ครั้งแรก ผลกระทบเล็กน้อยกับขนาดของกลุ่ม
- รหัสรันไทม์ HMR เพิ่มขนาดของบันเดิล
- สำหรับการใช้งานจริงต้องทำการทดสอบเพิ่มเติมเพื่อทดสอบ HMR handler นี่อาจเป็นเรื่องยาก