Hot Module Replacement (HMR) là gì trong Webpack?
Trước tiên, lưu ý rằng Hot Module Replacement (HMR) vẫn là một tính năng thử nghiệm.
Hot Module Replacement (HMR) là gì?
Hot Module Replacement (HMR) là một cách trao đổi các mô-đun trong một ứng dụng đang chạy (và thêm / bớt các mô-đun). Về cơ bản, bạn có thể cập nhật các mô-đun đã thay đổi mà không cần tải lại toàn bộ trang.
Tài liệu
Tiền đề:
- Using Plugins: https://webpack.js.org/concepts/plugins/
- Code Splitting: https://webpack.js.org/guides/code-splitting/
- webpack-dev-server: https://webpack.js.org/configuration/dev-server/
It's not so much for HMR, but here are the links:
- Example: https://webpack.js.org/guides/hot-module-replacement/
- API: https://webpack.js.org/concepts/hot-module-replacement/
I'll add these answers to the documentation.
Hot Module Replacement hoạt động như thế nào?
Từ app view
App code yêu cầu HMR runtime kiểm tra các bản cập nhật. HMR runtime tải xuống các bản cập nhật (không đồng bộ) và cho app code biết rằng bản cập nhật có sẵn. App code yêu cầu HMR runtime áp dụng các bản cập nhật. HMR runtime áp dụng các bản cập nhật (đồng bộ hóa). App code có thể yêu cầu hoặc không cần sự tương tác của người dùng trong quá trình này (do bạn quyết định).
Từ compiler (webpack) view
Ngoài các nội dung thông thường, compiler cần phát tín hiệu "Update" để cho phép cập nhật từ phiên bản trước lên phiên bản này. "Update" bao gồm hai phần:
- bản kê khai cập nhật (json)
- một hoặc nhiều phần cập nhật (js)
Tệp kê khai chứa compilation hash mới và danh sách tất cả các phần cập nhật (2).
Các phần cập nhật chứa code cho tất cả các mô-đun được cập nhật trong phần cập nhật (hoặc flag nếu một mô-đun đã bị xóa).
Ngoài ra, compiler còn đảm bảo rằng các id của mô-đun và phần cập nhật được nhất quán giữa các bản dựng này. Nó sử dụng tệp json "redcord" để lưu trữ id giữa các bản dựng (hoặc nó lưu trữ chúng trong bộ nhớ).
Từ module view
HMR là một tính năng opt-in, vì vậy nó chỉ ảnh hưởng đến các mô-đun có chứa mã HMR. Tài liệu mô tả API có sẵn trong các mô-đun. Nói chung, module developer viết các trình xử lý (handlers) được gọi khi một phần phụ thuộc của mô-đun này được cập nhật. Họ cũng có thể viết một trình xử lý được gọi khi mô-đun này được cập nhật.
Trong hầu hết các trường hợp, không bắt buộc phải viết mã HMR trong mọi mô-đun. Nếu một mô-đun không có HMR handler, bản cập nhật sẽ nổi lên. Điều này có nghĩa là một trình xử lý duy nhất có thể xử lý các bản cập nhật cho một cây mô-đun hoàn chỉnh. Nếu một mô-đun đơn lẻ trong cây này được cập nhật, cây mô-đun hoàn chỉnh sẽ được tải lại (chỉ được tải lại, chứ không chuyển đi).
Từ HMR runtime view (technical)
Mã bổ sung được phát ra cho module system runtime giúp theo dõi mô-đun parents
vàchildren
.
Về phía quản lý, runtime hỗ trợ hai hàm: check
vàapply
.
Lệnh check thực hiện một yêu cầu HTTP lên tệp kê khai cập nhật. Khi yêu cầu này không thành công, không có bản cập nhật nào khả dụng. Ngược lại, danh sách các phần được cập nhật sẽ được so sánh với danh sách các phần hiện đang được load. Đối với mỗi phần được load, phần cập nhật tương ứng sẽ được tải xuống. Tất cả các bản cập nhật mô-đun được lưu trữ trong runtime dưới dạng các bản cập nhật. Runtime chuyển sang trạng thái ready
, có nghĩa là bản cập nhật đã được tải xuống và sẵn sàng được áp dụng.
Đối với mỗi yêu cầu phần mới ở trạng thái sẵn sàng, phần cập nhật cũng được tải xuống.
Lệnh apply
gắn cờ tất cả các mô-đun đã cập nhật nào không hợp lệ. Đối với mỗi mô-đun không hợp lệ, cần có một trình xử lý cập nhật (update handler) trong mô-đun hoặc trình xử lý cập nhật trong mọi parent. Nếu không, các bong bóng không hợp lệ sẽ nổi lên và đánh dấu tất cả các parent là không hợp lệ. Quá trình này tiếp tục cho đến khi không xảy ra hiện tượng "bong bóng" nữa. Nếu nổi lên đến một entry point nhất định, quy trình sẽ thất bạn.
Bây giờ tất cả các mô-đun không hợp lệ sẽ được xử lý (tdispose handler) và được dỡ bỏ. Sau đó, hash hiện tại được cập nhật và tất cả các "accept" handler được gọi. Runtime chuyển trở lại trạng thái idle
và mọi thứ vẫn tiếp tục như bình thường.
Mình làm gì được là gì với HMR?
Bạn có thể sử dụng nó trong quá trình phát triển thay cho LiveReload. Trên thực tế, máy chủ webpack-dev hỗ trợ hot mode mà sẽ cập nhật bằng HMR trước khi cố gắng tải lại toàn bộ trang. Bạn chỉ cần thêm entry point webpack/hot/dev-server và gọi dev-server bằng --hot.
Bạn cũng có thể sử dụng nó trong prodution làm cơ chế cập nhật. Tại đây, bạn cần viết mã quản lý của riêng mình để tích hợp HMR với ứng dụng.
Một số bộ tải đã tạo ra các mô-đun có thể cập nhật nóng. ví dụ. style-loader có thể trao đổi stylesheet. Bạn không cần phải làm bất cứ điều gì đặc biệt.
Giả sử ta muốn cập nhật các mô-đun CSS (một stylesheet) và mô-đun JS khi ta lưu chúng vào đĩa, mà không cần tải lại trang và không sử dụng các plugin như LiveReload. Đây có phải là vấn đề mà Hot Module Replacement có thể giúp ta giải quyết?
Đúng là như vậy đấy
Loại công việc tôi cần làm và HMR đã cung cấp những gì?
Đây chính là một ví dụ nhỏ: https://webpack.js.org/guides/hot-module-replacement/
Một mô-đun chỉ có thể được cập nhật nếu bạn "accept" nó. Vì vậy, bạn cần phải module.hot.accept mô-đun trong parent hoặc parent của parent ... ví dụ: Router là một nơi tốt, hoặc subview.
Nếu bạn chỉ muốn sử dụng nó với webpack-dev-server, chỉ cần thêm webpack/hot/dev-server làm entry point. Nếu không, bạn cần một số mã quản lý HMR để gọicheck
vàapply
.
Ý kiến: Điều gì khiến nó tuyệt vời như vậy?
- Giống LiveReload, nhưng áp dụng được choi mọi kiểu mô-đun.
- Dùng được trong production.
- Các bản cập nhật sẽ tuân theo Code Splitting của chúng ta và chỉ tải bản cập nhật cho các phần được sử dụng của ứng dụng.
- Bạn có thể sử dụng nó cho 1 phần của ứng dụng và không ảnh hưởng lên các mô-đun khác.
- Nếu HMR bị vô hiệu hóa, tất cả mã HRM bị compiler xóa đi (gói nó trong if(module.hot))
Lưu ý
- Công cụ đang trong quá trình thử nghiệm và vẫn chưa được kiểm thử toàn diện.
- Có bugs là chuyện bình thường.
- Theo lý thuyết thì dùng được trong production, nhưng vẫn còn quá sớm cho các tác vụ "nghiêm túc".
- ID của mô-đun cần được theo dõi giữa các lần compile mã nên bạn cần lưu trữ chúng (
records
). - Trình tối ưu không thể tối ưu ID mô-đun nữa sau lần compile đầu tiền. Sẽ ảnh hưởng một chút lên kích thước bundle.
- Mã HRM runtime sẽ làm tăng kích thước bundle.
- Khi dùng cho production, cần testing thêm đối với HRM handler. Cái này hơi khó một chút.
Nhận xét
Đăng nhận xét