Tauri - Framework на Rust, обеспечивающий мульти-платформенную разработку Desktop-приложений. Tauri создаёт окно web-брайзера, без элементов пользовательского интерфейса браузера и запускает в нём web-приложение. Существует возможность вызвать из web-приложений нативный код, скомпилированный из исходников на Rust, что позволяет, в частности, выполнять взаимодействие с узлами компьютера на низком уровне.
Ключевые достоинства Tauri:
- очень маленький размер package - в десятки раз меньше, чем прилолжения Electron, или Avalonia
- скорость запуска приложения очень высокая (меньше секунды)
- потребность в оперативной памяти в разы меньше, чем у альтернативных решений (Electron, Avalonia)
- возможность выполнять вычислительно эффективный нативый код (скомпилированный из Rust с использованием LLVM)
- пользовательский интерфейс можно разрабатывать удобным для web-программиста образом, используя: HTML/CSS/JS, SvelteKit, Next.js, React, Angular, Vue.js, и т.д.
Недостатки:
- время сборки проекта может быть значимым (минуты)
- инструментальные средства для работы с Rust пока ещё не такие зрелые, как для других языков программирования (C#, JavaScript)
- обмен данными между web-приложением и нативным кодом скомпилированным из Rust осуществляется через IPC, т.е. расходы на коммуникацию достаточно существенные
Рекомендуется установить генератор шаблонного кода:
cargo install create-tauri-app
Эта команда загрузит исходные тексты утилиты и скомпилирует её под текущую платформу. Процесс может занять несколько минут.
Генерация каркаса приложения осуществляется командой:
cargo create-tauri-app
В процессе работы приложения требуется ответить на ряд вопросов генератора кода, в частности, выбрать web-платформу. В сгенерированном проекте будет две части: web-приложение (в папке src) и Rust-приложение (в папке src-tauri). Для сборки приложения следует перейти в папку src-tauri
и выполнить команду:
cargo build --release
Для сборки Tauri-приложения требуется загрузить 200+ crates (вспомогательных библиотек). Сборка приложения может занять больше минуты. В результате компиляции, на платформе Windows создаётся исполняемый файл размером ~5 мегабайт, который можно запустить на исполнение.
Для сборки приложения в Ubuntu 22.04 необходимо предварительно разрешить в Software & Updates, в разделе "Ubuntu Software" следующие источники данных: "Canonical-supported free and open-source software (main)" и "Source code". После этого следует установить pre-requisites:
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
build-essential \
curl \
wget \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev
Исполняемый файл занимает около 11 Мбайт и запускается менее, чем за секунду.
В главном файле Rust-приложения ("main.rs") может быть определена команда, вызываемая из кода web-приложения. В демонстрационном приложении такая команда выглядит так:
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
Входной параметр функции - строковый срез (&str), а возвращаемое значение имеет тип "строка" (String). В соответствии с синтаксисом Rust, возвращено будет строковое значение, являющееся результатом вызова format!().
Регистрация команды выглядит следюущим образом:
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
В приведённом выше коде создаётся контейнер комманд, в который добавляется обработчик - ранее определённая функция greet(). Если web-приложение вызовет эту команду, то Tauri создаст контекст выполнения команды и вызовет функцию greet(). В случае возникновения ошибки, возникнет panic! и приложение завершиться, выдав в консоль сообщение об ошибке "error while running tauri application". Для информации: метод expect() работает также, как и unwrap(), но позволяет лучше показать намерение разработчика, добавив текст, поясняющий причину ошибки.
JavaScript код (main.js) выполняет destructuring и получает из window.__TAURI__.tauri
функциональный объект invoke, который можно использовать для вызова функции на Rust:
const { invoke } = window.__TAURI__.tauri;
let greetInputEl;
let greetMsgEl;
async function greet() {
greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value });
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document
.querySelector("#greet-button")
.addEventListener("click", () => greet());
});
В приведённом выше примере, при нажатии на кнопку с идентификатором greet-button, из поля ввода с идентификатором greet-input будет извлечено значение и добавлено в текстовую строку с идентификатором greet-msg.
Почитать больше о командах можно в официальной документации по Tauri.
Более углублённая статья от японского разработчика - Trying to the Tauri GUI on Rust : 3. Communicate with js (^-^ by mar-m. nakamura.
Отправная точка для поиска: "tauri call js from rust". Пример кода, найденный в интернет, но который я ещё не проверял:
.on_menu_event(|event| {
let window = event.window();
match event.menu_item_id() {
"trigger" => {
window.emit();
}
_ => {}
}
})
Статья о создании приложения Tauri на React: How To Create Tauri Desktop Applications Using React by Mahbub Zaman.
Предварительные действия:
cargo install tauri-cli
cargo tauri --help
Создать приложение можно используя yarn
, альтернативный менеджер пакетов, считающийся более эффективным, чем npm. Сначала необходимо создать папку для решения, а потом уже запустить команду генерации шаблонного кода:
yarn create tauri-app
Команда загружает генератор шаблонов из репозитария и запускает его. Когда приложение запрашивает какой менджер проектов использовать, выбор cargo позволит лишь добавить VanillaJS-проекты. В случае выбора npm/yarn предоставляются варианты с использованием различных библиотек и frameworks. Один из вариантов: react-ts.
После генерации кода, предлагается выполнить следующие команды:
cd tauri-app
yarn
yarn tauri dev
Команда yarn
загружает зависимости проекта. На этом этапе можно "поймать" ошибки, связанные с инструментальными средствами. Например, на моей машине была установлена устаревшая версия Node.js (14.17.5). Команда yarn tauri dev
выполняет сборку проекта.
Используемый Front-End - действительно React с использованием TypeScript и Vite. Vite - инструмент для управления сборкой FrontEnd-приложений, пришедший на смену webpack, Rollup и Parcel. Ключевая особенность Vite - разработан на compile-to-native языках программирования (Go/gcc), он работает существенно быстрее, чем JavaScript-based менеджеры пакетов.
Чтобы выполнить сборку для выпуска продукта следует использовать команду yarn tauri build
, однако, эта команда не будет выполнена если не поменять идентификатор приложения в файле "tauri.config.json", в ветке tauri -> bundle -> identifier со значения "com.tauri.dev" на "com.tauri.app". Размер приложения "по умолчанию" - 7,5 Мб. Запускается мгновенно. Кроме исполняемого файла скрипт собрал и msi-файл (для Windows), используя систему сборки WiX.
В идеальном случае, для сборки React-приложения в рамках Tauri, было бы достаточно установить Node.js, NPM и yarn:
sudo apt install nodejs
sudo apt install npmsudo npm install --global yarn
У сожалению, идеальный путь не всегда работает - в Ubuntu 22.04 по умолчанию устанавливается Node.js 12 LTS, что не соответствует требованиям tauri-cli. По этой причине, необходимо устанавливать не LTS версию по инструкциям в Интернет (я использовал третий вариант установки из инструкции от DigitalOcean).
Однако, после установки Node.js 18 и генерации шаблона приложения Tauri+React/TS, Desktop-приложение для Linux успешно собирается. Размер приложения - чуть меньше 14 Мб.
Приложение было скопировано с машины с установленной Ubuntu Mate 22.04 на Ubuntu 22.04 и прекрасно запустилось. Дополнительно можно посмотреть зависимости исполняемого файла командой apt-cache depends [имя исполняемого файла]
Система сборки Tauri-приложения в режиме production в Linux, кроме непосредственно исполняемого файла, формирует два дистрибутивных комплекта: deb-файл размером 5,3 Мб и AppImage размером чуть более 78 Мб.
Deb-файл является "родным" для Debian-based дистрибутивов, в том числе, для Ubuntu и позволяет развернуть приложение используя "Software Install". Уставка deb-файла в Ubuntu 22.04 успешно установил приложение - оно запускается и работает.
Теоретически, AppImage должен запускаться на любой платформе. Для этого после копирования файла на целевую платформу следует предоставить разрешение на запуск AppImage командой: chmod +x my.AppImage
.
Однако, у меня не получилось запустить AppImage полученный на Ubuntu Mate 22.04 в Ubuntu 22.04: не были найдены ключевые системные библиотеки, в большинстве своём Glibc2.*
. Следует напомнить, что Glibc2 (The GNU C Library) - это библиотеки, отвечающие за обратную совместимость с устаревшими приложениями и компонентами. Это актуально, поскольку в AppImage, обычно включаются наиболее устаревшие компоненты, чтобы обеспечить совместимость с максимальным количеством платформ (в том числе, устаревших). Но и после установки Glibc2 AppImage установить не удалось - приложение потребовало установки FUSE, что может привести к нарушению работоспособности Ubuntu.
В статье Релиз фреймворка Tauri 2.0 рассказывается о выходе новой версии Tauri. Ключевая особенность - поддержка мобильных платформ вошла в стабильный релиз. Добавлен Hot-Module Replacement (HMR) для ускорения разработки мобильных приложений. Значительно улучшена система плагинов.
Продукт активно развивается и находит всё новых сторонников.