Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🦀
Debutant 25 min Tauri

Debuter avec Tauri

Pourquoi Tauri ?

Au milieu des nombreux choix pour développer un application Web en tant qu'application native, vous pouvez être confronté à une multitude de options : React Native, Flutter, Electron... Cependant, si vous cherchez une solution qui offre une expérience utilisateur fluide tout en offrant le contrôle total sur votre code source, Tauri est peut-être la solution idéale pour vous.

Un cas d'usage concret serait de développer une application de gestion des tâches. Avec Tauri, vous pouvez créer une interface Web moderne avec React ou Vue.js, tout en utilisant les capacités natives de votre système d'exploitation (comme le stockage local, les notifications push, etc.). Cela offre un bon équilibre entre l'interface utilisateur moderne et la fonctionnalité native.

Prerequis

Pour commencer avec Tauri, vous aurez besoin des éléments suivants :

  • Node.js: Minimum version 14.0.0
  • npm ou yarn: Pour gérer les dépendances du projet
  • Rust: Minimum version 1.56.0 (pour la compilation de l'application Tauri)
  • Un éditeur de code préféré : Par exemple, Visual Studio Code

Vous pouvez installer ces outils en suivant les instructions sur le site officiel :

Concepts fondamentaux

1. Projet Tauri

Un projet Tauri est composé de deux parties principales : une application Web et une application Native (le "shell").

Structure du projet :

my-tauri-app/
├── tauri/
│   ├── src-tauri/
│   │   ├── main.rs
│   │   └── Cargo.toml
│   └── tauri.conf.json
├── frontend/
│   ├── public/
│   ├── src/
│   ├── package.json
│   └── webpack.config.js
└── index.html

2. Configuration Tauri

La configuration de Tauri est définie dans tauri.conf.json. C'est le fichier qui contrôle comment votre application sera compilée et déployée.

{
  "build": {
    "distDir": "../frontend/dist",
    "devPath": "http://localhost:3000"
  },
  "allowlist": {
    "all": true
  }
}

3. Communication Frontend/Native

Tauri utilise une API de communication bidirectionnelle entre le frontend et le backend pour permettre l'interactions natives.

Exemple de code :

// src-tauri/src/main.rs

use tauri::{Builder, Manager};

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

#[tauri::command]
fn greet(name: &str) -> String {
  format!("Hello, {}!", name)
}
javascript
// frontend/src/App.js

import { invoke } from '@tauri-apps/api/tauri';

const App = () => {
  const handleClick = async () => {
    const greeting = await invoke('greet', { name: 'World' });
    alert(greeting);
  };

  return (
    <div>
      <button onClick={handleClick}>Greet</button>
    </div>
  );
};

export default App;

Mise en pratique : projet fil rouge

Mini-projet : Gestionnaire de tâches

Nous allons créer un simple gestionnaire de tâches où vous pouvez ajouter, supprimer et afficher les tâches.

Étape 1 : Initialiser le projet

npm init -y
npx create-tauri-app my-todo-app

Étape 2 : Ajouter une nouvelle tâche

Nous allons modifier le frontend pour ajouter une nouvelle tâche et l'envoyer au backend.

Exemple de code :

// frontend/src/App.js

import { useState } from 'react';
import { invoke } from '@tauri-apps/api/tauri';

const App = () => {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState('');

  const handleAddTask = async (e) => {
    e.preventDefault();
    await invoke('add_task', { task: newTask });
    setNewTask('');
    fetchTasks();
  };

  const fetchTasks = async () => {
    const tasks = await invoke('get_tasks');
    setTasks(tasks);
  };

  return (
    <div>
      <h1>Todo List</h1>
      <form onSubmit={handleAddTask}>
        <input
          type="text"
          value={newTask}
          onChange={(e) => setNewTask(e.target.value)}
          placeholder="Add a new task"
        />
        <button type="submit">Add</button>
      </form>
      <ul>
        {tasks.map((task, index) => (
          <li key={index}>{task}</li>
        ))}
      </ul>
    </div>
  );
};

export default App;

Exemple de code :

// src-tauri/src/main.rs

use tauri::{Builder, Manager};
use std::fs;

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![add_task, get_tasks])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

#[tauri::command]
fn add_task(task: &str) {
  let mut tasks = fetch_tasks();
  tasks.push(task.to_string());
  save_tasks(&tasks);
}

#[tauri::command]
fn get_tasks() -> Vec<String> {
  fetch_tasks()
}

fn fetch_tasks() -> Vec<String> {
  if fs::metadata("tasks.json").is_err() {
    return vec![];
  }

  let content = fs::read_to_string("tasks.json").unwrap();
  serde_json::from_str(&content).unwrap_or(vec![])
}

fn save_tasks(tasks: &Vec<String>) {
  let content = serde_json::to_string(tasks).unwrap();
  fs::write("tasks.json", content).unwrap();
}

Étape 3 : Supprimer une tâche

Nous allons ajouter la possibilité de supprimer une tâche.

Exemple de code :

// frontend/src/App.js

import { useState } from 'react';
import { invoke } from '@tauri-apps/api/tauri';

const App = () => {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState('');

  const handleAddTask = async (e) => {
    e.preventDefault();
    await invoke('add_task', { task: newTask });
    setNewTask('');
    fetchTasks();
  };

  const fetchTasks = async () => {
    const tasks = await invoke('get_tasks');
    setTasks(tasks);
  };

  const handleDeleteTask = async (index) => {
    await invoke('delete_task', { index });
    fetchTasks();
  };

  return (
    <div>
      <h1>Todo List</h1>
      <form onSubmit={handleAddTask}>
        <input
          type="text"
          value={newTask}
          onChange={(e) => setNewTask(e.target.value)}
          placeholder="Add a new task"
        />
        <button type="submit">Add</button>
      </form>
      <ul>
        {tasks.map((task, index) => (
          <li key={index}>
            {task}
            <button onClick={() => handleDeleteTask(index)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default App;

Exemple de code :

// src-tauri/src/main.rs

use tauri::{Builder, Manager};
use std::fs;

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![add_task, get_tasks, delete_task])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

#[tauri::command]
fn add_task(task: &str) {
  let mut tasks = fetch_tasks();
  tasks.push(task.to_string());
  save_tasks(&tasks);
}

#[tauri::command]
fn get_tasks() -> Vec<String> {
  fetch_tasks()
}

#[tauri::command]
fn delete_task(index: usize) {
  let mut tasks = fetch_tasks();
  if index < tasks.len() {
    tasks.remove(index);
    save_tasks(&tasks);
  }
}

fn fetch_tasks() -> Vec<String> {
  if fs::metadata("tasks.json").is_err() {
    return vec![];
  }

  let content = fs::read_to_string("tasks.json").unwrap();
  serde_json::from_str(&content).unwrap_or(vec![])
}

fn save_tasks(tasks: &Vec<String>) {
  let content = serde_json::to_string(tasks).unwrap();
  fs::write("tasks.json", content).unwrap();
}

Erreurs frequentes et debugging

Erreur 1 : error[E0433]: failed to resolve: use of undeclared type or module 'tauri'

Code incorrect :

## ❌ Mauvais
use tauri;

Code correct :

## ✅ Correct
use tauri::{Manager, Builder};

Erreur 2 : error: expected a type, found value expression

Code incorrect :

## ❌ Mauvais
#[tauri::command]
fn greet(name) {
  format!("Hello, {}!", name)
}

Code correct :

## ✅ Correct
#[tauri::command]
fn greet(name: &str) -> String {
  format!("Hello, {}!", name)
}

Erreur 3 : error[E0277]: the trait bound 'usize: std::marker::Send' is not satisfied

Code incorrect :

## ❌ Mauvais
#[tauri::command]
fn delete_task(index) {
  let mut tasks = fetch_tasks();
  if index < tasks.len() {
    tasks.remove(index);
    save_tasks(&tasks);
  }
}

Code correct :

## ✅ Correct
#[tauri::command]
fn delete_task(index: usize) {
  let mut tasks = fetch_tasks();
  if index < tasks.len() {
    tasks.remove(index);
    save_tasks(&tasks);
  }
}

Pour aller plus loin

1. Ajouter des notifications push

Vous pouvez utiliser l'API de Tauri pour envoyer des notifications push à votre utilisateur.

Exemple de code :

## ✅ Correct
#[tauri::command]
fn show_notification(title: &str, body: &str) {
  use tauri::api::notification;

  notification::NotificationBuilder::new()
    .title(title)
    .body(body)
    .show();
}

2. Utiliser des services en arrière-plan

Vous pouvez utiliser le service Tauri pour exécuter du code en arrière-plan, même lorsque votre application n'est pas en premier plan.

Exemple de code :

## ✅ Correct
#[tauri::command]
fn run_background_task() {
  use tauri::api::process;

  process::spawn_cmd("sleep 10 && echo 'Task completed'").unwrap();
}

3. Intégrer des bibliothèques Rust personnalisées

Vous pouvez intégrer vos propres bibliothèques Rust personnalisées à votre application Tauri.

Exemple de code :

## ✅ Correct
#[tauri::command]
fn call_custom_rust_function() {
  let result = my_custom_library::custom_function();
  println!("{}", result);
}

Défi pratique

Créer une application de messagerie simple

Créez une application de messagerie simple avec Tauri. L'application devrait permettre à l'utilisateur d'envoyer et de recevoir des messages. Utilisez les fonctionnalités natives pour le stockage local et la notification push.

Bon codage !

Besoin d'aide sur Tauri ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Qu'est-ce que Tauri?
Tauri est un framework open-source qui permet de créer des applications Web en utilisant HTML, CSS et JavaScript, tout en les empaquetant dans une application native pour Windows, macOS et Linux.
Comment installer Tauri?
Pour installer Tauri, vous devez d'abord avoir Node.js et npm installés sur votre système. Ensuite, suivez les instructions du guide officiel de Tauri pour créer un nouveau projet Tauri.
Quelle est la différence entre une application Web et une application native utilisant Tauri?
Une application Web s'exécute dans un navigateur et est dépendante du navigateur pour son fonctionnement. Une application native avec Tauri a une interface utilisateur natif, offre des performances meilleures et n'est pas limitée par les contraintes du navigateur.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.