Trong vài năm trở lại đây, cộng đồng front-end đã sôi nổi thảo luận và sử dụng thuật ngữ “micro-frontend” (sau đây gọi tắt là MF). Các công ty khác nhau chia sẻ cách tiếp cận của họ để tổ chức một giải pháp kiến trúc như vậy, nhưng cho đến nay có rất ít mô tả về các vấn đề mà MF được thiết kế để giải quyết trên Web, các tiêu chí về khả năng ứng dụng của chúng và các hạn chế khi sử dụng.
Trong bài viết này, tôi đã cố gắng so sánh các cách tổ chức MF khác nhau, cũng như đưa ra các khuyến nghị về nơi sử dụng cách tiếp cận nào.
Bài viết có thể hữu ích cho cả nhà phân tích và nhóm phát triển khi thiết kế kiến trúc của dự án và đặt ra các quy trình, cũng như cho chủ sở hữu sản phẩm vì việc giới thiệu MF có thể mang lại sự phát triển dễ quản lý hơn.
Trước khi chuyển sang định nghĩa về MF, chúng ta hãy xem xét một số vấn đề có thể gặp phải trong các dự án:
Bạn có một dự án lớn . Quy mô của một dự án thường mang tính chủ quan và có thể được xác định theo kinh nghiệm bởi số lượng chức năng và số lượng nhà phát triển. Nếu bạn có đủ công việc để đánh đố 1-2 người đi trước và đồng thời họ sẽ không “thúc khuỷu tay” - đây là dự án nhỏ, 3-6 là vừa và hơn 6-8 đã là dự án lớn .
Bạn có một đội ngũ lớn . Một lần nữa, theo kinh nghiệm, đây là hơn 10 người đi trước, những người tham gia còn lại không được tính. Theo quy định, một nhóm có quy mô này đã có thể được chia thành các nhóm phụ đảm nhận chức năng cụ thể để hỗ trợ và có được các nhà phân tích, người hỗ trợ và QA của riêng họ.
Bạn có chức năng tuyệt vời. Một nhà phát triển duy nhất chỉ có thể duy trì một đoạn mã cho nhóm phụ của mình. Tinh chỉnh phần còn lại của mã có thể tốn kém do không biết lĩnh vực chủ đề hoặc sự phức tạp của việc triển khai logic của bên thứ ba.
mong muốn thay đổi ngăn xếp;
một yêu cầu của công ty để hỗ trợ một nhóm các dự án liên quan.
Làm thế nào bạn có thể tổ chức các mối quan hệ giữa rất nhiều người? Làm thế nào bạn có thể xây dựng các quy trình trên một dự án ở quy mô này? Làm thế nào bạn có thể phân định chính xác các lĩnh vực trách nhiệm? Bạn càng thu thập được nhiều vấn đề thì càng nên xem xét việc giới thiệu phương pháp tiếp cận vi mô. Vì đây là sự tiếp tục tự nhiên của xu hướng tiến hóa trong quá trình phát triển theo hướng phân rã mã và nhóm dự án.
Do đó, cách tiếp cận MF là sự phân chia mặt trận nguyên khối thành các cơ sở mã riêng biệt được lưu trữ trong các kho lưu trữ riêng biệt mà các nhóm con riêng biệt có quyền truy cập. Đồng thời, họ có thể/nên có gian hàng thử nghiệm, thử nghiệm và chu kỳ phát hành của riêng mình. Theo đó, microfront là một phần có thể tháo rời của giao diện. Không nhất thiết phải chia theo trang, chức năng có thể là từ đầu đến cuối (ví dụ: bộ công cụ ui của công ty).
Một cách riêng biệt, cần nhấn mạnh rằng MF là một quyết định mang tính tổ chức hơn về cách quản lý sự phức tạp của quá trình phát triển trong một dự án lớn. MF sẽ không giúp bạn tăng tốc giao diện người dùng, ngược lại, một số triển khai thậm chí sẽ làm chậm giao diện người dùng. Nhưng cách tiếp cận này sẽ tăng tốc độ phát triển do phân bổ các lĩnh vực trách nhiệm và thử nghiệm riêng biệt.
Ngược lại, điều đáng nói là Lazy loading so với MF. Chúng giải quyết các vấn đề khác nhau, nhưng đôi khi mọi người nghĩ rằng đó là tất cả về một thứ, bởi vì trong cả hai trường hợp, chúng tôi đều "tách" ứng dụng.
Lazy loading giải quyết vấn đề về hiệu suất: làm thế nào để không buộc người dùng tải toàn bộ gói giao diện người dùng, làm thế nào để không phải đợi lâu hơn mức cần thiết và làm thế nào để khởi chạy giao diện người dùng trên máy khách nhanh hơn và bắt đầu tương tác với nó sớm hơn.
MF không giải quyết được vấn đề về hiệu suất và đôi khi còn làm trầm trọng thêm vấn đề. Nhưng chúng giúp tổ chức phát triển theo cách thoải mái hơn cho một nhóm phụ cụ thể, giảm thiểu các vấn đề nêu trên.
Bây giờ hãy nói về phương pháp kết hợp các MF vào một ứng dụng duy nhất. Bất cứ điều gì bạn chọn, nó sẽ giống như một ứng dụng duy nhất cho người dùng. Bạn có thể hợp nhất cả ở giai đoạn lắp ráp và động - trong quá trình thực thi mã ở phía người dùng.
Do đó, tất cả các cách tổ chức MF có thể được quy cho thời gian xây dựng hoặc thời gian chạy. Mỗi thứ đều có ưu và nhược điểm riêng.
| thời gian xây dựng | thời gian chạy |
---|---|---|
kiểm tra loại | + | - |
lập phiên bản | + | vô nghĩa |
triển khai độc lập | - | + |
Kiểm tra loại đóng một vai trò quan trọng trong sự phát triển hiện đại. Khi nó được điều hành bởi các nhóm phụ độc lập riêng biệt, nó trở thành một điều cần thiết. Làm thế nào để đảm bảo tính nhất quán của các MF, để chúng sử dụng và truyền dữ liệu chính xác theo đúng định dạng, v.v.
Bằng cách hợp nhất các mặt trận vi mô khi xây dựng, bạn không bị tước cơ hội kiểm tra các loại. Trong trường hợp liên kết thời gian chạy, bạn sẽ phải viết các bài kiểm tra tích hợp để mặt trước không đột ngột “nổ tung” trong quá trình sản xuất.
Phiên bản và triển khai độc lập rất mâu thuẫn:
Lập phiên bản có nghĩa là bạn có thể lấy bất kỳ phiên bản MF nào của đội khác. Điều này đặc biệt đúng khi bạn cần thực hiện công việc bổ sung để nâng cấp các phần phụ thuộc của MF-a từ các phần phụ thuộc khác. Mỗi đội chọn một thời điểm tốt hơn để nâng cấp.
Triển khai độc lập mang lại nhiều quyền tự chủ và độc lập hơn cho các nhóm. Điều quan trọng là luôn sử dụng các phiên bản mới nhất của MF. Điều này đòi hỏi khả năng tương thích ngược.
Phiên bản cũng có thể được thực hiện với hợp nhất thời gian chạy, nhưng điều này không thực tế. Thật hợp lý khi chỉ liên hệ với thời gian chạy vì mục đích triển khai độc lập và thời gian chạy sau không thể tồn tại cùng với việc lập phiên bản.
Tiếp theo, chúng ta sẽ xem các ví dụ về triển khai cụ thể của từng cách tiếp cận để kết hợp các MF.
Cách lâu đời nhất để tổ chức MF. iframe là một thẻ đặc biệt để chuyển địa chỉ của tài nguyên sẽ được hiển thị trên trang chính. Kết quả là một trang web trong một trang web.
Trong số các ưu điểm , đáng chú ý là dễ triển khai, cách ly hoàn toàn logic và kiểu dáng, khả năng triển khai độc lập và không có ràng buộc với các khung.
Những lợi ích này đi kèm với chi phí hiệu suất, vì mỗi lần chèn iframe dẫn đến tải tài nguyên. Bạn không thể tránh điều này: các nỗ lực gỡ lỗi và gắn lại một nút DOM sẽ không lưu các tài nguyên đã tải trước đó, bạn sẽ phải tải xuống lại chúng. Bạn có thể giảm thiểu sự suy giảm hiệu suất bằng cách cấu hình bộ nhớ đệm.
Để thực hiện việc này, bạn cần định cấu hình tính năng vô hiệu hóa bộ đệm dựa trên thời gian cho các tài nguyên không thay đổi. May mắn thay, tất cả các cli hiện đại dành cho các tệp js và css được thu thập đều đính kèm một hàm băm nhỏ vào tên. Nhược điểm của phương pháp này bao gồm việc rô-bốt tìm kiếm không thể hiển thị iframe để lập chỉ mục tiếp theo.
ưu | Nhược điểm |
---|---|
Dễ dàng thực hiện | Hiệu suất |
Cách ly logic và phong cách | SEO |
triển khai độc lập | |
khung bất khả tri | |
Cộng đồng front-end đã chờ đợi việc tạo ra các thành phần bản địa trong một thời gian dài, nhưng cuối cùng, chúng chưa bao giờ đạt được sự phổ biến rộng rãi như nhiều người mong đợi. Ba framework front-end phổ biến nhất (React, Vue, Angular) vẫn tạo các thành phần theo cách riêng của chúng.
Mặc dù có khả năng tạo MF trên các thành phần web, nhưng tôi chưa thấy điều này trong thực tế. Và đây không phải là ngẫu nhiên, có một số trình chặn:
libs Lit hoặc Stencil không đủ phổ biến và không đủ phổ biến. Ngoài ra, không có đủ chuyên gia trên thị trường biết cách làm việc với họ hoặc sẵn sàng học hỏi.
Các phần tử góc cạnh hoặc vue-custom-element vẫn còn kỳ lạ. Trong một môi trường bản địa, không có nhiều điểm trong việc sử dụng chúng. Nếu bạn đã chia ứng dụng, thì hãy chia thành các gói npm thông thường để sau này bạn có thể kết nối các thành phần theo ý muốn. Sử dụng các thành phần web với các khung khác là không hợp lý vì cùng với các thành phần được tạo, bạn cần kết nối một phiên bản nhỏ của khung mà chúng được viết trên đó.
Việc di chuyển các phần chức năng phức tạp vào các thành phần web có thể tốn kém. Vì bạn sẽ cần định cấu hình giao tiếp của thành phần của mình với phần còn lại của ứng dụng, nên có thể không hợp lý khi lấy toàn bộ trang trong một thành phần tùy chỉnh riêng biệt.
Robot tìm kiếm không thể tạo thành phần web và điều này sẽ ảnh hưởng đến việc tối ưu hóa SEO.
ưu | Nhược điểm |
---|---|
Thích hợp cho chức năng xuyên suốt | Khó thực hiện |
Tương thích với mọi khung | SEO |
Cách ly logic và phong cách | |
Phát triển với các gói npm có nhiều lợi ích. Các nhà phát triển chỉ cần nhập các thành phần và tệp họ cần từ lib. Đồng thời, việc gõ được giữ nguyên trong dự án, có phiên bản. Quá trình xây dựng là tối ưu: tính năng rung cây hoạt động (loại bỏ mã không sử dụng trong quá trình xây dựng) và nhà phát triển có thể dễ dàng thiết lập tải từng phần.
Tuy nhiên, phương pháp này cũng có nhược điểm của nó. Trong trường hợp này, bạn sẽ buộc phải duy trì tính thống nhất của ngăn xếp, cũng như duy trì các phiên bản của MF và các phần phụ thuộc bắc cầu của chúng. Mặt khác, đây có thể là một điểm cộng: bằng cách xuất bản một phiên bản mới của gói, các nhóm khác có thể đảm nhận nhiệm vụ nâng cao phiên bản của các phần phụ thuộc vào thời điểm thuận tiện cho họ nếu họ cần giới thiệu chức năng bổ sung hoặc ngược lại. , loại bỏ một cái gì đó.
ưu | Nhược điểm |
---|---|
Hiệu suất | Không có triển khai độc lập |
SEO | ngăn xếp đơn |
kiểm tra loại | |
lập phiên bản | |
Để thay thế cho MF trên các gói npm, hãy xem xét các mô-đun con git. Thực tế, đây là những kho bên trong một kho, trong đó cũng có thể có các kho. Bạn có thể đặt các nhánh khác nhau trong các mô hình con. Ví dụ: các mô-đun tính năng có thể có một nhánh giả không có gì trong đó. Điều này là cần thiết để quá trình lắp ráp diễn ra nhanh hơn và các mô-đun khác không tạo ra tác dụng phụ. Các nhánh giả có thể rất thuận tiện cho việc phát triển và thử nghiệm cục bộ.
Xét về ưu điểm và nhược điểm của nó, cách tiếp cận này rất gần với các gói npm. Chúng tôi cũng chỉ nhập một thứ gì đó, nhưng từ một thư mục lân cận chứ không phải từ một gói và sử dụng nó.
Chúng ta hãy xem sự khác biệt giữa hai phương pháp:
Trên thực tế, các gói NPM là một sản phẩm vi mô hữu hạn, được cách ly vừa phải với các bản phát hành và phiên bản riêng. Mọi thứ đều tập trung vào việc tạo chức năng có thể tái sử dụng. Nhưng ứng dụng này có thể phức tạp/lộn xộn và bốc mùi, vì vậy việc đóng gói một nguyên khối lớn có thể khá tốn kém. Đây là nơi hợp lý để xem xét các mô hình con vì chúng cho phép bạn cắt kho lưu trữ một cách thô bạo khi chúng ta di chuyển thư mục sang một kho lưu trữ riêng biệt mà không cần chuẩn bị thêm.
Các gói NPM có thể được lồng vào nhau theo cách đệ quy. Các mô-đun con cũng vậy, nhưng ở cấp độ lắp ráp, chúng có thể bắt đầu sao chép chức năng nếu một trong các mô-đun con được đưa vào nhiều lần trong các thư mục khác nhau dưới dạng một mô-đun con riêng biệt. Trong trường hợp này, nên sử dụng cấu trúc mô-đun phẳng hơn.
Nếu bạn cần triển khai nhanh một tính năng trong tất cả các gói cùng một lúc, việc phát triển trên nhiều gói có thể cực kỳ bất tiện. Trong khi mọi thứ vẫn giữ nguyên trên các mô-đun con, bạn có thể thực hiện các chỉnh sửa ảnh hưởng đến các mô-đun con khác. Trong trường hợp này, thật dễ dàng để gỡ lỗi. Nhưng cuối cùng, bạn sẽ không tự hợp nhất các thay đổi - ở cấp độ yêu cầu hợp nhất, nhóm bên thứ ba có mô-đun mà bạn đã chạm vào có thể yêu cầu bạn đưa mã phù hợp với quy tắc của họ.
npm | mô hình con git |
---|---|
khả năng tái sử dụng | Cắt thô chức năng |
Phụ thuộc lồng nhau tùy ý | Cấu trúc bằng phẳng |
Phát triển đa nền tảng | Phát triển với bất kỳ số lượng mô-đun nào |
spa đơn về bản chất là một khung kết hợp các khung khác. Công nghệ cực kỳ mạnh mẽ, ẩn chứa một số lượng lớn các sắc thái, là một chủ đề cho một bài báo riêng biệt.
Sơ đồ này tương tự như iframe, nhưng việc tải MF hiện được thực hiện thông qua nhập + bản đồ nhập gốc hoặc thông qua Systemjs nếu cần polyfill.
Không giống như tất cả các phương pháp tổ chức MF, phương pháp này rất phù hợp để kết hợp các khung khác nhau trong chính nó. Nhưng cần thận trọng khi sử dụng công nghệ vì lợi ích của chính công nghệ. Nếu có thể đạt được với một ngăn xếp, bạn cần sử dụng nó. Quá trình phát triển có thể mãi mãi chịu gánh nặng với việc duy trì một dự án phức tạp về mặt kỹ thuật và sửa bất kỳ lỗi nào do tác dụng phụ của các ứng dụng khác nhau. Người dùng có thể cảm thấy khó chịu, bởi vì. số lượng mã để tải xuống máy khách sẽ tăng lên (lõi của các khung khác nhau cho các phần chức năng khác nhau + lõi của chính spa đơn và các plugin của nó).
ưu | Nhược điểm |
---|---|
triển khai độc lập | Tài liệu lớn, vẫn chưa bao gồm tất cả các trường hợp |
khung bất khả tri | Khó khăn với SEO |
CLI mạnh mẽ | |
Một plugin webpack 5 được phát triển đặc biệt để tạo MF. Công nghệ đầy hứa hẹn: một plugin xây dựng nhỏ để đóng gói chính xác hơn và nhập động khi chạy.
Sơ đồ gần như lặp lại từng lần một spa, nhưng hiện tại, nhập động được sử dụng để tải MF
ưu | Nhược điểm |
---|---|
triển khai độc lập | cấp thấp |
Dễ dàng thực hiện | |
Tương thích với SSR | |
Chúng ta hãy xem những gì có thể được áp dụng và cho những gì:
iframe - một phần chèn duy nhất cho sự kết hợp không phù hợp
các thành phần web - khi bạn cần một chức năng nhỏ từ đầu đến cuối mà không bị ràng buộc với khung, chẳng hạn như bộ ui công ty
gói npm - nếu có khả năng sử dụng lại giữa các dự án và/hoặc bạn cần kiểm tra loại trong thời gian xây dựng
git submodules - khi bạn cần cắt nhỏ một dự án và phân bổ các khu vực chịu trách nhiệm
spa đơn - khi có nhu cầu kết hợp vô thời hạn nhiều khung, tốt nhất là không có SSR
liên kết mô-đun - tất cả các kịch bản khác cho việc sử dụng MF, tùy thuộc vào sự thống nhất của ngăn xếp.
Mỗi cách tiếp cận đều tốt theo cách riêng của nó và mọi thứ nên có vị trí của nó. Trước khi chuyển sang MF, chúng tôi khuyên bạn nên suy nghĩ xem bạn có thực sự cần nó hay không. Cho dù phương pháp nào được chọn, nó chắc chắn sẽ làm phức tạp một số thứ ở cấp độ phát triển, CI / CD hoặc hiệu suất. Nếu có cơ hội ở lại trên một ngăn xếp và ứng dụng nguyên khối, vui lòng chấp nhận cơ hội này.
Và, tất nhiên, đừng quên người dùng . Cuối cùng, họ tải xuống tất cả các khung được kết nối và chịu đựng các lỗi có thể xảy ra do tích hợp không chính xác các MF trong các phần chức năng khác nhau. Ngược lại, các doanh nghiệp sẽ phải trả tiền cho việc thực hiện và hỗ trợ tất cả những điều này.