
Il s'agit d'un modèle de projet Tauri à l'aide de Next.js, en bootstrapé en combinant create-next-app et create tauri-app .
Ce modèle utilise pnpm comme gestionnaire de dépendance Node.js.
Après le clonage pour la première fois, configurez les crochets pré-comités Git:
pnpm preparePour développer et exécuter le frontend dans une fenêtre Tauri:
pnpm dev Cela chargera le frontend Next.js directement dans une fenêtre Tauri WebView, en plus de démarrer un serveur de développement sur localhost:3000 .
Pour exporter le frontend suivant.js via SSG et construire l'application Tauri pour la version:
pnpm build N'oubliez pas de modifier l'identifiant du bundle dans tauri.conf.json > tauri > bundle > identifier , car la valeur par défaut donnera une erreur qui vous empêche de créer l'application pour la libération.
Les fichiers source de frontend next.js sont situés dans les fichiers de source d'application src/ et Tauri Rust sont situés dans src-tauri/ . Veuillez consulter respectivement la documentation suivante.
Next.js est un excellent cadre de frontend React qui prend en charge le rendu côté serveur (SSR) ainsi que la génération de sites statique (SSG ou pré-rendu). Aux fins de la création d'un frontend Tauri, seul SSG peut être utilisé car SSR nécessite un serveur Node.js actif.
L'utilisation de Next.js et SSG aide à fournir une expérience frontale rapide et performante d'une seule page (SPA). Plus d'informations à ce sujet peuvent être trouvées ici: https://nextjs.org/docs/basic-deatures/pages#pre-redering
next/image Le composant next/image est une amélioration par rapport à l'élément HTML <img> régulier avec des optimisations supplémentaires intégrées. Cependant, parce que nous ne déploiez pas le frontend sur Vercel directement, certaines optimisations doivent être désactivées pour construire et exporter correctement le frontage via SSG. En tant que tel, la propriété unoptimized est définie sur true pour le composant next/image dans la configuration next.config.js . Cela permettra à l'image d'être servie en tant que source, sans modifications de sa qualité, de sa taille ou de son format.
#![feature] peut ne pas être utilisé sur le canal de version stable Si vous obtenez ce problème lorsque vous essayez d'exécuter pnpm tauri dev , il se peut que vous ayez une version plus récente d'une dépendance de rouille qui utilise une fonctionnalité instable. pnpm tauri build devrait toujours fonctionner pour les builds de production, mais pour faire fonctionner la commande Dev, soit rétrograder la dépendance, soit utiliser Rust Nightly via rustup override set nightly .
Si vous utilisez la fonction invoke de Tauri ou n'importe quelle fonction Tauri liée au système d'exploitation à partir de JavaScript, vous pouvez rencontrer cette erreur lors de l'importation de la fonction dans un contexte global et non naval. Cela est dû à la nature du serveur Dev de Next.js exécutant efficacement un serveur Node.js pour SSR et le remplacement des modules HOT (HMR), et Node.js n'a pas de notion de window ou navigator .
Assurez-vous que vous appelez ces fonctions dans le contexte du navigateur, par exemple dans un composant React à l'intérieur d'un crochet useEffect lorsque le Dom existe réellement d'ici là. Si vous essayez d'utiliser une fonction Tauri dans un fichier source d'utilité généralisée, une solution de contournement consiste à utiliser l'injection de dépendance pour la fonction elle-même afin de retarder l'importation réelle de la fonction réelle (voir l'exemple ci-dessous pour plus d'informations).
Exemple utilisant la fonction invoke de Tauri:
src/lib/some_tauri_functions.ts (problématique)
// Generalized file containing all the invoke functions we need to fetch data from Rust
import { invoke } from "@tauri-apps/api/tauri"
const loadFoo = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_foo" )
}
const loadBar = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_bar" )
}
const loadBaz = ( ) : Promise < string > => {
return invoke < string > ( "invoke_handler_baz" )
}
// and so on ... src/lib/some_tauri_functions.ts (fixe)
// Generalized file containing all the invoke functions we need to fetch data from Rust
//
// We apply the idea of dependency injection to use a supplied invoke function as a
// function argument, rather than directly referencing the Tauri invoke function.
// Hence, don't import invoke globally in this file.
//
// import { invoke } from "@tauri-apps/api/tauri" <-- remove this!
//
import { InvokeArgs } from "@tauri-apps/api/tauri"
type InvokeFunction = < T > ( cmd : string , args ?: InvokeArgs | undefined ) => Promise < T >
const loadFoo = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_foo" )
}
const loadBar = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_bar" )
}
const loadBaz = ( invoke : InvokeFunction ) : Promise < string > => {
return invoke < string > ( "invoke_handler_baz" )
}
// and so on ... Ensuite, lorsque vous utilisez loadFoo / loadBar / loadBaz dans vos composants React, importez la fonction invoquée de @tauri-apps/api et passez invoke dans la fonction LoadXXX comme argument InvokeFunction . Cela devrait permettre à l'API Tauri réelle d'être regroupé uniquement dans le contexte d'un composant React, il ne faut donc pas être chargé par suivant.js au démarrage initial jusqu'à ce que le navigateur ait terminé le chargement de la page.
import() Étant donné que l'API Tauri doit lire à partir de la window du navigateur et de l'objet navigator , ces données n'existent pas dans un environnement Node.js et donc SSR. On peut créer une fonction exportée qui enveloppe l'API Tauri derrière un appel dynamique import() .
Exemple: Créez un src/lib/tauri.ts pour réexporter invoke
import type { InvokeArgs } from "@tauri-apps/api/tauri"
const isNode = ( ) : boolean =>
Object . prototype . toString . call ( typeof process !== "undefined" ? process : 0 ) ===
"[object process]"
export async function invoke < T > (
cmd : string ,
args ?: InvokeArgs | undefined ,
) : Promise < T > {
if ( isNode ( ) ) {
// This shouldn't ever happen when React fully loads
return Promise . resolve ( undefined as unknown as T )
}
const tauriAppsApi = await import ( "@tauri-apps/api" )
const tauriInvoke = tauriAppsApi . invoke
return tauriInvoke ( cmd , args )
} Ensuite, au lieu d'importer import { invoke } from "@tauri-apps/api/tauri" , utilisez invoquer à partir de import { invoke } from "@/lib/tauri" .
Pour en savoir plus sur Next.js, jetez un œil aux ressources suivantes:
Et pour en savoir plus sur Tauri, jetez un œil aux ressources suivantes: