Hot Module Replacement ใน Webpack คืออะไร?


245

ผมเคยอ่านไม่กี่ หน้าเกี่ยวกับโมดูลร้อนทดแทนใน Webpack
มีแม้กระทั่งแอพตัวอย่างที่ใช้ใช้มัน

ฉันอ่านทั้งหมดแล้วและยังไม่เข้าใจ

ฉันจะทำอย่างไรกับมัน?

  1. มันควรจะใช้เฉพาะในการพัฒนาและไม่ได้อยู่ในการผลิต?
  2. มันเหมือน LiveReload แต่คุณต้องจัดการมันด้วยตัวเอง?
  3. WebpackDevServer ผสานรวมกับ LiveReload อย่างใดหรือไม่?

สมมติว่าฉันต้องการอัปเดต CSS (หนึ่งสไตล์ชีท) และโมดูล JS เมื่อฉันบันทึกลงในดิสก์โดยไม่ต้องโหลดหน้าซ้ำและไม่ต้องใช้ปลั๊กอินเช่น LiveReload นี่เป็นสิ่งที่ Hot Module Replacement สามารถช่วยฉันได้หรือไม่ ฉันต้องทำงานประเภทใดและ HMR ให้บริการอะไรแล้ว


HMR กับ Webpack เกือบจะดีเช่นนี้: medium.com/@the1mills/ …
Alexander Mills

คำตอบ:


408

ก่อนอื่นฉันต้องการทราบว่า Hot Module Replacement (HMR) ยังคงเป็นคุณลักษณะทดลอง

HMR เป็นวิธีการแลกเปลี่ยนโมดูลในแอปพลิเคชันที่กำลังทำงาน (และการเพิ่ม / ลบโมดูล) โดยทั่วไปคุณสามารถอัปเดตโมดูลที่เปลี่ยนแปลงโดยไม่ต้องโหลดหน้าเต็ม

เอกสาร

Prerequirements:

มันไม่มากสำหรับ HMR แต่นี่คือลิงค์:

ฉันจะเพิ่มคำตอบเหล่านี้ลงในเอกสาร

มันทำงานยังไง?

จากมุมมองแอพ

รหัสแอปขอให้รันไทม์ HMR เพื่อตรวจสอบการอัพเดต HMR รันไทม์ดาวน์โหลดอัปเดต (async) และบอกรหัสแอพว่ามีการอัปเดต รหัสแอปขอให้รันไทม์ HMR เพื่อใช้การอัปเดต HMR รันไทม์ใช้การอัพเดต (ซิงค์) รหัสแอปอาจหรือไม่จำเป็นต้องมีการโต้ตอบกับผู้ใช้ในกระบวนการนี้ (คุณเป็นผู้ตัดสินใจ)

จากมุมมองคอมไพเลอร์ (webpack)

นอกเหนือจากเนื้อหาปกติคอมไพเลอร์ต้องปล่อย "อัปเดต" เพื่ออนุญาตการอัปเดตจากเวอร์ชันก่อนหน้าเป็นเวอร์ชันนี้ "อัพเดท" มีสองส่วน:

  1. ไฟล์อัพเดท (json)
  2. ชิ้นส่วนอัพเดทหนึ่งหรือหลายชิ้น (js)

ไฟล์ Manifest มีแฮชการคอมไพล์ใหม่และรายการรายการอัพเดตทั้งหมด (2)

ชิ้นส่วนอัปเดตมีรหัสสำหรับโมดูลที่อัปเดตทั้งหมดในกลุ่มนี้ (หรือตั้งค่าสถานะหากโมดูลถูกลบ)

คอมไพเลอร์เพิ่มเติมทำให้แน่ใจว่าโมดูลและรหัสก้อนมีความสอดคล้องกันระหว่างบิลด์เหล่านี้ มันใช้ไฟล์ "บันทึก" json เพื่อจัดเก็บระหว่าง build (หรือเก็บไว้ในหน่วยความจำ)

จากมุมมองโมดูล

HMR เป็นคุณสมบัติการเลือกใช้ดังนั้นจะมีผลกับโมดูลที่มีรหัส HMR เท่านั้น เอกสารอธิบายถึง API ที่มีอยู่ในโมดูล โดยทั่วไปผู้พัฒนาโมดูลจะเขียนตัวจัดการที่ถูกเรียกเมื่อมีการอัพเดทโมดูลนี้ พวกเขายังสามารถเขียนตัวจัดการที่เรียกว่าเมื่อโมดูลนี้มีการปรับปรุง

ในกรณีส่วนใหญ่ไม่จำเป็นต้องเขียนรหัส HMR ในทุกโมดูล หากโมดูลไม่มี HMR handler การอัพเดตจะเพิ่มขึ้น ซึ่งหมายความว่าตัวจัดการเดียวสามารถจัดการอัพเดตสำหรับแผนผังโมดูลที่สมบูรณ์ ถ้ามีการอัพเดตโมดูลเดียวในแผนผังนี้ทรีโมดูลที่สมบูรณ์จะถูกโหลดใหม่ (โหลดซ้ำเท่านั้นไม่ถูกถ่ายโอน)

จากมุมมองรันไทม์ HMR (ทางเทคนิค)

รหัสเพิ่มเติมถูกปล่อยออกมาสำหรับระบบ runtime โมดูลโมดูลในการติดตามและparentschildren

ในด้านการจัดการการรันไทม์สนับสนุนสองวิธี: และcheckapply

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 บางอย่างที่โทรและcheckapply

ความเห็น: อะไรทำให้มันเท่ห์

  • มันเป็น LiveReload แต่สำหรับโมดูลทุกชนิด
  • คุณสามารถใช้มันในการผลิต
  • การอัปเดตเกี่ยวข้องกับการแยกรหัสของคุณและดาวน์โหลดเฉพาะการอัปเดตสำหรับชิ้นส่วนที่ใช้ของแอป
  • คุณสามารถใช้มันเป็นส่วนหนึ่งของแอปพลิเคชันของคุณและจะไม่มีผลกับโมดูลอื่น ๆ
  • หาก HMR ถูกปิดใช้งานรหัส HMR ทั้งหมดจะถูกลบออกโดยคอมไพเลอร์ (ห่อไว้ในif(module.hot))

คำเตือน

  • มันเป็นการทดลองและไม่ผ่านการทดสอบอย่างดี
  • คาดว่าข้อบกพร่องบางอย่าง
  • ใช้ในทางทฤษฎีในการผลิต แต่อาจเร็วเกินไปที่จะใช้สำหรับบางสิ่งที่ร้ายแรง
  • ID โมดูลจะต้องมีการติดตามระหว่างการรวบรวมดังนั้นคุณต้องเก็บไว้ ( records)
  • เครื่องมือเพิ่มประสิทธิภาพไม่สามารถปรับ ID โมดูลให้เหมาะสมได้อีกหลังจากการคอมไพล์ครั้งแรก ผลกระทบเล็กน้อยกับขนาดของกลุ่ม
  • รหัสรันไทม์ HMR เพิ่มขนาดของบันเดิล
  • สำหรับการใช้งานจริงต้องทำการทดสอบเพิ่มเติมเพื่อทดสอบ HMR handler นี่อาจเป็นเรื่องยาก

145
นรกแห่งคำตอบเดียว
Dan Abramov

13
ขอขอบคุณอีกครั้งสำหรับคำอธิบายฉันทำวิดีโอที่แสดงพลัง HMR เพื่อแก้ไขแอป React แบบสดๆ
Dan Abramov

1
ค่อนข้างเย็น ... ฉันคิดเกี่ยวกับการทำปฏิกิริยาโหลดเดอร์ซึ่งเพิ่มการโหลด HMR และ async ให้กับส่วนประกอบต่างๆ
Tobias K.

4
ฉันคัดลอกคำตอบนี้ลงในเอกสาร: webpack.github.io/docs/hot-module-replacement-with-webpack.html
Tobias K.

2
คุณสามารถตรวจจับข้อผิดพลาดในโมดูลที่อัพเดตเมื่อคุณตัดคำrequireในตัวจัดการอัพเดต HMR ในบล็อก try-catch
Tobias K.

10

คำตอบที่ได้รับการยอมรับจะทำให้ทุกอย่างถูกต้องอย่างไรก็ตามคำอธิบายต่อไปนี้จะช่วยให้เข้าใจ HMR ได้อย่างรวดเร็ว

การแทนที่ Hot Module เป็นหนึ่งในเทคนิคใหม่ล่าสุดในการพัฒนาจาวาสคริปต์ที่ดึงดูดความสนใจจากนักพัฒนา ช่วยในการพัฒนาโดยลดจำนวนการรีเฟรชหน้าโดยแทนที่โมดูลด้วยการเปลี่ยนแปลงที่รันไทม์

ในขณะที่ค้นหาเกี่ยวกับ HMR ฉันพบบทความที่อธิบายแนวคิดบนอินเทอร์เน็ตคุณสามารถรับได้จากที่นี่และเพิ่มรูปภาพ GIF ที่อธิบายแนวคิดโดยไม่มีคำอธิบายมาก

ที่นี่เป็นที่ทำงาน - โปรดทราบว่าตัวจับเวลาไม่ได้รีเซ็ตเป็น 0 เหมือนเดิมหลังจากโหลดหน้าใหม่แล้วและ css ก็เปลี่ยนการรีเฟรชอัตโนมัติด้วยเช่นกัน GIF เปลี่ยนโมดูลร้อน

Webpack ช่วยให้บรรลุ HMR คุณสามารถหาเอกสารได้ที่นี่

ช่วยให้บรรลุดังนี้

  • เก็บสถานะแอปพลิเคชันซึ่งสูญหายระหว่างการโหลดซ้ำแบบเต็ม

  • ประหยัดเวลาอันมีค่าในการพัฒนาโดยอัพเดตสิ่งที่เปลี่ยนแปลงไปเท่านั้น

  • ปรับแต่งสไตล์ได้เร็วขึ้น - เกือบเทียบเท่ากับการเปลี่ยนสไตล์ในโปรแกรมดีบั๊กของเบราว์เซอร์

นี่คือคู่มือ webpack เพื่อให้บรรลุ HMR

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.