Développement d'applications
Il n'y a pas de règles gravées dans le marbre pour le développement d'applications avec Wails, mais il y a quelques lignes directrices de base.
Configuration de l'application
Le modèle utilisé par défaut défini que main.go
est utilisé pour configurer et démarrer l'application, tandis que app.go
est utilisé pour définir la logique de l'application.
Le fichier app.go
va définir une structure qui a 2 méthodes qui agissent comme crochets dans l'application principale:
type App struct {
ctx context.Context
}
func NewApp() *App {
return &App{}
}
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
func (a *App) shutdown(ctx context.Context) {
}
La méthode startup est appelée d-s que Wails a donné les ressources nécessaires et qu'il est dans un bon état pour créer les ressources, mettre en place les event listeners et tout ce dont l'application peut avoir besoin pour démarrer. Il est donné un
context.Context
qui est généralement sauvegardé dans un champ struct. Ce contexte est nécessaire pour appeler le runtime. Si cette méthode renvoie une erreur, l'application se fermera. En mode développement, l'erreur sera affichée dans la console.La méthode d'arrêt sera appelée par Wails à la fin du processus d'arrêt. C'est un bon endroit pour vider la mémoire et effectuer toutes les tâches d'arrêt.
Le fichier main.go
consiste généralement en un seul appel à wails.Run()
, qui accepte la configuration de l'application. Le modèle utilisé par les templates fait qu'avant l'appel à wails.Run()
, une instance du struct que l'on a définie dans app.go
est créée et instanciée dans une variable appelée app
. Cette configuration est l'endroit où nous ajoutons nos callbacks :
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
})
if err != nil {
log.Fatal(err)
}
}
Plus d'informations sur les crochets du cycle de vie des applications peuvent être trouvées ici.
Méthodes de liaison
Il est probable que vous vouliez appeler les méthodes Go depuis le frontend. Cela se fait normalement en ajoutant des méthodes publiques à le struct déjà défini dans app.go
:
type App struct {
ctx context.Context
}
func NewApp() *App {
return &App{}
}
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
func (a *App) shutdown(ctx context.Context) {
}
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s!", name)
}
Dans la configuration principale de l'application, le paramètre Bind
est l'endroit où nous pouvons dire à Wails ce que nous voulons lier :
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
Bind: []interface{}{
app,
},
})
if err != nil {
log.Fatal(err)
}
}
Cela liera toutes les méthodes publiques de notre structure App
(cela ne liera jamais les méthodes de démarrage et d'arrêt du système).
Traiter avec le contexte lors de la liaison de plusieurs structures
Si vous voulez lier des méthodes pour des structures multiples, mais que vous voulez que chaque struct conserve une référence au contexte pour que vous puissiez utiliser les fonctions d'exécution... Un bon choix est de passer le contexte de la méthode OnStartup
à vos instances struct :
func main() {
app := NewApp()
otherStruct := NewOtherStruct()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: func(ctx context.Context){
app.SetContext(ctx)
otherStruct.SetContext(ctx)
},
OnShutdown: app.shutdown,
Bind: []interface{}{
app,
otherStruct
},
})
if err != nil {
log.Fatal(err)
}
}
Plus d'informations à sur Binding peuvent être trouvées ici.
Menu de l’application
Wails prend en charge l'ajout d'un menu à votre application. Ceci est fait en passant un Menu structuré à la configuration de l'application. Il est courant d'utiliser une méthode qui renvoie un Menu, et encore plus courant pour que cela soit une méthode sur la struct de l'app
qui soit utilisée pour les hooks du cycle de vie.
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
Menu: app.menu(),
Bind: []interface{}{
app,
},
})
if err != nil {
log.Fatal(err)
}
}
Ressources
La grande chose à propos de la façon dont Wails v2 gère les ressources pour le frontend, est que ce n'est pas le cas! La seule chose que vous devez donner à Wails est un embed.FS
. C'est à vous de décider comment vous y arrivez. Vous pouvez utiliser les fichiers html/css/js vanilla comme dans le modèle vanilla. Vous pourriez avoir un système de compilation compliqué, peu importe.
Quand la commande wails dev
est exécutée, elle vérifiera le fichier de projet wails.json
à la racine du projet. Il y a 2 clés dans le fichier du projet qui sont lues :
- "frontend:install"
- "frontend:build"
Le premier, si fourni, sera exécuté dans le répertoire frontend
pour installer les modules. Le second, si fourni, sera exécuté dans le répertoire frontend
pour construire le projet frontend.
Si ces 2 clés ne sont pas fournies, alors Wails ne fait absolument rien avec le frontend. Il n'attend que embed.FS
.
AssetsHandler
Une application Wails v2 peut éventuellement définir un http.Handler
dans options.app
, qui permet de se connecter à l'AssetServer pour créer des fichiers à la volée ou traiter les requêtes POST/PUT. Les requêtes GET sont toujours traitées d'abord par le assets
FS. Si le FS ne trouve pas le fichier demandé, la requête sera transmise au http.Handler
. Toute requête autre que GET sera traitée directement par le AssetsHandler
si spécifié. Il est également possible d'utiliser le AssetsHandler
uniquement en spécifiant nil
dans l'option Assets
.
Serveur de développement embarqué
Exécuter wails dev
démarrera le serveur de développement intégré qui démarrera un observateur de fichiers dans votre répertoire de projet. Par par défaut, si un fichier change, wails vérifie s'il s'agit d'un fichier d'application (par défaut: .go
, configurable avec l'option -e
). Si c'est le cas, il reconstruira votre application et la relancera. Si le fichier modifié se trouvait dans les actifs, il lancera un rechargement après un court laps de temps.
Le serveur de développement utilise une technique appelée "debouncing", ce qui signifie qu'il ne se recharge pas tout de suite, comme il peut y avoir plusieurs fichiers modifiés en un court laps de temps. Lorsqu'un déclencheur se produit, il attend un temps défini avant d'émettre un rechargement. Si un autre déclencheur se produit, le temps d'attente se réinitialise avant un prochain rechargement. Par défaut, cette période est définie à 100ms
. Si cette valeur ne fonctionne pas pour votre projet, elle peut être configurée en utilisant l'option -debounce
. Si elle est utilisée, cette valeur sera enregistrée dans la configuration de votre projet et deviendra la valeur par défaut.
Serveur de développement externe
Certains frameworks sont fournis avec leur propre serveur de rechargement en direct, cependant ils ne seront pas en mesure de tirer parti des liaisons Wails Go. Dans ce scénario, il est préférable d'exécuter un script qui va surveiller le projet dans dossier build, dossier que Wails surveille aussi. Pour un exemple, voir le modèle svelte par défaut qui utilise rollup. Pour create-react-app, il est possible d'utiliser ce script pour obtenir un résultat similaire.
Module Go
Les modèles Wails par défaut génèrent un fichier go.mod
qui contient le nom de module "changeme". Vous devriez changer ceci pour quelque chose de plus approprié après la génération du projet.