Hot Module Replacement ใน Redux

เผยแพร่แล้ว: 2022-03-11

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

หากคุณไม่สามารถรอที่จะใช้ HMR ให้ข้ามไปที่ส่วนนี้เพื่อตั้งค่า HMR สำหรับโครงการของคุณภายในห้านาที!

การสาธิตการเปลี่ยนโมดูลร้อน

เรียกใช้ตัวอย่าง

เอามือสกปรกก่อน! ก่อนที่คุณจะรันคำสั่งเพื่อเริ่มแอปพลิเคชันตัวอย่างนี้ โปรดตรวจสอบให้แน่ใจว่า Git, Node.js และ Yarn ได้รับการติดตั้งอย่างถูกต้องบนเครื่องของคุณ

 $ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start

จากนั้นไปที่ http://localhost:3000/ เพื่อดูว่าใช้งานได้หรือไม่

เมื่อเขียนโค้ดของคุณ hot module replacement สามารถอัปเดตหน้าโดยไม่ต้องรีเฟรชแบบเต็ม ที่สำคัญกว่านั้น สถานะ Redux จะถูกเก็บไว้ในขณะที่ทรัพยากรอื่นๆ ได้รับการอัปเดตแล้ว

การเปลี่ยนโมดูลร้อน

การเปลี่ยนโมดูลแบบด่วนเป็นหนึ่งในคุณสมบัติที่มีประโยชน์ที่สุดที่ Webpack นำเสนอ อนุญาตให้อัปเดตโมดูลทุกประเภท รวมถึงไฟล์ JSON, CSS และ JS ณ รันไทม์โดยไม่ต้องรีเฟรชแบบเต็ม

นี่คือวิธีการทำงานภายใน:

  1. แอปพลิเคชันขอให้รันไทม์ HMR ตรวจหาการอัปเดต
  2. รันไทม์ดาวน์โหลดการอัปเดตและแจ้งแอปพลิเคชันแบบอะซิงโครนัส
  3. แอปพลิเคชันจะถามรันไทม์เพื่อใช้การอัปเดต
  4. รันไทม์ใช้การอัปเดตพร้อมกัน

ไดอะแกรมการเปลี่ยนโมดูลร้อน

HMR เพิ่มประสิทธิภาพการทำงานเมื่อพัฒนาแอปพลิเคชัน Redux Redux เป็นคอนเทนเนอร์สถานะที่คาดเดาได้สำหรับแอป JavaScript เป็นเฟรมเวิร์กล้ำสมัยที่ได้รับความนิยมอย่างมากจาก React Redux ตามคำจำกัดความของหลักการแรกของ Redux เป็นที่จัดเก็บข้อมูลที่ใช้ร่วมกันแบบเอกพจน์ ซึ่งอธิบายโดยเอกสารประกอบว่าเป็น "แหล่งความจริงเดียว" ที่เก็บข้อมูล (อ็อบเจ็กต์ JavaScript ธรรมดาที่อัพเดตโดย reducers ) จะได้รับการอัปเดตเมื่อผู้ใช้ดำเนินการกับแอปพลิเคชัน การดำเนินการของผู้ใช้ทุกครั้ง เช่น การคลิกปุ่ม การโหลดข้อมูลแบ็คเอนด์ ฯลฯ มีแนวโน้มที่จะอัปเดตร้านค้าหลายครั้ง การแก้ไขจุดบกพร่องไม่ใช่เรื่องง่ายเมื่อจุดบกพร่องเกิดขึ้นเฉพาะกับสแน็ปช็อตของรัฐเท่านั้น

HMR ช่วยให้เราอัปเดตหน้าโดยไม่ต้องเริ่มต้นร้านค้าส่วนกลางอีกครั้ง ในระหว่างการพัฒนา Redux เราอาจต้องการตรวจสอบร้านค้าหลังจากดำเนินการหลายครั้ง สถานการณ์ทั่วไปคือ จุดบกพร่องเกิดขึ้นหลังจากที่เราได้เพิ่มรายการเฉพาะ (อาจซับซ้อน) ลงในร้านค้าแล้วเท่านั้น หากไม่มี HMR เราต้องทำตามขั้นตอนต่อไปนี้:

  1. แก้ไขรหัสที่อาจก่อให้เกิดข้อผิดพลาด
  2. รีเฟรชหน้า เพิ่มรายการเฉพาะในร้านค้า
  3. หากข้อบกพร่องยังคงมีอยู่ ให้ทำซ้ำขั้นตอนที่ 1

การทำซ้ำข้างต้นจะถูกทำซ้ำอีกครั้งและอีกครั้งหากข้อผิดพลาดนั้นหายาก ในโลกแห่งความเป็นจริง บั๊กอาจปรากฏขึ้นหลังจากดำเนินการมากขึ้นเท่านั้น HMR ช่วยให้เราคอมไพล์และใช้โค้ดที่แก้ไขแล้วโดยที่ค่าปัจจุบันของร้านค้าไม่เปลี่ยนแปลง เราไม่จำเป็นต้องทำซ้ำขั้นตอนที่ 2 ซึ่งจะช่วยเพิ่มประสิทธิภาพในการพัฒนา

การแก้ไขข้อผิดพลาดไม่ได้หมายความว่าคุณต้องรีสตาร์ทแอปพลิเคชันด้วย HMR

หมายเหตุ: ในบางกรณี การแก้ไขโค้ดอาจส่งผลต่อมูลค่าร้านค้าปัจจุบัน ในกรณีนั้น HMR จะเตือนให้คุณโหลดซ้ำทั้งหน้า

คุณลักษณะในตัวอย่างนี้

เราต้องการทำให้คุณลักษณะนี้น้อยที่สุด เพียงเพื่อแสดงความสามารถของ HMR ดังนั้นในแอปพลิเคชันนี้ เราจึงไม่รวมคุณสมบัติทั่วไปในแอปพลิเคชัน React รวมถึง redux-logger, react-router-redux, redux-thunk, redux-devtools เป็นต้น ในขณะเดียวกันเราเก็บตัวลดขนาดเพียงตัวเดียว สองการกระทำ และ 1 หน้าหนังสือ.

แอปพลิเคชันของเราเก็บเฉพาะมูลค่าที่เคาน์เตอร์ในร้านค้า เรามีเพียงหน้าเดียวที่เรียกว่า home ซึ่งแสดงค่าตัวนับและปุ่มสองปุ่มเพื่อเพิ่ม/ลดค่าตัวนับ

เพื่อยืนยันว่า HMR ใช้งานได้ เพียงเพิ่ม/ลดตัวนับหลาย ๆ ครั้ง แล้วแก้ไขโค้ดบางส่วน ตัวอย่างเช่น แก้ไขชื่อ Counter เป็น Counter ในร้านค้า จากนั้นเราจะพบว่า:

  • หน้าไม่รีเฟรช
  • ค่าตัวนับที่แสดงจะไม่เปลี่ยนแปลง
  • ชื่อเรื่องถูกเปลี่ยนเป็น Counter ในร้านค้า

‍ ตั้งค่า HMR ในห้านาที

ในการตั้งค่า HMR ให้ทำตามขั้นตอนเหล่านี้

ห้องสมุดจำเป็น

ต้องติดตั้งไลบรารีเหล่านี้เพื่อรองรับ HMR:

  • react-hot-loader@^4.2.0: รวบรวมและอัปเดตแอปพลิเคชัน React แบบเรียลไทม์
  • webpack-dev-server@^3.1.4: ให้บริการแอป Webpack อัปเดตเบราว์เซอร์เมื่อมีการเปลี่ยนแปลง

ES6

หากคุณกำลังใช้ ECMAScript6 (ทุกวันนี้ไม่ใช่ใคร) คุณต้องมีเครื่องมือเพิ่มเติมเพื่อคอมไพล์ ES6 แบบเรียลไทม์ อันดับแรก นี่คือไฟล์กำหนดค่า ES6 ขั้นต่ำ .babelrc:

 { "env": { "development": { "presets": [ "react-hmre" ] } } }

เพื่อรองรับการคอมไพล์แบบเรียลไทม์ ไลบรารีนี้จำเป็นต้องมี:

  • babel-preset-react-hmre@^1.1.1

Webpack.config.js

เราจำเป็นต้องกำหนดค่า HMR ในไฟล์การกำหนดค่า Webpack webpack.config.js

ขั้นแรก เปิดใช้งานปลั๊กอิน HMR ในส่วนปลั๊กอิน:

 "plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]

ปลั๊กอิน HMR จะสร้างไฟล์ Manifest ไฟล์ JSON ที่แสดงรายการโมดูลที่อัปเดต และไฟล์อัปเดต ซึ่งเป็นไฟล์ JSON ที่มีข้อมูลที่จะใช้ สิ่งที่ควรสังเกตคือ HMR เป็นตัวเลือกที่ Webpack มีให้ ตัวโหลด เช่น style-loader ซึ่งใช้อินเทอร์เฟซ HMR รับการอัปเดตผ่าน HMR จากนั้นแทนที่โค้ดเก่าด้วยโค้ดใหม่

หากเราใช้ webpack-dev-server เราต้องเปิด hot flag ในส่วน devServer:

 "devServer": [ ... hot: true, ]

รีโหลด Redux Reducers อย่างร้อนแรง

เริ่มต้นจาก Redux เวอร์ชัน 2.0.0 ตัวลดขนาดจะไม่โหลดซ้ำโดยปริยายเนื่องจากการรีโหลดโดยนัยทำให้เกิดปัญหาบางอย่าง หากสถานะ Redux ของคุณถูกรีเซ็ตเป็นค่าเริ่มต้นเมื่ออัปเดต hot ให้ลองเปิดใช้งาน hot update สำหรับตัวลด:

 import { createStore } from 'redux'; import rootReducer from '../reducers/index'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers/index'); store.replaceReducer(nextRootReducer); }); } return store; }

ตั้งค่าขั้นสูง

สำหรับการตั้งค่าขั้นสูงเพิ่มเติมของ HMR โปรดดูที่ HMR API

วิ่ง

สุดท้าย โปรดเรียกใช้แอปพลิเคชันด้วย:

 $ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server

การแก้ไขปัญหา

HMR ไม่ได้ใช้การเปลี่ยนแปลง

HMR อาจล้มเหลวโดยไม่มีการเตือนใดๆ เมื่อคุณอัปเดตโค้ดและบันทึก หน้าเว็บจะไม่อัปเดตเลย อาจเป็นเพราะระบบของคุณไม่อนุญาตให้คุณดูการเปลี่ยนแปลงไฟล์จำนวนมาก

บน Ubuntu คุณสามารถเรียกใช้ sysctl -a | grep inotify sysctl -a | grep inotify เพื่อดูค่า user.max_inotify_watches ปัจจุบัน ลองเพิ่มจำนวนนี้ด้วยการรัน: sudo sysctl fs.inotify.max_user_watches=524288 อีกทางหนึ่ง ต่อท้ายบรรทัดใหม่ fs.inotify.max_user_watches=524288 เพื่อไฟล์ sudo vim /etc/sysctl.conf แล้วรัน sudo sysctl -p /etc/sysctl.conf เพื่อใช้การเปลี่ยนแปลง