
Trong nhiều năm, hệ sinh thái frontend bị thống trị bởi một ngôn ngữ duy nhất: JavaScript (và tập hợp con được gõ mạnh của nó, TypeScript). Tuy nhiên, trong vài năm qua, một sự thay đổi đáng kể đã xảy ra. Rust, một ngôn ngữ lập trình hệ thống nổi tiếng về hiệu suất và an toàn bộ nhớ, đã mạnh mẽ gia nhập lĩnh vực frontend. Ban đầu được thúc đẩy bởi nhu cầu về các công cụ xây dựng nhanh hơn, Rust giờ đây là một công dân hạng nhất trong trình duyệt thông qua WebAssembly (Wasm).
Nếu bạn là một nhà phát triển frontend đang đầu tư nhiều vào React, Vue hoặc Angular, viễn cảnh học Rust có vẻ đáng sợ. Hướng dẫn này nhằm mục đích thu hẹp khoảng cách, dịch các khái niệm từ hệ sinh thái JavaScript sang mô hình Rust và chứng minh tại sao sự chuyển đổi này đáng để bạn dành thời gian.
Trước khi phân tích chi tiết cú pháp, chúng ta phải giải quyết câu hỏi "tại sao". Tại sao một nhà phát triển web lại phải quan tâm đến một ngôn ngữ hệ thống?
Trở ngại lớn nhất khi chuyển từ TypeScript sang Rust không phải là cú pháp, mà là mô hình tư duy liên quan đến quản lý bộ nhớ và quyền sở hữu.
Trong JavaScript, Garbage Collector tự động xử lý việc cấp phát và giải phóng bộ nhớ. Bạn tạo một đối tượng, truyền nó đi, và khi không còn tham chiếu nào đến nó, nó sẽ được dọn dẹp.
Trong Rust, không có Garbage Collector. Thay vào đó, Rust sử dụng một tập hợp các quy tắc nghiêm ngặt được gọi là "Quyền sở hữu":
Nếu bạn muốn truyền một giá trị cho một hàm mà không từ bỏ quyền sở hữu, bạn phải "mượn" nó bằng cách sử dụng các tham chiếu (&).
// Rust Example
fn main() {
let s1 = String::from("hello");
// We pass a reference to s1. We do not transfer ownership.
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
Sự nghiêm ngặt này buộc bạn phải suy nghĩ cẩn thận về vòng đời của dữ liệu, dẫn đến hiệu suất mạnh mẽ và có thể dự đoán được.
null và undefined so với OptionTypeScript sử dụng null và undefined để biểu thị sự vắng mặt của một giá trị. Ngay cả với strictNullChecks, lỗi thời gian chạy vẫn có thể xảy ra.
Rust loại bỏ hoàn toàn null. Thay vào đó, nó cung cấp enum Option. Một Option là Some(value) hoặc None.
// An Option containing an i32
let some_number: Option<i32> = Some(5);
let no_number: Option<i32> = None;
// You MUST handle both cases explicitly
match some_number {
Some(n) => println!("The number is {}", n),
None => println!("There is no number"),
}
Lựa chọn thiết kế cơ bản này loại bỏ "TypeError: Cannot read properties of undefined" mãi mãi.
try/catch so với ResultTrong JavaScript, lỗi thường được ném và bắt bằng các khối try/catch. Điều này có thể làm cho luồng điều khiển trở nên ngầm định và khó theo dõi.
Rust sử dụng enum Result cho các lỗi có thể phục hồi. Một Result là Ok(value) hoặc Err(error). Các hàm có thể thất bại phải trả về một Result, buộc người gọi phải xử lý lỗi tiềm ẩn một cách rõ ràng.
use std::fs::File;
fn open_file() {
let f = File::open("hello.txt");
let file = match f {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
Rust cũng cung cấp toán tử ? để truyền lỗi ngắn gọn, làm cho việc xử lý lỗi vừa rõ ràng vừa dễ đọc.
Hãy xem cách bạn thực sự có thể chạy Rust trong trình duyệt. Hệ sinh thái cung cấp các công cụ tuyệt vời như wasm-bindgen để tạo điều kiện giao tiếp liền mạch giữa JavaScript và Rust.
Đầu tiên, bạn định nghĩa một hàm Rust và chú thích nó bằng #[wasm_bindgen]:
use wasm_bindgen::prelude::*;
// This attribute exposes the function to JavaScript
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
Sử dụng một công cụ như wasm-pack, bạn có thể biên dịch mã Rust này thành một mô-đun WebAssembly cùng với các ràng buộc JavaScript được tạo. Sau đó, bạn có thể nhập mô-đun này trực tiếp vào ứng dụng frontend của mình giống như bất kỳ mô-đun JavaScript nào khác.
import init, { fibonacci } from './pkg/my_rust_module.js';
async function run() {
await init(); // Initialize the Wasm module
const result = fibonacci(40);
console.log(`Result from Rust: ${result}`);
}
run();
Một nhóm frontend đang cân nhắc di chuyển một module xử lý hình ảnh quan trọng, đòi hỏi nhiều tính toán từ TypeScript sang Rust được biên dịch thành WebAssembly. Lợi ích đáng kể NHẤT ở cấp độ production mà họ có thể đạt được từ sự chuyển đổi này là gì, giả sử việc triển khai Rust được tối ưu hóa tốt?
Chuyển đổi sang Rust đòi hỏi một sự thay đổi mô hình. Bạn phải đánh đổi sự linh hoạt của một ngôn ngữ có bộ thu gom rác để lấy sự nghiêm ngặt của bộ kiểm tra mượn. Tuy nhiên, phần thưởng là rất lớn. Bằng cách học Rust, bạn có quyền truy cập vào hiệu suất chưa từng có, độ tin cậy vững chắc và khả năng tận dụng WebAssembly cho các tác vụ frontend đòi hỏi cao. Khi nền tảng web trưởng thành, Rust đang định vị mình không phải là một sự thay thế cho JavaScript, mà là một người bạn đồng hành thiết yếu, hiệu suất cao.
Làm sạch log AI CLI, tạo biểu thức cron, giải mã JWT và tính quyền chmod offline.

Tìm hiểu cách viết các tác vụ tính toán hiệu suất cao bằng Rust, biên dịch chúng sang WebAssembly bằng wasm-pack và tích hợp chúng vào React hiện đại.
Đọc tiếp
Hướng dẫn toàn diện về việc chuyển đổi từ Jest sang Vitest, khám phá những cải tiến về hiệu suất, các tính năng hiện đại và các bước thực tế để nâng cấp liền mạch ngăn xếp kiểm thử frontend của bạn.
Đọc tiếp
Hướng dẫn toàn diện về WebAssembly SIMD trên trình duyệt: vector hóa 128-bit cho xử lý ảnh & tín hiệu thời gian thực với kiến trúc cấp độ sản xuất và các ví dụ mã.
Đọc tiếp