Micro Frontend là gì và có những cách nào để áp dụng Micro Frontend?
- Published on
Table Of Content
- MicroFrontend là gì?
- Ưu điểm của MicroFrontend
- Nhược điểm của MicroFrontend
- Khi nào nên áp dụng MicroFrontend
- Có những cách nào để áp dụng MicroFrontend
- Tài liệu tham khảo
MicroFrontend là gì?
Trong bối cảnh hiện đại của phát triển web, mô hình Microfrontend đang nổi lên như một cách tiếp cận mang tính cách mạng để xây dựng và quản lý các ứng dụng phức tạp. Vậy Microfrontend là gì và tại sao nó lại quan trọng đối với các nhà phát triển và tổ chức lớn?
Microfrontend là một kiểu kiến trúc ứng dụng, nơi giao diện người dùng (frontend) được chia thành các "sub-frontends" hoặc các thành phần nhỏ, độc lập. Mỗi thành phần này được phát triển, triển khai và quản lý bởi một đội riêng biệt, với trách nhiệm rõ ràng và khả năng tự chủ cao. Mô hình này cho phép các nhóm tập trung vào các mục tiêu và yêu cầu kinh doanh cụ thể, từ đó tạo ra các sản phẩm linh hoạt và dễ mở rộng hơn.
Hãy cùng xem các hình ảnh dưới đây để thấy sự so sánh trực quan giữa cách tiếp cận truyền thống và mô hình Microfrontend:
Monolithic Frontends
- The Monolith: Đây là kiểu kiến trúc "tất cả trong một", nơi mà Frontend, Backend, và Database được tích hợp trong một khối. Kiểu này thích hợp cho các ứng dụng đơn giản hoặc khi bạn cần triển khai nhanh chóng và dễ dàng. Một số các framework đó là: Ruby on Rails, Django, Laravel, Spring Boot, ASP.NET MVC, ...
- Nhược điểm: tất cả mọi thứ đều nằm trên 1 project, làm cho project bị phình to, nặng nề, kém sự linh hoạt. Một số dev có chuyên môn riêng biệt về FE hoặc BE sẽ gặp khó khăn ban đầu khi mới tiếp cận.
Frontend & Backend: Còn được gọi là kiến trúc tầng, nơi Frontend và Backend được phân tách rõ ràng nhưng vẫn thuộc một hệ thống duy nhất. Tuy đã được phân tách rõ ràng logic FE và BE, nhưng với những project có nhiều module phức tạp thì mô hình này vẫn chưa tối ưu trong việc development, scaling, deployment.
Microservices: Là kiểu kiến trúc nơi ứng dụng được chia thành nhiều service nhỏ, mỗi service đảm nhận một chức năng cụ thể và có thể triển khai độc lập. Tuy nhiên mô hình này chỉ áp dụng tại backend.
Organisation in Verticals
Source: https://micro-frontends.org/
Micro frontends cho phép tạo ra các đội ngũ dọc, tức là một team dev full-stack có thể đồng thời quản lý một tính năng bao gồm cả backend lẫn frontend bằng cách chia ứng dụng thành các chức năng nhỏ và độc lập, mỗi chức năng sẽ được triển khai bởi 1 team riêng biệt.
Cách tiếp cận này trở nên phổ biến do những vấn đề với mô hình Monolithic, với những website có frontend phát triển nhanh cho các ứng dụng doanh nghiệp lớn việc bảo trì sẽ trở nên khó khăn hơn.
Tương tự như kiến trúc microservices ở backend, micro frontends đảm bảo khả năng mở rộng, linh hoạt và thích ứng. Chúng có thể được coi là các vertical components độc lập (cũng được gọi là verticals
) của một ứng dụng web, điều này làm cho việc phát triển ứng dụng hiệu quả hơn. Mỗi vertical
chịu trách nhiệm về một module như “Profile,” “Catalog,” hoặc “Order”. Presentation layer, persistence layer, service layer (microservice), và cơ sở dữ liệu của nó đều độc lập. Từ quan điểm phát triển, một đội thực hiện mỗi vertical
.
Ưu điểm của MicroFrontend
Trong phần giới thiệu trên cũng đã nêu lên những ưu điểm của Micro Frontend. Mình sẽ note lại những ý chính về ưu điểm của Micro Frontend như sau:
1. Nâng cấp Linh hoạt
MicroFrontend cho phép các doanh nghiệp áp dụng những cải tiến một cách linh hoạt, từng bước một, mà không cần phải xử lý cả khối lượng công việc lớn cùng một lúc. Qua đó, rủi ro được quản lý hiệu quả và ứng dụng luôn được cập nhật với những công nghệ tiên tiến nhất.
2. Quản lý Mã Nguồn Đơn Giản và Hiệu quả
Mã nguồn nhỏ gọn và tách biệt giúp việc bảo trì trở nên dễ dàng hơn. Nhà phát triển có thể tập trung vào một phần nhỏ của dự án, giảm thiểu sự phức tạp và tăng năng suất.
3. Triển Khai Độc Lập
Các tính năng hoặc thành phần mới có thể nhanh chóng được đưa lên môi trường production mà không cần phải chờ đợi hoặc phụ thuộc vào những phần khác của ứng dụng. Điều này tạo điều kiện cho việc cập nhật và triển khai diễn ra nhanh chóng, đáp ứng kịp thời nhu cầu thay đổi của thị trường.
Ví dụ: MicroFrontend A có thể đang cập nhật một tính năng mới và cần được triển khai ngay lập tức để đáp ứng yêu cầu kinh doanh. Trong khi đó, MicroFrontend B và C có thể không cần thay đổi và vẫn tiếp tục hoạt động bình thường. Nhóm A có thể triển khai cập nhật của họ mà không làm gián đoạn hoặc yêu cầu sự phối hợp với nhóm B và C.
4. Sự Tự Chủ của các Team
MicroFrontend hỗ trợ cho việc hình thành các nhóm phát triển tự chủ, nơi mỗi nhóm chịu trách nhiệm về một phần của sản phẩm từ ý tưởng đến khi sản phẩm đi vào hoạt động. Điều này thúc đẩy sự đổi mới và sự sáng tạo, đồng thời cải thiện khả năng hợp tác và giao tiếp giữa các thành viên trong nhóm.
Nhược điểm của MicroFrontend
Cô lập: Cuối cùng, code từ mỗi đội phát triển cần phải được thực thi trên cùng một trình duyệt. Để tránh xung đột code hoặc style, chúng ta cần phải cách ly các module một cách cẩn thận.
Lặp code: Các component nên chia sẻ tài nguyên và thư viện khi có thể để giảm thiểu sự trùng lặp và duy trì một giao diện người dùng (frontend) gọn nhẹ. Tuy nhiên, điều này có thể dẫn đến sự phụ thuộc không mong muốn giữa các thành phần.
Styling: Việc giữ cho giao diện có vẻ ngoài thống nhất trở nên khó khăn hơn khi giao diện người dùng được tạo thành từ các component do các đội khác nhau xây dựng. Có thể xuất hiện những bất đồng nhỏ về phong cách.
Khi nào nên áp dụng MicroFrontend
Micro Frontend có rất nhiều ưu điểm tuy nhiên không phải dự án nào cũng phù hợp để áp dụng. Chúng ta nên xem xét sử dụng kiến trúc Micro Frontend trong các trường hợp sau:
Dự án Lớn và Phức Tạp: Khi ứng dụng của bạn lớn và bao gồm nhiều tính năng, việc chia nhỏ thành các micro frontends giúp quản lý dễ dàng hơn.
Nhiều Đội Ngũ Phát Triển: Khi có nhiều đội ngũ làm việc đồng thời và cần sự độc lập trong quy trình phát triển, MicroFrontend cho phép từng đội tập trung vào một phần cụ thể của sản phẩm.
Nhu Cầu Triển Khai Độc Lập: Khi cần cập nhật hoặc triển khai các phần của ứng dụng một cách độc lập mà không ảnh hưởng tới các phần khác.
Sử Dụng Nhiều Framework/Kỹ Thuật: Nếu muốn sử dụng nhiều công nghệ hoặc framework khác nhau trong cùng một ứng dụng, MicroFrontend cung cấp khả năng tích hợp linh hoạt.
Thử Nghiệm Và Đổi Mới: Khi cần thử nghiệm các giải pháp mới một cách nhanh chóng và không muốn rủi ro ảnh hưởng đến toàn bộ ứng dụng.
Quy Mô Đội Ngũ Và Địa Lý Phân Tán: Khi các đội phát triển đặt ở nhiều địa điểm khác nhau và cần phối hợp công việc mà không gây chậm trễ do phụ thuộc.
Có những cách nào để áp dụng MicroFrontend
1. Phân chia Theo Route/Path
Mỗi microfrontend đảm nhận một phần nhất định của ứng dụng dựa trên đường dẫn URL. Ví dụ, một microfrontend quản lý products
, một khác quản lý trang account
. Đây là phương pháp đơn giản nhất để triển khai và quản lý.
Sử dụng Nginx
Nginx là một web server đồng thời là reverse proxy mạnh mẽ, thường được sử dụng để điều hướng và cân bằng tải giữa các microfrontend. Khi sử dụng Nginx như một reverse proxy, bạn có thể dễ dàng điều hướng yêu cầu từ client tới microfrontend phù hợp dựa trên URL. Điều này không chỉ giúp phân tách các microfrontend trên mạng mà còn cải thiện hiệu suất bằng cách cache nội dung tĩnh và giảm thời gian đáp ứng.
Ví dụ cấu hình Nginx:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000; # Main application
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /products {
proxy_pass http://localhost:3001; # Microfrontend for products
}
location /account {
proxy_pass http://localhost:3002; # Microfrontend for account management
}
}
Sử dụng AWS Application Load Balancer
Cấu hình một Application Load Balancer (ALB) để điều hướng yêu cầu đến các nhóm máy chủ phù hợp dựa trên đường dẫn URL.
- Tạo các Target Groups cho mỗi microfrontend.
- Định nghĩa các Listener Rules trong ALB để chuyển hướng yêu cầu đến Target Groups dựa trên đường dẫn URL.
2. Server-Side Integration
Sử dụng Node.js và Express
Kết hợp các microfrontend trên server sử dụng Express, làm cho các fragment của HTML được tạo động và ghép chúng lại thành một trang hoàn chỉnh.
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send(`
<html>
<body>
${require('./header')}
${require('./main')}
${require('./footer')}
</body>
</html>
`);
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Sử dụng Nginx SSI (Server Side Includes)
Nginx cung cấp một tính năng gọi là Server Side Includes (SSI), cho phép nội dung của một trang web được xây dựng bằng cách bao gồm nội dung từ các tệp hoặc URLs khác. SSI rất hữu ích cho việc triển khai microfrontend trên phía server bởi vì nó cho phép các phần của trang web được phục vụ độc lập từ các dịch vụ khác nhau và được kết hợp lại trực tiếp trên server trước khi gửi đến client.
1. Kích hoạt SSI trong Nginx
server {
listen 80;
server_name example.com;
location / {
ssi on;
root /usr/share/nginx/html;
index index.html;
}
}
Bước 2: Định nghĩa các Include trong HTML
<!-- index.html -->
<html>
<head>
<title>My Microfrontend Application</title>
</head>
<body>
<!-- Include the header from a different microfrontend -->
<!--#include virtual="/header.html" -->
<h1>Welcome to the Main App!</h1>
<!-- Include the footer from a different microfrontend -->
<!--#include virtual="/footer.html" -->
</body>
</html>
Ở đây, các file như header.html
và footer.html
có thể được serve từ các server khác nhau, hoặc từ các path khác nhau trên cùng một server, cho phép bạn tách biệt rõ ràng giữa các phần của ứng dụng.
3. Build-Time Integration
Sử dụng Webpack Module Federation
Webpack 5 giới thiệu tính năng Module Federation, cho phép một JavaScript application tải động các phần code từ một application khác. Điều này tạo điều kiện thuận lợi cho việc phát triển microfrontend, vì bạn có thể giữ các microfrontend như các dự án riêng biệt, được biên dịch riêng lẻ và chỉ chia sẻ các phần cần thiết.
Cấu hình Module Federation trong Webpack:
// Webpack config for Product App
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'productApp',
filename: 'remoteEntry.js',
exposes: {
'./ProductPage': './src/ProductPage',
},
shared: ['react', 'react-dom']
}),
],
};
Trong ví dụ trên, productApp
là một ứng dụng microfrontend có khả năng xuất mô-đun ProductPage
để các ứng dụng khác có thể sử dụng.
4. Client-Side Integration via Web Components
Sử dụng Web Components để đóng gói các microfrontend. Mỗi microfrontend là một Web Component, có thể được nhúng vào bất cứ đâu trong ứng dụng mà không lo ngại về các vấn đề phụ thuộc hay xung đột.
// Define a new component
class HeaderComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = `<header>Welcome to Our Site!</header>`;
}
}
customElements.define('header-component', HeaderComponent);
<!-- Use in HTML -->
<header-component></header-component>
Trong một kiến trúc thực tế, chúng ta có thể kết hợp cả hai cách tiếp cận: sử dụng Nginx để phân phối các microfrontend dựa trên URL và sử dụng Webpack Module Federation để chia sẻ và tái sử dụng code giữa các microfrontend. Điều này cho phép bạn tận dụng lợi thế của cả hai phương pháp, tối ưu hóa cả sự cô lập (qua Nginx) và tính năng tái sử dụng code (qua Webpack).
Source code demo: https://github.com/neuland/micro-frontends/tree/master
Tài liệu tham khảo
https://martinfowler.com/articles/micro-frontends.html
Hẹn gặp lại trong những bài viết tiếp theo. Tạm biệt 🤗