0
0
Lập trình
Admin Team
Admin Teamtechmely

Sử Dụng Tauri-Helper: Tiện Ích Rust Tự Động Thu Thập Lệnh Tauri

Đăng vào 6 ngày trước

• 6 phút đọc

Giới Thiệu

Nếu bạn đã từng làm việc với Tauri, có lẽ bạn đã sử dụng macro tauri::command, nhưng sau một vài lệnh, bạn nhận ra rằng bạn cần phải viết từng hàm một cách thủ công trong invoke_handler, điều này có vẻ khó chịu nhưng chấp nhận được.

Tuy nhiên, khi dự án của tôi phát triển, việc quản lý hàng trăm lệnh trở nên khó khăn hơn; việc viết chúng, nhớ rằng mình đã viết chúng, thậm chí việc sửa đổi tên hàm cũng thật phiền phức. Sau vài tuần, tôi tình cờ phát hiện ra specta, một crate Rust cho phép tôi chuyển Struct thành các loại TS, và các hàm với các tham số đúng, v.v...

NHƯNG nỗi khổ lại đến khi tôi nhận ra rằng tôi phải viết lại tất cả tên hàm mà tôi đã có trong một invoke_handler khác, điều này có thể được giải quyết bằng cách sao chép và dán, nhưng tôi đã đủ chán với tất cả mã lệnh rườm rà này và việc mã của tôi trở nên dài hàng trăm dòng vì một điều đơn giản như vậy, vì vậy tôi quyết định viết một crate Rust nhỏ, tauri-helper, để giúp chúng ta, các nhà phát triển, viết mã Rust trong Tauri một cách nhanh chóng và không cần tất cả những dòng mã vô nghĩa này.

Vấn Đề Gặp Phải

Khi xây dựng tauri-helper, tôi đã gặp phải một số vấn đề trong Rust làm cho việc phát triển trở nên khó khăn hơn:

  • Giới hạn của Macro: Tiếc là, các macro trong Rust không thể biết vị trí chính xác của một hàm trong một module hoặc workspace. Điều đó có nghĩa là nếu tôi muốn chuyển các hàm xung quanh, tôi phải nhập khẩu toàn bộ module, ví dụ: use some_module::*;. Điều này làm cho việc viết các macro thu thập trở nên phức tạp hơn mong đợi, mặc dù trong tương lai gần sẽ có khả năng làm điều đó mà không cần nhập toàn bộ module, nhưng hiện tại vẫn đang trong phiên bản nightly và tôi muốn tránh điều đó.

  • Nhiều Workspaces: Việc thu thập các lệnh từ nhiều crate trong một workspace trở nên lộn xộn. Mỗi crate có các module và đường dẫn riêng, vì vậy tôi phải làm cho các macro nhận biết workspace và xử lý việc phát hiện hàm chéo giữa các crate để nhận biết mọi thay đổi đối với một hàm hoặc việc tạo ra một hàm để có thể ghi lại nó.

  • Cấu trúc tệp và build.rs: Để tự động tạo danh sách lệnh, tôi đã viết các tệp được tạo trong một thư mục riêng bằng cách sử dụng build.rs. Nó hoạt động, nhưng tôi phải quản lý cẩn thận các đường dẫn và đảm bảo mọi thứ được đồng bộ khi các hàm di chuyển hoặc được đổi tên.

Mỗi thách thức này đều yêu cầu thiết kế và thử nghiệm cẩn thận để làm cho tauri-helper đáng tin cậy và dễ sử dụng cho những người khác, vì đó chính là mục tiêu của crate này.

Cách Sử Dụng Tauri-Helper

Khi tôi giải quyết được các vấn đề phát triển, việc sử dụng crate trở nên đơn giản hơn nhiều và giúp Tauri dễ sử dụng hơn:

Cài Đặt

Thêm tauri-helper vào tệp Cargo.toml của bạn:

toml Copy
[dependencies]
tauri-helper = "0.1.4"

Nếu bạn muốn sử dụng macro WithLogging với tracing, hãy bật tính năng tracing:

toml Copy
[dependencies]
tauri-helper = { version = "0.1.4", features = ["tracing"] }

Sau đó thêm nó vào [build-dependencies]:

toml Copy
[build-dependencies]
tauri-helper = "0.1.4"

QUAN TRỌNG

Trước khi sử dụng bất kỳ việc thu thập lệnh nào, bạn phải thêm đoạn mã này vào tệp build.rs:

rust Copy
fn main() {
    tauri_helper::generate_command_file(tauri_helper::TauriHelperOptions::default());
    tauri_build::build();
}

Và sau đó hãy chắc chắn rằng workspace của bạn là chính xác và đã định nghĩa crate hiện tại trong Cargo.toml của bạn như sau:

toml Copy
[workspace]
members = [
    ".",
    "local-crates/some-commands1",
    "local-crates/some-commands2",
    "local-crates/some-commands3",
]

Đừng quên thêm . như một thành viên, nếu không crate sẽ không thể lấy các lệnh từ crate mặc định.

Cách Sử Dụng

Thu Thập Lệnh

Ghi chú các hàm lệnh Tauri của bạn bằng cách sử dụng #[auto_collect_command] để tự động thu thập chúng:

rust Copy
#[tauri::command]
#[auto_collect_command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

Tạo một lệnh gọi tauri::generate_handler!:

rust Copy
tauri_collect_commands!();

Tạo một lệnh gọi tauri_specta::collect_commands!:

rust Copy
specta_collect_commands!();

Lưu Ý

Nếu bạn không muốn phải ghi chú mỗi lệnh với #[auto_collect_command], bạn có thể làm điều này trong build.rs:

rust Copy
fn main() {
    tauri_helper::generate_command_file(tauri_helper::TauriHelperOptions::new(true));
    tauri_build::build();
}

Điều này sẽ yêu cầu script build lấy mọi tauri_command có sẵn trong mọi thành viên của workspace.

Điều này không được khuyến cáo vì có thể dẫn đến việc thêm các hàm không có ý định được xuất khẩu.

Nếu workspace của bạn chứa nhiều crate, bạn phải xuất tất cả các hàm trong tệp gốc (lib.rs) của mỗi crate.

Ví Dụ

Trong my_commands.rs:

rust Copy
#[tauri::command]
#[auto_collect_command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

Trong lib.rs:

rust Copy
pub mod my_commands;
pub use my_commands::*;

Lưu Ý: Điều này là cần thiết vì tính năng cho phép truy xuất đường dẫn module đầy đủ vẫn chỉ có sẵn trong phiên bản nightly của Rust.

Ví Dụ Hoàn Chỉnh

Dưới đây là một ví dụ hoàn chỉnh về việc sử dụng tauri_helper trong một ứng dụng Tauri:

rust Copy
#[tauri::command]
#[auto_collect_command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

#[tauri::command]
#[auto_collect_command]
fn calculate_sum(a: i32, b: i32) -> i32 {
    a + b
}

fn main() {
    let builder: tauri_specta::Builder = tauri_specta::Builder::<tauri::Wry>::new()
        .commands(specta_collect_commands!());

    #[cfg(debug_assertions)]
    builder
        .export(
            Typescript::default().bigint(specta_typescript::BigIntExportBehavior::Number),
            "../src/bindings.ts",
        )
        .expect("should work");

    tauri::Builder::default()
        .invoke_handler(tauri_collect_commands!())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Kết Luận

Việc tạo ra tauri-helper không dễ dàng như tôi mong đợi, đặc biệt là cho một dự án đầu tiên, các macro Rust, workspaces đa crate, và việc tạo mã tại thời điểm build đều gây ra những vấn đề lớn trong quá trình phát triển. Nhưng giải quyết chúng đã dẫn đến một crate nhỏ, mạnh mẽ giúp đơn giản hóa ít nhất một chút việc thu thập lệnh trong các dự án Tauri.

Nếu bạn đang xây dựng ứng dụng Tauri và cảm thấy chán ngán với mã lệnh rườm rà, tauri-helper cho phép bạn viết mã Rust một cách hiệu quả trong khi vẫn giữ cho việc đăng ký lệnh tự động và có tổ chức, giúp bạn tránh được tình trạng mã lib.rs dài hàng ngàn dòng thật đáng sợ.

Chỉ một lưu ý nhỏ cho các nhà phát triển Rust: với Rust 1.90.0, cargo publish --workspace đã được giới thiệu, điều này làm cho việc xuất bản các workspaces đa crate dễ dàng hơn nhiều, giúp đơn giản hóa khá nhiều việc xuất bản các workspace đa crate và sẽ làm cho tauri-helper trở nên hữu ích hơn nữa vì giờ đây bạn có thể tạo ra nhiều crate mà không gặp phải vấn đề xuất bản. Điều này không quan trọng cho việc sử dụng crate, nhưng đó là một cải tiến chất lượng cuộc sống tốt cho các nhà phát triển quản lý các dự án đa crate.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào