Cơn ác mộng rò rỉ bộ nhớ lúc 2 giờ sáng
Chính xác là lúc 2:14 sáng khi các cảnh báo giám sát bắt đầu kêu inh ỏi. Một ứng dụng tiện ích nhỏ mà tôi đã xây dựng cho đội vận hành—một bảng điều khiển đơn giản để theo dõi sức khỏe máy chủ—đang ngốn tới 2.5GB RAM trên một máy chỉ có tổng cộng 8GB. Thủ phạm là gì?
Một bộ vỏ Electron chạy một phiên bản Chromium đầy đủ chỉ để hiển thị ba cái nút và một nhật ký văn bản. Đó là khoảnh khắc tôi nhận ra chúng tôi phải chuyển hướng. Chúng tôi cần sự linh hoạt của công nghệ web cho giao diện người dùng (UI) nhưng cần hiệu quả thuần túy của một ngôn ngữ hệ thống cho backend.
Đến lúc bình minh, tôi đã chuyển đổi tiện ích đó sang Tauri. Mức chiếm dụng bộ nhớ giảm mạnh từ 2.5GB xuống còn con số kinh ngạc 45MB. Nếu bạn đã từng cảm thấy xót xa khi phải phát hành một tệp thực thi 180MB cho một công cụ đơn giản, bạn sẽ hiểu tại sao điều này lại quan trọng. Tauri là cứu cánh cho sự tỉnh táo của những nhà phát triển ưu tiên hiệu năng hơn là sự cồng kềnh.
Kiến trúc: Tại sao Tauri chiến thắng
Hầu hết các framework desktop đều ép ứng dụng của bạn phải gánh thêm một công cụ trình duyệt nặng nề. Tauri chọn một con đường thông minh hơn bằng cách tận dụng WebView gốc của hệ điều hành—WebView2 trên Windows, WebKit trên macOS và GTK trên Linux. Giao diện của bạn vẫn là HTML và CSS, nhưng phần cốt lõi được vận hành bởi Rust.
Sự tách biệt này mang lại hai lợi thế lớn. Thứ nhất, các tệp nhị phân của bạn cực kỳ nhỏ. Bạn không cần đóng gói kèm trình duyệt vì người dùng đã có sẵn một cái ở cấp độ hệ điều hành. Thứ hai, bạn được hưởng lợi từ các đảm bảo về an toàn bộ nhớ và xử lý đồng thời của Rust. Từ những gì tôi thấy trong môi trường thực tế, đây là cách hiệu quả nhất để nâng cấp từ một ‘nhà phát triển web’ thành một ‘kỹ sư phần mềm‘ có khả năng xây dựng các công cụ desktop chuyên nghiệp.
Thiết lập chiến trường
Cài đặt môi trường Rust có thể giống như một trận đấu vật với trình biên dịch, đặc biệt là trên Windows. Bạn không thể chỉ tải xuống một trình cài đặt duy nhất và mong nó hoạt động ngay. Bạn cần một bộ công cụ C++ cụ thể để xử lý các tác vụ nặng nề.
1. Các điều kiện tiên quyết
Trên Windows, bạn phải cài đặt gói ‘Desktop development with C++’ thông qua Visual Studio Installer. Bỏ qua bước này sẽ khiến trình biên dịch Rust (rustc) bị lỗi ngay khi nó cố gắng liên kết tệp nhị phân của bạn. Người dùng Mac thì dễ dàng hơn; xcode-select --install sẽ xử lý các phụ thuộc. Đối với Ubuntu hoặc Debian, bạn sẽ cần các thư viện sau để giao tiếp với web view của hệ thống:
bash
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev
2. Cài đặt Rust
Hãy sử dụng rustup. Đây là tiêu chuẩn vàng để quản lý các phiên bản mà không làm bẩn đường dẫn hệ thống (system path) của bạn.
bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Khởi tạo dự án
Tôi thường sử dụng tiện ích create-tauri-app để tránh các lỗi cấu hình thường gặp ở các thiết lập thủ công. Mở terminal và chạy:
bash
npx create-tauri-app@latest
Trong hướng dẫn này, chúng ta sẽ sử dụng React và npm. Khi CLI nhắc bạn, hãy chọn template UI mà bạn thấy thoải mái nhất, nhưng hãy giữ trình quản lý gói đơn giản để tránh rơi vào “địa ngục phụ thuộc” ngay từ đầu.
Cầu nối: Các lệnh Rust
Trái tim của bất kỳ ứng dụng Tauri nào là Giao tiếp giữa các tiến trình (IPC). Bạn viết một hàm trong Rust, gắn thẻ nó bằng một macro, và gọi nó trực tiếp từ JavaScript. Đây là nơi nhiều nhà phát triển vấp ngã khi cố gắng truyền các đối tượng phức tạp, không thể tuần tự hóa qua cầu nối này.
Mở src-tauri/src/main.rs. Đây là nơi logic cốt lõi hoạt động. Chúng ta sẽ tạo một lệnh để đọc một tệp hệ thống—một tác vụ mà JavaScript không thể thực hiện một cách an toàn.
rust
#[tauri::command]
fn read_secret_config(path: String) -> Result<String, String> {
// Các ứng dụng thực tế nên xác thực đường dẫn tại đây để ngăn chặn tấn công duyệt thư mục
std::fs::read_to_string(path)
.map_err(|e| e.to_string())
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![read_secret_config])
.run(tauri::generate_context!())
.expect("lỗi khi chạy ứng dụng tauri");
}
Trong component React của bạn, giờ đây bạn có thể kích hoạt hàm backend này bằng Tauri API:
javascript
import { invoke } from '@tauri-apps/api/tauri';
async function handleFileRead() {
try {
const content = await invoke('read_secret_config', { path: '/etc/hosts' });
console.log('Nội dung tệp:', content);
} catch (error) {
console.error('Truy cập bị từ chối:', error);
}
}
Đóng gói và Phân phối
Xây dựng ứng dụng là lúc Tauri thực sự chứng minh giá trị của mình. Nó không chỉ xuất ra một tệp .exe thô; nó tạo ra các bộ cài đặt sẵn sàng cho môi trường thực tế. Đây từng là một cơn ác mộng khi tôi sử dụng các công cụ dựa trên Python. Tauri tự động xử lý .msi cho Windows, .dmg cho Mac và .deb cho Linux.
Thực hiện việc biên dịch:
bash
npm run tauri build
Hãy chuẩn bị tinh thần rằng lần chạy đầu tiên có thể mất từ 3 đến 5 phút để Rust tải về các crate cần thiết. Hãy đi pha một tách cà phê. Sau khi hoàn tất, hãy kiểm tra thư mục src-tauri/target/release/bundle/. Bạn sẽ thấy một bộ cài đã được ký số với dung lượng có thể dưới 4.5MB—xấp xỉ kích thước của một bức ảnh độ phân giải cao duy nhất.
Thực tế về biên dịch chéo
Một sự thật phũ phàng: bạn không thể biên dịch trực tiếp một tệp .exe cho Windows trên một chiếc MacBook. Mặc dù có những giải pháp lách luật, nhưng chúng rất dễ lỗi. Giải pháp chuyên nghiệp là sử dụng GitHub Actions. Hãy sử dụng quy trình CI/CD để kích hoạt biên dịch trên cả ba nền tảng cùng một lúc. Điều này giúp loại bỏ nhu cầu duy trì ba máy làm việc vật lý chỉ để đẩy một bản cập nhật.
Lời kết
Chuyển sang Tauri mang lại cảm giác giống như tháo bỏ bánh phụ trên xe đạp. Tôi phải tôn trọng sự nghiêm ngặt của Rust, nhưng phần thưởng là một ứng dụng nhanh như chớp mà người dùng thực sự yêu thích. Nó không chiếm dụng CPU hay làm cạn kiệt pin của họ. Sự chuyển đổi từ web sang desktop đòi hỏi sự tập trung sâu hơn vào bảo mật và quản lý trạng thái cục bộ.
Lần tới khi bạn được yêu cầu xây dựng một công cụ desktop, hãy cưỡng lại sự cám dỗ từ các framework nặng nề, cồng kềnh. Hãy thử bộ công cụ Rust-Tauri. RAM của người dùng sẽ cảm ơn bạn, và bạn sẽ ngủ ngon hơn khi biết ứng dụng của mình không phải là lý do cho một cuộc gọi khẩn cấp lúc 2 giờ sáng.

